home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / games / gi / joy.c < prev    next >
C/C++ Source or Header  |  1993-11-07  |  14KB  |  425 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*   Main-Module   : Joystick-Interface mit Game-Support & Self-Config      */
  4. /*                                                                          */
  5. /*   Version       : V1.00                                                  */
  6. /*                                                                          */
  7. /*   Date          : 10.05.93                                               */
  8. /*                                                                          */
  9. /*   Written       : RF                                                     */
  10. /*                                                                          */
  11. /*     Revision History :
  12.  
  13.     15.05.93    RF  Init-Konzept neu
  14.     29.10.93    RF    kbd.h wird nicht mehr importiert
  15.                                                                             */
  16. /*--------------------------------------------------------------------------*/
  17. #define INCL_DOSDEVICES
  18. #define INCL_PM
  19. #include <os2.h>
  20. #pragma hdrstop
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <mem.h>
  25. #include <string.h>
  26. #include <gi.h>
  27. #include <checkbox.hpp>
  28. #include <slider.hpp>
  29.  
  30. typedef struct
  31.     {
  32.     SHORT   ax;                // A Joystick X position
  33.     SHORT   ay;             // A Joystick Y position
  34.     SHORT   bx;                // B Joystick X position
  35.     SHORT   by;                // B Joystick Y position
  36.     USHORT  a1c;            // Button A1 Press Count
  37.     USHORT  a2c;            // Button A2 Press Count
  38.     USHORT  b1c;            // Button B1 Press Count
  39.     USHORT  b2c;            // Button B2 Press Count
  40.     UCHAR ucJs_JoyStickMask;    // Mask of Connected Joystick Pots
  41.     UCHAR   button;            // Bits of Switches Down
  42.     LONG   lJs_Ticks;        // Total Clock Ticks (60 Hz)
  43.     } JOYSTATUS, *JOYSTATUSP;
  44.  
  45. typedef struct
  46.     {
  47.     BOOL    init;
  48.     BOOL    abflag;
  49.     BOOL    buttonswap;
  50.     USHORT  threshold;
  51.     USHORT  scale[4];
  52.  
  53.     // Instance Data
  54.     HFILE   jhand;
  55.     SHORT   x, y, b1, b2, xo, yo;
  56.     char    dir[6];
  57.     } JOYCONFIG, *JOYCONFIGP;
  58.  
  59. #define MAXSTATUS   50
  60. #define DEFNAME     "joy.cfg"
  61. #define JOYCLASS    "JoyConfig"
  62. #define ABST        3
  63. #define BOXSIZE     4
  64.  
  65. /*--------------------------------------------------------------------------*/
  66. /*---- Globals for Config-Part ----*/
  67. HMODULE     module;
  68. HAB         hab;
  69. char        statustext[3][MAXSTATUS];
  70. HWND        wid[18], but_ok, but_cancel;
  71. SLIDER      slider;
  72. ULONG       mx, my, ctitle, cborder;
  73. USHORT      tmpscale[4];
  74. RECTL       rcl = {0,0,0,0 };            // Update of Joy-Rectl
  75. unsigned    refresh=0;
  76. int         mode;
  77. BOOL        wait;
  78. JOYCONFIGP  gjc;
  79.  
  80. /*--------------------------------------------------------------------------*/
  81. extern "C" {
  82. ULONG _dllmain (ULONG termflag, HMODULE modhandle)
  83.     {
  84.     if (!termflag)  // Init...
  85.         module = modhandle;
  86.  
  87.     return (TRUE);
  88.     }
  89. }
  90. /*--------------------------------------------------------------------------*/
  91. extern "C"  {
  92. unsigned _export GetDataSize (void)
  93.     {
  94.     return (sizeof (JOYCONFIG));    // Oh, what a hack!
  95.     }
  96. }
  97. /*--------------------------------------------------------------------------*/
  98. extern "C" {
  99. unsigned _export  InitializeDLL (char __far16 *data)
  100.     {
  101.     ULONG       action;
  102.     JOYCONFIGP  jc;
  103.  
  104.     jc = (JOYCONFIGP)data;
  105.  
  106.     if (!jc->init)           // Create New Config
  107.         {
  108.         jc->init     = TRUE;
  109.         jc->abflag   = FALSE;      // A-Joy
  110.         jc->buttonswap= FALSE;
  111.         jc->threshold = THRESHOLD;
  112.         jc->scale[2] = jc->scale[1] = 1300;   // My Joy-Values...
  113.         jc->scale[0] = jc->scale[3] = 0;
  114.         }
  115.  
  116.     // Open Joy-Driver
  117.     DosOpen ("GAME$", &jc->jhand, &action, 0L, 0L, 0x11L,
  118.                 OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NO_LOCALITY | OPEN_SHARE_DENYNONE,
  119.                 NULL);
  120.  
  121.     return (NOERR);
  122.     }
  123. }
  124. /*--------------------------------------------------------------------------*/
  125. extern "C" {
  126. unsigned _export  Name (char __far16 *target)
  127.     {
  128.     strcpy (target, "Joystick");
  129.     return (0);
  130.     }
  131. }
  132. /*--------------------------------------------------------------------------*/
  133. void GetJoy (JOYCONFIGP jc)
  134.     {
  135.     ULONG       actsize = sizeof (JOYSTATUS);
  136.     BOOL        h;
  137.     JOYSTATUS   js;
  138.  
  139.     DosDevIOCtl(jc->jhand, 0x80, 0x20, NULL, 0, NULL, &js, actsize, &actsize);
  140.  
  141.     jc->xo = (jc->abflag ? js.bx : js.ax) - jc->scale[3];
  142.     jc->yo = (jc->abflag ? js.by : js.ay) - jc->scale[0];
  143.     jc->b1 = jc->abflag ? (js.button & 64)>>6   : (js.button & 16)>>4;
  144.     jc->b2 = jc->abflag ? (js.button & 0x80)>>7 : (js.button & 32)>>5;
  145.  
  146.     // Skalierung
  147.     jc->x = 200*jc->xo / (jc->scale[1]-jc->scale[3]);    // Das Intervall wird auf 0..200 skaliert
  148.     jc->y = 200*jc->yo / (jc->scale[2]-jc->scale[0]);
  149.  
  150.     // Richtungen extrahieren
  151.     if (jc->x >= 100)
  152.         {
  153.         jc->dir[1] = jc->x - 100;
  154.         jc->dir[3] = 0;
  155.         }
  156.     else
  157.         {
  158.         jc->dir[1] = 0;
  159.         jc->dir[3] = 100 - jc->x;
  160.         }
  161.     if (jc->y >= 100)      // Y arbeitet invers !!!
  162.         {
  163.         jc->dir[2] = jc->y - 100;
  164.         jc->dir[0] = 0;
  165.         }
  166.     else
  167.         {
  168.         jc->dir[2] = 0;
  169.         jc->dir[0] = 100 - jc->y;
  170.         }
  171.  
  172.     // Button-Swap
  173.     if (jc->buttonswap)
  174.         {
  175.         h      = jc->b1;
  176.         jc->b1 = jc->b2;
  177.         jc->b2 = h;
  178.         }
  179.     jc->dir[4] = jc->b1;
  180.     jc->dir[5] = jc->b2;
  181.     }
  182. /*--------------------------------------------------------------------------*/
  183. MRESULT    EXPENTRY maxproc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  184.     {
  185.     char        txt[10];
  186.  
  187.     switch (msg)
  188.         {
  189.         case WM_INITDLG:
  190.             WinSetWindowText (WinWindowFromID (hwnd, 201), statustext[0]);
  191.             mode = 0;
  192.             wait = FALSE;
  193.             WinStartTimer (hab, hwnd, 2, 100);
  194.             break;
  195.         case WM_TIMER:
  196.             GetJoy (gjc);
  197.             WinSetWindowText (WinWindowFromID (hwnd, 203), itoa (gjc->x, txt, 10));
  198.             WinSetWindowText (WinWindowFromID (hwnd, 205), itoa (gjc->y, txt, 10));
  199.  
  200.             if (gjc->b1|gjc->b2 && !wait)
  201.                 wait = TRUE;
  202.             else if (gjc->b1|gjc->b2 && wait)
  203.                 break;
  204.             else if (!(gjc->b1|gjc->b2) && wait)
  205.                 {
  206.                 wait = FALSE;
  207.                 if (mode==0)
  208.                     {
  209.                     tmpscale[0] = gjc->yo;
  210.                     tmpscale[3] = gjc->xo;
  211.                     WinSetWindowText (WinWindowFromID (hwnd, 201), statustext[1]);
  212.                     mode++;
  213.                     DosBeep (1000, 100);
  214.                     }
  215.                 else if (mode==1)
  216.                     {
  217.                     tmpscale[1] = gjc->xo;
  218.                     tmpscale[2] = gjc->yo;
  219.                     WinSetWindowText (WinWindowFromID (hwnd, 201), statustext[2]);
  220.                     mode++;
  221.                     DosBeep (1200, 100);
  222.                     }
  223.                 }
  224.             break;
  225.         case WM_COMMAND:
  226.             WinStopTimer (hab, hwnd, 2);
  227.             switch (SHORT1FROMMP (mp1))
  228.                 {
  229.                 case DID_OK:
  230.                     gjc->scale[0] = tmpscale[0];
  231.                     gjc->scale[1] = tmpscale[1];
  232.                     gjc->scale[2] = tmpscale[2];
  233.                     gjc->scale[3] = tmpscale[3];
  234.                     WinDismissDlg (hwnd, TRUE);
  235.                     break;
  236.                 case DID_CANCEL:
  237.                     WinDismissDlg (hwnd, FALSE);
  238.                     break;
  239.                 }
  240.             return (0);
  241.         default:
  242.             return (WinDefDlgProc (hwnd, msg, mp1, mp2));
  243.         }
  244.     return (0);
  245.     }
  246. /*--------------------------------------------------------------------------*/
  247. MRESULT    EXPENTRY joyproc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  248.     {
  249.     HPS     hps;
  250.     POINTL  p;
  251.     RECTL   rr;
  252.  
  253.     switch (msg)
  254.         {
  255.         case WM_CREATE:
  256.             WinStartTimer (hab, hwnd, 1, 100);
  257.             return (FALSE);
  258.         case WM_TIMER:
  259.             WinInvalidateRect (hwnd, NULL, FALSE);
  260.             return (0);
  261.         case WM_ENABLE:
  262.             if (SHORT1FROMMP (mp1))
  263.                 WinStartTimer (hab, hwnd, 1, 100);
  264.             else
  265.                 WinStopTimer (hab, hwnd, 1);
  266.             return (0);
  267.         case WM_PAINT:
  268.             hps = WinBeginPaint (hwnd, NULL, &rr);
  269.             if (rcl.xLeft == rcl.xRight || refresh==10)
  270.                 {
  271.                 WinFillRect (hps, &rr, CLR_WHITE);
  272.                 refresh=0;
  273.                 }
  274.             else
  275.                 {
  276.                 WinFillRect (hps, &rcl, CLR_WHITE);
  277.                 refresh++;
  278.                 }
  279.  
  280.             // Position des Joysticks zeichnen
  281.             GetJoy (gjc);
  282.             rcl.xLeft = gjc->x*2*mx/200;
  283.             rcl.yBottom = 2*my - (gjc->y*2*my/200);
  284.             rcl.xRight = rcl.xLeft + BOXSIZE;
  285.             rcl.yTop = rcl.yBottom + BOXSIZE;
  286.             WinFillRect (hps, &rcl, CLR_BLACK);
  287.             WinEndPaint (hps);
  288.  
  289.             // Checkboxen aktivieren
  290.             CheckBoxSet (wid[ 7], gjc->dir[0] > gjc->threshold);  // Up
  291.             CheckBoxSet (wid[ 8], gjc->dir[1] > gjc->threshold);  // Right
  292.             CheckBoxSet (wid[ 9], gjc->dir[2] > gjc->threshold);  // Down
  293.             CheckBoxSet (wid[10], gjc->dir[3] > gjc->threshold);  // Left
  294.             CheckBoxSet (wid[12], gjc->dir[4]);                  // Button 1
  295.             CheckBoxSet (wid[13], gjc->dir[5]);                  // Button 2
  296.             return (0);
  297.         default:
  298.             return (WinDefWindowProc (hwnd, msg, mp1, mp2));
  299.         }
  300.     }
  301. /*--------------------------------------------------------------------------*/
  302. MRESULT    EXPENTRY dlgproc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  303.     {
  304.     int         i;
  305.     SWP         swp;
  306.  
  307.     switch (msg)
  308.         {
  309.         case WM_INITDLG:
  310.             hab=WinInitialize (0);
  311.             for (i=0; i<18; i++)
  312.                 wid[i] = WinWindowFromID (hwnd, i+101);
  313.             but_ok      = WinWindowFromID (hwnd, DID_OK);
  314.             but_cancel  = WinWindowFromID (hwnd, DID_CANCEL);
  315.             WinLoadString (hab, module, 200, MAXSTATUS, statustext[0]);
  316.             WinLoadString (hab, module, 201, MAXSTATUS, statustext[1]);
  317.             WinLoadString (hab, module, 202, MAXSTATUS, statustext[2]);
  318.  
  319.             WinSetWindowText (wid[0], statustext[0]);
  320.             CheckBoxSet (wid[11], gjc->buttonswap);
  321.             slider.Set (wid[4]);
  322.             for (i=0; i<11; i++)
  323.                 slider.SetTickSize (i, 6);
  324.             slider.SetScaleText (0, "0%");
  325.             slider.SetScaleText (5, "50%");
  326.             slider.SetScaleText (10, "100%");
  327.             slider.SetSliderPos (gjc->threshold/10);
  328.  
  329.             ctitle = WinQuerySysValue (HWND_DESKTOP, SV_CYTITLEBAR);
  330.             cborder= WinQuerySysValue (HWND_DESKTOP, SV_CXBORDER);
  331.             WinQueryWindowPos (wid[1], &swp);
  332.             WinRegisterClass (hab, JOYCLASS, joyproc, CS_SAVEBITS | CS_SYNCPAINT, 0);
  333.             mx = (swp.cx-BOXSIZE)/2-ABST;
  334.             my = (swp.cy-BOXSIZE-ctitle)/2-ABST;
  335.             wid[2] = WinCreateWindow (wid[1], JOYCLASS, NULL, WS_VISIBLE, ABST, ABST,
  336.                         mx*2+BOXSIZE, my*2+BOXSIZE, wid[1], HWND_TOP, 103, NULL, 0);
  337.             if (!wid[2])
  338.                 return (TRUE);  // Abort Creation
  339.  
  340.             CheckBoxSet (wid[16], !gjc->abflag);
  341.             CheckBoxSet (wid[17], gjc->abflag);
  342.             return (FALSE);
  343.         case WM_COMMAND:
  344.             switch (SHORT1FROMMP (mp1))
  345.                 {
  346.                 case DID_OK:
  347.                     WinDismissDlg (hwnd, TRUE);
  348.                     break;
  349.                 case DID_CANCEL:
  350.                     WinDismissDlg (hwnd, FALSE);
  351.                     break;
  352.                 case 115:   // Def. Max
  353.                     WinEnableWindow (but_ok, FALSE);
  354.                     WinEnableWindow (but_cancel, FALSE);
  355.                     for (i=1; i<14; i++)
  356.                         WinEnableWindow (wid[i], FALSE);
  357.                     WinDlgBox (hwnd, hwnd, maxproc, module, 200, NULL);
  358.                     for (i=1; i<14; i++)
  359.                         WinEnableWindow (wid[i], TRUE);
  360.                     WinEnableWindow (but_cancel, TRUE);
  361.                     WinEnableWindow (but_ok, TRUE);
  362.                     break;
  363.                 }
  364.             break;
  365.         case WM_CONTROL:
  366.             if (SHORT1FROMMP (mp1) == 105 && SHORT2FROMMP (mp1) == SLN_CHANGE)
  367.                 gjc->threshold = 10*slider.QuerySliderPos();
  368.             else if (SHORT1FROMMP (mp1) == 112)
  369.                 gjc->buttonswap = CheckBoxQuery (wid[11]);
  370.             else if (SHORT1FROMMP (mp1) == 117 || SHORT1FROMMP (mp1) == 118)
  371.                 gjc->abflag = !CheckBoxQuery (wid[16]);
  372.             break;
  373.         default:
  374.             return (WinDefDlgProc (hwnd, msg, mp1, mp2));
  375.         }
  376.     return (0L);
  377.     }
  378. /*--------------------------------------------------------------------------*/
  379. extern "C" {
  380. unsigned _export  ConfigDLL (char __far16 *dd)
  381.     {
  382.     JOYCONFIG   jcold;
  383.  
  384.     gjc = (JOYCONFIGP)dd;
  385.     jcold = *gjc;
  386.  
  387.     if (WinDlgBox (HWND_DESKTOP, HWND_DESKTOP, dlgproc, module, 100, NULL) == FALSE)
  388.         *gjc = jcold;
  389.  
  390.     return (0);
  391.     }
  392. }
  393. /*--------------------------------------------------------------------------*/
  394. extern "C" {
  395. unsigned _export  Threshold (char __far16 *dd)
  396.     {
  397.     JOYCONFIGP  jc;
  398.  
  399.     jc = (JOYCONFIGP)dd;
  400.     return (jc->threshold);
  401.     }
  402. }
  403. /*--------------------------------------------------------------------------*/
  404. extern "C" {
  405. unsigned _export  Direction (char __far16 *dd, char __far16 *de)
  406.     {
  407.     JOYCONFIGP      jc;
  408.     PLAYERINFOP     pi;
  409.  
  410.     jc = (JOYCONFIGP)dd;
  411.     pi = (PLAYERINFOP)de;
  412.  
  413.     GetJoy (jc);
  414.     pi->dir[0] = jc->dir[0];
  415.     pi->dir[1] = jc->dir[1];
  416.     pi->dir[2] = jc->dir[2];
  417.     pi->dir[3] = jc->dir[3];
  418.     pi->dir[4] = jc->dir[4];
  419.     pi->dir[5] = jc->dir[5];
  420.     return (0);
  421.     }
  422. }
  423. /*--------------------------------------------------------------------------*/
  424.  
  425.