home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / diags / gport101.zip / GAMDEMO.C < prev    next >
C/C++ Source or Header  |  1991-08-31  |  19KB  |  737 lines

  1. /*
  2. // GAMDEMO.C
  3. //
  4. // Game port demo program for the Gport game port library.
  5. //
  6. // Compiled and linked with Borland C++ v2.00
  7. //
  8. // Copyright (c) 1991 Bri Productions
  9. //
  10. */
  11.  
  12.  
  13. #include "gport.h"
  14. #include <stdlib.h>
  15. #include <bios.h>
  16. #include <graphics.h>
  17. #include <alloc.h>
  18. #include <stdio.h>
  19. #include <stdarg.h>
  20. #include <dos.h>
  21.  
  22.  
  23. #define  AXIS  0                    /* GamAxis()/GamStick switch  */
  24.  
  25. #define  limit(n,max,min)  (n) > (max) ? (max) : ((n) < (min) ? (min) :(n))
  26.  
  27.  
  28. /*
  29. //-------------------------------------
  30. //
  31. // screen coordinates, sizes, etc.
  32. //
  33. //-------------------------------------
  34. */
  35.  
  36. #define  BASE_X      640            /* base with of the screen */
  37. #define  BASE_Y      480            /* base with of the screen */
  38. #define  XREF        9              /* X scaling reference     */
  39. #define  YREF        35             /* X scaling reference     */
  40. #define  OAX         170            /* x origin of joystick a  */
  41. #define  OAY         175            /* y origin of joystick a  */
  42. #define  OBX         470            /* x origin of joystick b  */
  43. #define  OBY         175            /* y origin of joystick b  */
  44. #define  JR          135            /* joystick radius         */
  45. #define  TSIZE       5              /* size of tic marks       */
  46. #define  TSPACE      10             /* spacing of tic marks    */
  47. #define  TNUM        13             /* number of tic marks     */
  48. #define  HSIZE       5              /* cross hair size         */
  49. #define  BAY         350            /* y center of a buttons   */
  50. #define  BBY         350            /* y center of b buttons   */
  51. #define  BSPACE      100            /* x space between buttons */
  52. #define  BR          20             /* button radius           */
  53. #define  BON         1              /* button on               */
  54. #define  BOFF        0              /* button off              */
  55. #define  GAIN        7              /* gain divisor for Gport  */
  56. #define  BIOS_GAIN   14             /* gain multiplier for bios*/
  57.  
  58. #define  Y_COORD_OFF 235            /* Y coordinate offset     */
  59. #define  JAY_COORD   (OAY) + Y_COORD_OFF
  60. #define  JBY_COORD   (OAY) + Y_COORD_OFF
  61. #define  TEXT_Y   370               /* text y position         */
  62.  
  63.  
  64. /*
  65. //-------------------------------------
  66. //
  67. // Text justification
  68. //
  69. //-------------------------------------
  70. */
  71.  
  72. #define  J_LEFT      0              /* left justified text     */
  73. #define  J_CENTER    1              /* center justified text   */
  74. #define  J_RIGHT     2              /* right justified text    */
  75.  
  76. /*
  77. //-------------------------------------
  78. //
  79. // keystrokes
  80. //
  81. //-------------------------------------
  82. */
  83.  
  84. #define  F1    0x3B00
  85. #define  F2    0x3C00
  86. #define  F3    0x3D00
  87. #define  F4    0x3E00
  88. #define  F5    0x3F00
  89. #define  F6    0x4000
  90. #define  F7    0x4100
  91. #define  F8    0x4200
  92. #define  F9    0x4300
  93. #define  F10   0x4400
  94. #define  ESC   0x011B
  95.  
  96.  
  97. /*
  98. //-------------------------------------
  99. //
  100. // function prototypes
  101. //
  102. //-------------------------------------
  103. */
  104.  
  105. void  Init        (void);
  106. void  Uninit      (void);
  107. void  PutAxis     (int x, int y);
  108. void  PutButton   (int x, int off);
  109. void  CrossHair   (int x, int y);
  110. void  Button      (byte status);
  111. void  PutCoord    (int x, int y, int just, signed value);
  112. void  gputs       (int x, int y, int color, int just, char *str);
  113. void  gerase      (int x, int y, int color, int just, char *str);
  114.  
  115.  
  116. /*
  117. //-------------------------------------
  118. //
  119. // global variables
  120. //
  121. //-------------------------------------
  122. */
  123.  
  124. void  *old_image[2];             /* image behind the cross hair   */
  125. int   Xasp, Yasp;                /* X and Y aspect ratios         */
  126. int   bios_ax0, bios_ay0;        /* bios values for joystick A    */
  127. int   bios_bx0, bios_by0;        /* bios values for joystick B    */
  128.  
  129.  
  130. /*
  131. //-------------------------------------
  132. //
  133. // default colors (vga/ega)
  134. //
  135. //-------------------------------------
  136. */
  137.  
  138. int   color   = YELLOW;          /* default color     */
  139. int   bcolor  = RED;             /* button color      */
  140. int   vcolor  = YELLOW;          /* values color      */
  141. int   tcolor  = GREEN;           /* text color        */
  142. int   hcolor  = WHITE;           /* cross hair color  */
  143. int   bkcolor = DARKGRAY;        /* background color  */
  144.  
  145.  
  146. /*
  147. //-------------------------------------
  148. //
  149. // function macros
  150. //
  151. //-------------------------------------
  152. */
  153.  
  154. #define  X(a)  (a)*XREF/Xasp     /* X scaling   */
  155. #define  Y(a)  (a)*YREF/Yasp     /* Y scaling   */
  156.  
  157.  
  158. /*
  159. //-------------------------------------
  160. //
  161. // main()
  162. //
  163. //-------------------------------------
  164. */
  165.  
  166. void main(void)
  167. {
  168. signed ax, ay, bx, by;                 /* joystick coordinates       */
  169. signed old_ax, old_ay, old_bx, old_by; /* old joystick coordinates   */
  170. byte   bstat;                          /* button status              */
  171. byte   old_bstat = 0;                  /* old button status          */
  172. int    key = 0;                        /* keystroke                  */
  173. int    gport = 1;                      /* gport mode flag            */
  174. union  REGS regs;                      /* CPU registers for bios     */
  175. char   *mode[] = { "Bios", "Gport" };  /* mode text                  */
  176. char   *cmode[] = { "Real", "Mean" };
  177. byte   center = 0;
  178.  
  179.  
  180.    Init();
  181.    old_ax = old_ay = old_bx = old_by =0x7fff;
  182.  
  183.  
  184.    while(key != ESC)
  185.    {
  186.  
  187.          /* If we are not in Gport mode, call the bios to */
  188.          /* get the joystick positions.                   */
  189.  
  190.       if(!gport)
  191.       {
  192.          regs.h.ah = 0x84;
  193.          regs.x.dx = 1;
  194.          int86(0x15, ®s, ®s);
  195.          ax = ( regs.x.ax - bios_ax0) * BIOS_GAIN;
  196.          ay = (-regs.x.bx + bios_ay0) * BIOS_GAIN;
  197.          bx = ( regs.x.cx - bios_bx0) * BIOS_GAIN;
  198.          by = (-regs.x.dx + bios_by0) * BIOS_GAIN;
  199.  
  200.          ax = limit(ax,1000,-1000);
  201.          ay = limit(ay,1000,-1000);
  202.          bx = limit(bx,1000,-1000);
  203.          by = limit(by,1000,-1000);
  204.  
  205.       }
  206.  
  207.  
  208.          /* If we are in Gport mode, call GamAxis or GamStick to */
  209.          /* get the joystick position for joystick A             */
  210.  
  211.       if(gport)
  212.       {
  213. #if AXIS
  214.          ax = GamAxis(JAX);
  215.          ay = GamAxis(JAY);
  216. #else
  217.          GamAxes(JA, &ax, &ay);
  218. #endif
  219.       }
  220.  
  221.  
  222.          /* If either coordinate has changed since the last time  */
  223.          /* it was checked, the screen must be updated with the   */
  224.          /* new value                                             */
  225.  
  226.       if(ax != old_ax)
  227.       {
  228.          PutCoord(OAX, JAY_COORD, textwidth("  +0000"), ax);
  229.          old_ax = ax;
  230.       }
  231.       if(ay != old_ay)
  232.       {
  233.          PutCoord(OAX, JAY_COORD, - textwidth("Y = "), ay);
  234.          old_ay = ay;
  235.       }
  236.  
  237.  
  238.          /* Apply the gain divisor to the new coordinates and  */
  239.          /* update the cross hair.                             */
  240.  
  241.       ax /= GAIN; ay /= GAIN;
  242.       CrossHair(OAX + ax, OAY - ay);
  243.  
  244.  
  245.          /* If we are in Gport mode, call GamAxis or GamStick to */
  246.          /* get the joystick position for joystick B             */
  247.  
  248.       if(gport)
  249.       {
  250. #if AXIS
  251.          bx = GamAxis(JBX);
  252.          by = GamAxis(JBY);
  253. #else
  254.          GamAxes(JB, &bx, &by);
  255. #endif
  256.       }
  257.  
  258.  
  259.          /* If either coordinate has changed since the last time  */
  260.          /* it was checked, the screen must be updated with the   */
  261.          /* new value                                             */
  262.  
  263.       if(bx != old_bx)
  264.       {
  265.          PutCoord(OBX, JBY_COORD, textwidth("  +0000") , bx);
  266.          old_bx = bx;
  267.       }
  268.       if(by != old_by)
  269.       {
  270.          PutCoord(OBX, JBY_COORD, - textwidth("Y = "), by);
  271.          old_by = by;
  272.       }
  273.  
  274.  
  275.          /* Apply the gain divisor to the new coordinates and  */
  276.          /* update the cross hair.                             */
  277.  
  278.       bx /= 7; by /= GAIN;
  279.       CrossHair(OBX + bx, OBY - by);
  280.  
  281.  
  282.          /* If we are in Gport mode, use GamButton. Otherwise */
  283.          /* make the call to the bios.                        */
  284.  
  285.       if(gport)
  286.          bstat = GamButton();
  287.       else
  288.       {
  289.          regs.h.ah = 0x84;
  290.          regs.x.dx = 0;
  291.          int86(0x15, ®s, ®s);
  292.          bstat = regs.h.al ^ 0xf0;
  293.       }
  294.  
  295.  
  296.          /* Check the button status has changed from the    */
  297.          /* last call. If it has, update the screen.        */
  298.  
  299.       if(bstat != old_bstat)
  300.       {
  301.          Button(bstat);
  302.          old_bstat = bstat;
  303.       }
  304.  
  305.  
  306.          /* If the spacebar has been pressed, toggle modes. The   */
  307.          /* screen is updated to reflect the new mode and a call  */
  308.          /* to GamButton is made to clear the button status.      */
  309.  
  310.       if(bioskey(1))
  311.       {
  312.          key = bioskey(0);
  313.          switch(key)
  314.          {
  315.             case F1:
  316.                GamCalAxis(JAX, GamRawAxis(JAX));
  317.                break;
  318.  
  319.             case F2:
  320.                GamCalAxis(JAY, GamRawAxis(JAY));
  321.                break;
  322.  
  323.             case F3:
  324.                GamCalAxis(JBX, GamRawAxis(JBX));
  325.                break;
  326.  
  327.             case F4:
  328.                GamCalAxis(JBY, GamRawAxis(JBY));
  329.                break;
  330.  
  331.             case F5:
  332.                if(gport)
  333.                {
  334.                   gerase(BASE_X/2, TEXT_Y + 20, bkcolor, J_CENTER, *(cmode + center));
  335.                   center ^= 1;
  336.                   GamCenter(center);
  337.                   gputs(BASE_X/2, TEXT_Y + 20, tcolor, J_CENTER, *(cmode + center));
  338.                   break;
  339.                }
  340.                break;
  341.  
  342.             case F6:
  343.                gerase(BASE_X/2, TEXT_Y, bkcolor, J_CENTER, *(mode + gport));
  344.                gport ^= 1;
  345.                gputs(BASE_X/2, TEXT_Y, tcolor, J_CENTER, *(mode + gport));
  346.                if(!gport)
  347.                   gerase(BASE_X/2, TEXT_Y + 20, bkcolor, J_CENTER, *(cmode + center));
  348.                else
  349.                   gputs(BASE_X/2, TEXT_Y + 20, tcolor, J_CENTER, *(cmode + center));
  350.  
  351.                Button(bstat);
  352.                break;
  353.  
  354.             case F7:
  355.                GamOpen();
  356.  
  357.                regs.h.ah = 0x84;
  358.                regs.x.dx = 1;
  359.                int86(0x15, ®s, ®s);
  360.                bios_ax0 = regs.x.ax;
  361.                bios_ay0 = regs.x.bx;
  362.                bios_bx0 = regs.x.cx;
  363.                bios_by0 = regs.x.dx;
  364.  
  365.                gerase(BASE_X/2, TEXT_Y + 20, bkcolor, J_CENTER, *(cmode + center));
  366.                break;
  367.  
  368.          }
  369.       }
  370.    }
  371.  
  372.    Uninit();
  373.  
  374. }
  375.  
  376.  
  377. /*
  378. //-------------------------------------
  379. //
  380. // initialize
  381. //
  382. //-------------------------------------
  383. */
  384.  
  385. void Init(void)
  386. {
  387. int   mode;                   /* display mode         */
  388. int   i;                      /* iterations           */
  389. int   driver = DETECT;        /* display driver       */
  390. union REGS regs;              /* registers for bios   */
  391.  
  392.  
  393.       /* Initialize the game port for Gport and the bios  */
  394.  
  395.    if(!GamOpen())
  396.    {
  397.       puts("\nGame port not detected");
  398.       exit(1);
  399.    }
  400.  
  401.  
  402.    regs.h.ah = 0x84;
  403.    regs.x.dx = 1;
  404.    int86(0x15, ®s, ®s);
  405.    bios_ax0 = regs.x.ax;
  406.    bios_ay0 = regs.x.bx;
  407.    bios_bx0 = regs.x.cx;
  408.    bios_by0 = regs.x.dx;
  409.  
  410.  
  411.       /* Detect and initialize the graphics display */
  412.  
  413.    detectgraph(&driver,&mode);
  414.    switch(driver)
  415.    {
  416.       case CGA:
  417.          mode = CGAC0;
  418.          color = CGA_YELLOW;
  419.          bcolor = CGA_RED;
  420.          vcolor = CGA_YELLOW;
  421.          tcolor = CGA_GREEN;
  422.          hcolor = CGA_RED;
  423.          bkcolor = DARKGRAY;
  424.          registerbgidriver(CGA_driver);
  425.          break;
  426.  
  427.       case EGAMONO:
  428.          color = LIGHTGRAY;
  429.          bcolor = LIGHTGRAY;
  430.          tcolor = LIGHTGRAY;
  431.          vcolor = BLACK;
  432.          hcolor = WHITE;
  433.          registerbgidriver(EGAVGA_driver);
  434.          break;
  435.  
  436.       case HERCMONO:
  437.          bcolor = WHITE;
  438.          vcolor = BLACK;
  439.          hcolor = WHITE;
  440.          bkcolor = BLACK;
  441.          registerbgidriver(Herc_driver);
  442.          break;
  443.  
  444.       default:
  445.          registerbgidriver(EGAVGA_driver);
  446.          break;
  447.    }
  448.    registerbgifont(small_font);
  449.    initgraph(&driver,&mode,0);
  450.  
  451.    Xasp = BASE_X * XREF / (getmaxx() + 1);
  452.    Yasp = BASE_Y * YREF / (getmaxy() + 1);
  453.    cleardevice();
  454.    setbkcolor(bkcolor);
  455.    settextstyle(SMALL_FONT, HORIZ_DIR, 4);
  456.  
  457.  
  458.       /* Draw our stuff on the screen  */
  459.  
  460.    gputs(OAX, 15, tcolor, J_CENTER, "Joystick A");
  461.    gputs(OBX, 15, tcolor, J_CENTER, "Joystick B");
  462.    setcolor(color);
  463.    PutAxis(OAX, OAY);
  464.    PutAxis(OBX, OBY);
  465.    for(i=-BSPACE/2; i<BSPACE; i+=BSPACE)
  466.    {
  467.       PutButton(OAX + i, BAY);
  468.       PutButton(OBX + i, BBY);
  469.    }
  470.  
  471.    gerase(BASE_X/2, TEXT_Y, bkcolor, J_CENTER, "Gport");
  472.    gputs(BASE_X/2, TEXT_Y, tcolor, J_CENTER, "Gport");
  473.    gputs(BASE_X/2, TEXT_Y + 70, tcolor, J_CENTER, "Press ESC to quit");
  474.    setcolor(color);
  475.  
  476.  
  477. }
  478.  
  479.  
  480. /*
  481. //-------------------------------------
  482. //
  483. // un-initialize
  484. //
  485. //-------------------------------------
  486. */
  487.  
  488. void Uninit(void)
  489. {
  490.    GamClose();
  491.    closegraph();
  492.    free(old_image[0]);
  493.    free(old_image[1]);
  494.    exit(0);
  495. }
  496.  
  497.  
  498. /*
  499. //-------------------------------------
  500. //
  501. // Draw the axes for a joystick
  502. //
  503. //-------------------------------------
  504. */
  505.  
  506. void PutAxis(int x, int y)
  507. {
  508. int i;
  509. static j = 0;
  510.  
  511.  
  512.       /* Draw the horizontal axis  */
  513.  
  514.    line(X(x - JR), Y(y), X(x + JR), Y(y));
  515.    for(i=TSPACE; i<TNUM*(TSPACE*2+1); i+=TSPACE)
  516.    {
  517.       moveto(X(x - TSPACE*(TNUM+1) + i), Y(y - TSIZE));
  518.       linerel(0, Y(TSIZE * 2));
  519.    }
  520.  
  521.  
  522.       /* Draw the vertical axis  */
  523.  
  524.    line(X(x), Y(y - JR), X(x), Y(y + JR));
  525.    for(i=TSPACE; i<TNUM*(TSPACE*2 + 1); i+=TSPACE)
  526.    {
  527.       moveto(X(x - TSIZE), Y(y - TSPACE*(TNUM+1) + i));
  528.       linerel(X(TSIZE * 2), 0);
  529.    }
  530.  
  531.    gputs(x, y + Y_COORD_OFF, color, J_CENTER, "X =        Y =        ");
  532.  
  533.  
  534.       /*    Allocate memory for storing the image behind the cross   */
  535.       /* hair, and store the initial image behind the initial cross  */
  536.       /* hair. Because this memory is only allocated once and the    */
  537.       /* same area on different parts of the screen may need a       */
  538.       /* different amount of memory, twice the approximate memory    */
  539.       /* needed is allocated just to be safe.                        */
  540.  
  541.    old_image[j] = malloc(imagesize(0, 0, X(HSIZE * 2), Y(HSIZE * 2)) * 2);
  542.    getimage(X(x - HSIZE), Y(y - HSIZE), X(x + HSIZE + 1), Y(y + HSIZE), old_image[j]);
  543.    CrossHair(x, y);
  544.    j++;
  545. }
  546.  
  547.  
  548. /*
  549. //-------------------------------------
  550. //
  551. // put cross hair at x,y
  552. //
  553. //-------------------------------------
  554. */
  555.  
  556. void CrossHair(int x, int y)
  557. {
  558. static i = 1;
  559. static int old_x[2] = { OAX , OBX };   /* old crosshair for joystick B  */
  560. static int old_y[2] = { OAY , OBY };   /* old crosshair for joystick A  */
  561. int old_color;                         /* current color storage         */
  562.  
  563.  
  564.       /* Restore the old image behind the cross hair, saving the     */
  565.       /* new coordinates for the next call. By XORing 'i' with 1, we */
  566.       /* flip flop between the 2 joystick                            */
  567.  
  568.    i ^= 1;
  569.  
  570.    if(x == *(old_x + i) && y == *(old_y + i))
  571.       return;
  572.  
  573.  
  574.       /* If the coordinate has not changed there is no need to    */
  575.       /* update the screen.                                       */
  576.  
  577.    putimage(X(*(old_x + i) - HSIZE), Y(*(old_y + i) - HSIZE), *(old_image + i), 0);
  578.    getimage(X(x - HSIZE), Y(y - HSIZE), X(x + HSIZE + 1), Y(y + HSIZE), *(old_image + i));
  579.  
  580.  
  581.       /* Draw the new cross hair */
  582.  
  583.    old_color = getcolor();
  584.    setcolor(hcolor);
  585.    moveto(X(x), Y(y - HSIZE));
  586.    linerel(0, Y(HSIZE * 2));
  587.    moverel(X(-HSIZE), Y(-HSIZE));
  588.    linerel(X(HSIZE * 2), 0);
  589.    setcolor(old_color);
  590.  
  591.    *(old_x + i) = x;
  592.    *(old_y + i) = y;
  593. }
  594.  
  595.  
  596. /*
  597. //-------------------------------------
  598. //
  599. // display a button
  600. //
  601. //-------------------------------------
  602. */
  603.  
  604. void PutButton(int x, int y)
  605. {
  606.    circle(X(x), Y(y), X(BR));
  607.    circle(X(x), Y(y), X(BR - 3));
  608. }
  609.  
  610.  
  611. /*
  612. //-------------------------------------
  613. //
  614. // display new button status
  615. //
  616. //-------------------------------------
  617. */
  618.  
  619. void Button(byte status)
  620. {
  621. int i = 0;
  622. byte _button;
  623. static byte button[4] = { 0, 0, 0, 0 };
  624. int y[4] = { BAY, BAY, BBY, BBY };
  625. int x[4] = { OAX - BSPACE / 2, OAX + BSPACE / 2,
  626.              OBX - BSPACE / 2, OBX + BSPACE / 2
  627.            };
  628.  
  629.       /* Or the pending status with the current status to determine  */
  630.       /* if a button has been pressed                                */
  631.  
  632.    status |= (status >> 4);
  633.  
  634.       /* Check each button for a change in it's state by shifting       */
  635.       /* the bits right once each iteration and anding with 1, and      */
  636.       /* then comparing it's new status with it's old status. If it's   */
  637.       /* status has changed, redraw the button accordingly              */
  638.  
  639.    while(i < 4)
  640.    {
  641.       _button = status & 1;
  642.       if(button[i] != _button)
  643.       {
  644.          button[i] = _button;
  645.          setfillstyle(_button, bcolor);
  646.          fillellipse(X(x[i]), Y(y[i]), X(BR - 3), Y(BR - 3));
  647.       }
  648.       status >>= 1;
  649.       i++;
  650.    }
  651. }
  652.  
  653.  
  654.  
  655. /*
  656. //-------------------------------------
  657. //
  658. // put a coordinate value
  659. //
  660. //-------------------------------------
  661. */
  662.  
  663. void PutCoord(int x, int y, int just, signed value)
  664. {
  665. char     str[80];
  666.  
  667.    sprintf(str, "%+04d", value);
  668.    gerase(x, y, bcolor, just, str);
  669.    gputs(x, y, vcolor, just, str);
  670.  
  671. }
  672.  
  673.  
  674. /*
  675. //-------------------------------------
  676. //
  677. // graphics puts
  678. //
  679. //-------------------------------------
  680. */
  681.  
  682. void gputs(int x, int y, int color, int just, char *str)
  683. {
  684.  
  685.    switch(just)
  686.    {
  687.       case J_CENTER:
  688.          just = textwidth(str) / 2;
  689.  
  690.       case J_LEFT:
  691.          break;
  692.  
  693.       case J_RIGHT:
  694.          just = textwidth(str);
  695.  
  696.       default:
  697.          break;
  698.    }
  699.  
  700.    setcolor(color);
  701.    outtextxy(X(x) - just, Y(y), str);
  702.    setcolor(color);
  703. }
  704.  
  705.  
  706. /*
  707. //-------------------------------------
  708. //
  709. // graphics erase
  710. //
  711. //-------------------------------------
  712. */
  713.  
  714. void gerase(int x, int y, int color, int just, char *str)
  715. {
  716. struct   fillsettingstype old_set;
  717.  
  718.  
  719.    switch(just)
  720.    {
  721.       case J_CENTER:
  722.          just = textwidth(str) / 2;
  723.  
  724.       case J_LEFT:
  725.          break;
  726.  
  727.       case J_RIGHT:
  728.          just = textwidth(str);
  729.    }
  730.  
  731.    getfillsettings(&old_set);
  732.    setfillstyle(SOLID_FILL, color);
  733.    bar(X(x) - just - 2, Y(y), X(x) + textwidth(str) - just + 1, Y(y) + textheight(str) + 3);
  734.    setfillstyle(old_set.pattern, old_set.color);
  735.  
  736. }
  737.