Click here if you are stuck in someone else's frames.


If this page looks like garbage then you need one of these browsers...

Microsoft Internet Explorer

Netscape Navigator

Please sign my programmer's page guestbook.

Please sign my guestbook

View my guestbook entries

Communicating with the Mouse in BASIC


The mouse is one of those elusive devices that seem simple, yet can be quite sophisticated as you try to understand how to get your programs to communicate with them. After you learned the nuanses of interfacing your programs with the mouse, you find that it is pretty simple after all, at least from the programmer's standpoint.

The mouse basically works by tracking which direction and how fast it is going and sends this information in a serial stream (typically through a COM port). Most mice do this with a ball located inside the mouse that turns two rotating drums, one for the horizontal direction and one for the vertical direction. These two 'drums' have holes in them that allow a light beam through them (or electrical contacts on both sides to touch) at intermittent places all around. As you move the mouse, the light goes through the holes and then breaks (or the electrical contacts short and then open) generating pulses that are then sent to the computer through the serial stream.

Most mice send the data stream in a format that is Microsoft compatible, but whatever format it uses, a mouse driver software then reads this stream of pulses and translates it into useful information that can be made available to us. We could write programs that would read the actual stream itself, but it is never a good idea since that would be quite an undertaking. So to make the mouse useful for our programs, we communicate with the mouse driver software instead.

The mouse driver software is a TSR program supplied by the manufacturer of the mouse hardware. It has either a COM or a SYS extension (an EXE is also possible) and is loaded either from the CONFIG.SYS or the AUTOEXEC.BAT file. The software, once loaded, takes care of all the communications with the mouse. It tracks that location of the mouse on the screen and even provides a standard mouse cursor for all of the standard video modes, including mode 13h. So mainly all we need to do is get the status of the mouse coordinates and it's buttons and let it do the rest.


Using the mouse in code

Basically, to communicate with the mouse driver we do the following things:

  • Load register AX with the value corresponding to which mouse function we want the mouse driver to do.
  • If applicable, load registers BX, CX, DX, and sometimes ES with the appropriate input values needed by the particular function we are about to call.
  • Invoke interrupt 33h to call the appropriate function set in AX.
  • The mouse driver will then set the registers AX, BX, CX, and DX to the appropriate values that you requested.

This sounds simple enough and indeed it is. All we need to know now are what these 'so-called appropriate' values are on the entry and exit conditions of interrupt 33h.

To help you out, I created this table listing some of the major functions we will be using to program the mouse into our programs.

Mouse function Entry Conditions Exit conditions
Reset mouse AX = 0000h
If mouse driver is loaded
AX = FFFFh
BX = number of buttons supported
else
AX remains unchanged
Comments: Use this function first to test for the presence of a mouse driver and ultimately a mouse. If a mouse driver is not detected, register AX remains unchanged (0000h). Please note that the number of mouse buttons set in BX is the number of buttons that the driver supports not necesarily the physical number of buttons on the mouse itself. This function is also used to reset any settings back to default.
Mouse function Entry Conditions Exit conditions
Show cursor AX = 0001h None
Comments: This functions shows the mouse cursor by incrementing the visibility cursor counter by 1. This function must be called the same number of times the hide cursor function was called in order for the cursor to be visible.
Mouse function Entry Conditions Exit conditions
Hide cursor AX = 0002h None
Comments: This functions hides the cursor by decrementing the visibility counter by one. A corresponding number of calls to Show cursor must be made to actually redisplay the mouse cursor.
Mouse function Entry Conditions Exit conditions
Get Mouse Status AX = 0003h
In register BX
Bit 2 = Center button state
Bit 1 = Right button state
Bit 0 = Left button state
CX = current X coordinate
DX = current Y coordinate
Comments: The bits in register BX are high (1) when the button is pressed and low (0) when the button is released. The cursor position (X and Y coordinates) are in mouse coordinates (always 640x200) not screen coordinates.
Mouse function Entry Conditions Exit conditions
Set Mouse Position AX = 0004h
CX = X Coordinate
DX = Y Coordinate
None
Comments: The Coordinates are in mouse coordinates, not screen coordinates.

Let's see some code!

The following QuickBASIC program demonstrates the four mouse functions illustrated in the above table.

' MOUSY.BAS

' This program written in QuickBASIC illustrates the
' basic mouse usage.  Quick and dirty by Gary Neal Jr.

'$INCLUDE: 'QB.BI'

' Our encapsulated mouse functions
DECLARE FUNCTION ResetMouse% ()
DECLARE SUB MouseShow ()
DECLARE SUB MouseHide ()
DECLARE FUNCTION MouseStatus% (X AS INTEGER, Y AS INTEGER)
DECLARE SUB MouseMove (X AS INTEGER, Y AS INTEGER)

DIM SHARED regs AS RegType

' Check to see if a mouse is installed
IF ResetMouse% = 0 THEN
    PRINT "Sorry, you do not have a mouse installed."
    END
END IF

SCREEN 13  ' Set mode 13h

MouseShow

' Print instructions
LOCATE 25, 1
PRINT "S-Show H-Hide M-Move ESC-Quit";

DO
    Button% = MouseStatus%(X%, Y%)
    LOCATE 1, 1
    PRINT "Coordinates"; X%; ","; Y%; "     "
    IF (Button% AND 4) THEN
        PRINT "Center button pressed"
    ELSE
        PRINT SPACE$(21)
    END IF

    IF (Button% AND 2) THEN
        PRINT "Right button pressed"
    ELSE
        PRINT SPACE$(21)
    END IF

    IF (Button% AND 1) THEN
        PRINT "Left button pressed"
    ELSE
        PRINT SPACE$(21)
    END IF

    a$ = INKEY$
    IF a$ = "s" OR a$ = "S" THEN MouseShow
    IF a$ = "h" OR a$ = "H" THEN MouseHide
    IF a$ = "m" OR a$ = "M" THEN MouseMove RND * 640, RND * 200
LOOP UNTIL a$ = CHR$(27)
END

SUB MouseHide
    regs.AX = 2

    ' Hide the mouse cursor
    CALL INTERRUPT(&H33, regs, regs)
END SUB

SUB MouseMove (X AS INTEGER, Y AS INTEGER)
    regs.AX = 4
    regs.CX = X
    regs.DX = Y

    ' Move the mouse cursor
    CALL INTERRUPT(&H33, regs, regs)
END SUB

SUB MouseShow
    regs.AX = 1

    ' Show the mouse cursor
    CALL INTERRUPT(&H33, regs, regs)
END SUB

FUNCTION MouseStatus% (X AS INTEGER, Y AS INTEGER)
    regs.AX = 3

    ' Get Mouse Status
    CALL INTERRUPT(&H33, regs, regs)

    ' Assign our variables
    X = regs.CX
    Y = regs.DX
    MouseStatus% = regs.BX
END FUNCTION

FUNCTION ResetMouse%
    regs.AX = 0

    ' Check and reset mouse
    CALL INTERRUPT(&H33, regs, regs)

    ' If a mouse is loaded,
    ' return number of buttons
    ' or else return 0
    IF regs.AX = 0 THEN
        ResetMouse% = 0
    ELSE
        ResetMouse% = regs.BX
    END IF
END FUNCTION
    

In addition there are some other mouse programs that I found on the news groups that allow you QBasic users to add mouse control to your programs.


Send your questions, comments, or ideas to: wilkeg@gamewood.net

This page hosted by GeoCities Get your own Free Home Page
Back |