home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK4 / SAMPLES / GRAPHICS / MOUSE.C$ / MOUSE
Encoding:
Text File  |  1992-02-27  |  9.7 KB  |  349 lines

  1. /* MOUSE - Module of mouse functions. To use it, include the MOUSE.H file
  2.  * in your program. The following functions are public:
  3.  *
  4.  *   MouseInit      - Initialize mouse
  5.  *   GetMouseEvent  - Get information about most recent mouse event
  6.  *   SetPtrVis      - Set visibility of pointer to HIDE or SHOW
  7.  *   SetPtrPos      - Set position of pointer
  8.  *   SetPtrShape    - Set shape of pointer in graphics modes, or
  9.  *                    character and color in text modes
  10.  *   GetPtrPos      - Get pointer position and button status
  11.  *
  12.  * The following structure is defined:
  13.  *
  14.  *   EVENT      -   Defines x, y, and mouse status of a mouse event
  15.  */
  16.  
  17. #include <graph.h>
  18. #include "mouse.h"
  19.  
  20. /* Internal information used by various mouse functions. */
  21. struct MOUINFO
  22. {
  23.     int      fExist, fInit, fGraph;
  24.     short    xVirtual,  yVirtual;
  25.     short    xActual,   yActual;
  26.     short    xLast,     yLast;
  27.     unsigned fsBtnLast, cBtn;
  28. } static mi =
  29. {
  30.     1, 0, 0,
  31.     0, 0,
  32.     0, 0,
  33.     0, 0,
  34.     0, 0
  35. };
  36.  
  37. #pragma optimize( "lge", off )     /* /Ol, /Og, and /Oe cannot be used */
  38.                                    /* with inline assembler            */
  39.  
  40. /* MouseInit - Initialize mouse and turns on mouse pointer. Initializes
  41.  * all internal variables used by other mouse functions. This function
  42.  * should be called whenever a new video mode is set, since internal
  43.  * variables are mode-dependent.
  44.  *
  45.  * Params: none
  46.  *
  47.  * Return: 0 if no mouse available, otherwise number of buttons available
  48.  */
  49. int MouseInit()
  50. {
  51.     struct videoconfig vc;
  52.     char __far *pMode = (char __far *)0x00000449L; /* Address for mode */
  53.  
  54.     /* Get video configuration. */
  55.     _getvideoconfig( &vc );
  56.  
  57.     /* Handle special case of Hercules graphics. To use mouse with video
  58.      * page 0. assume mode 6. To use mouse with page 1, assume mode 5.
  59.      * Since the mouse functions couldn't easily detect and adjust for
  60.      * page changes anyway, this code assumes page 0. Note also that the
  61.      * mouse for Hercules graphics must be set in text mono mode.
  62.      */
  63.     if( vc.mode == _HERCMONO )
  64.     {
  65.         _setvideomode( _TEXTMONO );
  66.         *pMode = 6;
  67.     }
  68.  
  69.     mi.fInit = 1;
  70.     __asm
  71.     {
  72.         sub     ax, ax              ; Mouse function 0, reset mouse
  73.         mov     mi.cBtn, ax         ; Assume no mouse buttons
  74.         int     33h
  75.         mov     mi.fExist, ax       ; Set existence flag for future calls
  76.         or      ax, ax              ; If AX = 0, there is no mouse
  77.         jz      nomouse
  78.         mov     mi.cBtn, bx         ; Save number of mouse buttons for return
  79.     nomouse:
  80.     }
  81.     if( !mi.fExist )
  82.         return 0;
  83.  
  84.     /* Set graphics flag. */
  85.     if( vc.numxpixels )
  86.     {
  87.         mi.fGraph = 1;
  88.         mi.yActual = vc.numypixels - 1;
  89.         mi.xActual = vc.numxpixels - 1;
  90.     }
  91.     else
  92.         mi.fGraph = 0;
  93.  
  94.     /* The mouse works on a virtual screen of 640 x pixels by (8 * textrows)
  95.      * vertical pixels. By default, it assumes 640 x 200 for 25-line mode.
  96.      * You must call function 8 to adjust for other screen sizes.
  97.      */
  98.     mi.xVirtual = 639;
  99.     if( mi.fGraph )
  100.         mi.yVirtual = vc.numypixels - 1;
  101.     else
  102.         mi.yVirtual = (vc.numtextrows << 3) - 1;
  103.  
  104.     /* Reset Hercules graphics mode and reset the height. */
  105.     if( vc.mode == _HERCMONO )
  106.     {
  107.         _setvideomode( _HERCMONO );
  108.         mi.xVirtual = 719;
  109.     }
  110.  
  111.     __asm
  112.     {
  113.         mov     ax, 8               ; Set minimum and maximum vertical
  114.         sub     cx, cx              ; Minimum is 0
  115.         mov     dx, mi.yVirtual     ; Maximum is 8 * rows (or rows SHL 3)
  116.         int     33h                 ; Adjust for 25, 30, 43, 50, or 60 lines
  117.  
  118.         mov     ax, 1               ; Turn on mouse pointer
  119.         int     33h
  120.  
  121.         mov     ax, 3               ; Get initial position and button status
  122.         int     33h
  123.         mov     mi.xLast, cx        ; Save internally
  124.         mov     mi.yLast, dx
  125.         mov     mi.fsBtnLast, bx
  126.     }
  127.     return mi.cBtn;                 /* Return the number of mouse buttons */
  128. }
  129.  
  130. /* GetMouseEvent - Check to see if there has been a mouse event. If event
  131.  * occurred, update event structure.
  132.  *
  133.  * Params: pEvent - Pointer to event structure
  134.  *
  135.  * Return: 1 if event, 0 if no event
  136.  */
  137. int GetMouseEvent( EVENT __far *pEvent )
  138. {
  139.     int rtn;
  140.  
  141.     /* Make sure that mouse is initialized and exists. */
  142.     if( !mi.fInit )
  143.         MouseInit();
  144.     if( !mi.fExist )
  145.         return 0;
  146.  
  147.     __asm
  148.     {
  149.         mov     ax, 3               ; Get Mouse position and button status
  150.         int     33h
  151.         sub     ax, ax              ; Assume no event
  152.  
  153.         cmp     cx, mi.xLast        ; Has column changed?
  154.         jne     event
  155.         cmp     dx, mi.yLast        ; Has row changed?
  156.         jne     event
  157.         cmp     bx, mi.fsBtnLast    ; Has button changed?
  158.         je      noevent
  159. event:
  160.         mov     ax, 1               ; If something changed, event occurred
  161.         mov     mi.xLast, cx        ; Update internal variables
  162.         mov     mi.yLast, dx
  163.         mov     mi.fsBtnLast, bx
  164. noevent:
  165.         mov     rtn, ax             ; Set return value
  166.     }
  167.  
  168.     /* If event, put adjust values in structure. */
  169.     if( rtn )
  170.     {
  171.         /* If graphics mode, adjust virtual mouse position to actual
  172.          * screen coordinates.
  173.          */
  174.         if( mi.fGraph )
  175.         {
  176.             pEvent->x = (short)((long)mi.xLast * mi.xActual) / mi.xVirtual;
  177.             pEvent->y = (short)((long)mi.yLast * mi.yActual) / mi.yVirtual;
  178.         }
  179.         /* If text mode, adjust virtual mouse position to 1-based
  180.          * row/column.
  181.          */
  182.         else
  183.         {
  184.             pEvent->x = (mi.xLast >> 3) + 1;
  185.             pEvent->y = (mi.yLast >> 3) + 1;
  186.         }
  187.         pEvent->fsBtn = mi.fsBtnLast;
  188.     }
  189.     return rtn;
  190. }
  191.  
  192. /* GetPtrPos - Get mouse pointer position and button status regardless of
  193.  * whether there was an event.
  194.  *
  195.  * Params: pEvent - Pointer to event structure
  196.  *
  197.  * Return: 0 if no mouse, otherwise 1
  198.  */
  199. int GetPtrPos( EVENT __far *pEvent )
  200. {
  201.     /* Make sure that mouse is initialized and exists. */
  202.     if( !mi.fInit )
  203.         MouseInit();
  204.     if( !mi.fExist )
  205.         return 0;
  206.  
  207.     __asm
  208.     {
  209.         mov     ax, 3               ; Get Mouse position and button status
  210.         int     33h
  211.         les     di, pEvent
  212.         mov     es:pEvent[di].x, cx
  213.         mov     es:pEvent[di].y, dx
  214.         mov     es:pEvent[di].fsBtn, bx
  215.     }
  216.  
  217.     /* If graphics mode, adjust virtual mouse position to actual
  218.      * screen coordinates.
  219.      */
  220.     if( mi.fGraph )
  221.     {
  222.         pEvent->x = (short)((long)pEvent->x * mi.xActual) / mi.xVirtual;
  223.         pEvent->y = (short)((long)pEvent->y * mi.yActual) / mi.yVirtual;
  224.     }
  225.     /* If text mode, adjust virtual mouse position to 1-based
  226.      * row/column.
  227.      */
  228.     else
  229.     {
  230.         pEvent->x >>= 3;
  231.         pEvent->y >>= 3;
  232.         pEvent->x++;
  233.         pEvent->y++;
  234.     }
  235.     return 1;
  236. }
  237.  
  238. /* SetPtrVis - Set pointer visibility.
  239.  *
  240.  * Params: state - SHOW or HIDE
  241.  *
  242.  * Return: 0 if no mouse, otherwise 1
  243.  */
  244. int SetPtrVis( PTRVIS pv )
  245. {
  246.     /* Make sure that mouse is initialized and exists. */
  247.     if( !mi.fInit )
  248.         MouseInit();
  249.     if( !mi.fExist )
  250.         return 0;
  251.  
  252.     __asm
  253.     {
  254.         mov ax, pv                  ; Show or hide mouse pointer
  255.         int 33h
  256.     }
  257. }
  258.  
  259. /* SetPtrPos - Set mouse pointer position.
  260.  *
  261.  * Params: x - column position in text modes, actual x coordinate in graphics
  262.  *         y - row position in text modes, actual y coordinate in graphics
  263.  *
  264.  * Return: 0 if no mouse, otherwise 1
  265.  */
  266. int SetPtrPos( short x, short y )
  267. {
  268.     /* Make sure that mouse is initialized and exists. */
  269.     if( !mi.fInit )
  270.         MouseInit();
  271.     if( !mi.fExist )
  272.         return 0;
  273.  
  274.     /* If graphics, adjust actual coordinates to virtual coordinates. */
  275.     if( mi.fGraph )
  276.     {
  277.         x = (short)((long)x * mi.xActual) / mi.xVirtual;
  278.         y = (short)((long)y * mi.yActual) / mi.yVirtual;
  279.     }
  280.     /* If text, adjust row/column to 0-based virtual coordinates. */
  281.     else
  282.     {
  283.         x--;
  284.         y--;
  285.         x <<= 3;
  286.         y <<= 3;
  287.     }
  288.  
  289.     __asm
  290.     {
  291.         mov     ax, 4               ; Set mouse position
  292.         mov     cx, x
  293.         mov     dx, y
  294.         int     33h
  295.     }
  296.     return 1;
  297. }
  298.  
  299. /* SetPtrShape - Set mouse pointer shape.
  300.  *
  301.  * Params: x - column position in text modes, actual x coordinate in graphics
  302.  *         y - row position in text modes, actual y coordinate in graphics
  303.  *
  304.  * Return: 0 if no mouse, otherwise 1
  305.  */
  306. int SetPtrShape( PTRSHAPE __far *ps )
  307. {
  308.     /* Make sure that mouse is initialized and exists. */
  309.     if( !mi.fInit )
  310.         MouseInit();
  311.     if( !mi.fExist )
  312.         return 0;
  313.  
  314.     /* If graphics, use pointer shape bitmask array. */
  315.     if( mi.fGraph )
  316.     {
  317.         __asm
  318.         {
  319.             les     di, ps
  320.             mov     bx, es:[di].g.xHot      ; Load hot spot offsets
  321.             mov     cx, es:[di].g.yHot
  322.             mov     dx, di
  323.             add     dx, 4
  324.  
  325.             mov     ax, 9                   ; Set graphics pointer
  326.             int     33h
  327.         }
  328.     }
  329.     /* If text, use pointer color/character values. */
  330.     else
  331.     {
  332.         __asm
  333.         {
  334.             les     di, ps
  335.             mov     bx, 0                   ; Use software cursor
  336.             mov     cl, es:[di].t.chScreen
  337.             mov     ch, es:[di].t.atScreen
  338.             mov     dl, es:[di].t.chCursor
  339.             mov     dh, es:[di].t.atCursor
  340.  
  341.             mov     ax, 10                  ; Set text pointer
  342.             int     33h
  343.         }
  344.     }
  345.     return 1;
  346. }
  347.  
  348. #pragma optimize( "", on )
  349.