'
' NeoLib - Mouse Module
'
' Features:
'  6 subs
'  7 functions
' For a total of: 13 routines
'
' Specially designed and coded for AAP's QBCPC
' Official Library of the QuickBASIC Caliber Programming Compo (Summer & Autumn 2003)
'

DECLARE FUNCTION neoMouseInit% ()
DECLARE FUNCTION neoMouseGetButtons% ()
DECLARE FUNCTION neoMouseX% ()
DECLARE FUNCTION neoMouseY% ()
DECLARE FUNCTION neoMouseLB% ()
DECLARE FUNCTION neoMouseRB% ()
DECLARE FUNCTION neoMouseMB% ()

DECLARE SUB neoMouseShow ()
DECLARE SUB neoMouseHide ()
DECLARE SUB neoMouseSetPos (NewX AS INTEGER, NewY AS INTEGER)
DECLARE SUB neoMouseSetRange (MinX AS INTEGER, MinY AS INTEGER, MaxX AS INTEGER, MaxY AS INTEGER)
DECLARE SUB neoMouseSetShape (NewShape AS STRING, HotX AS INTEGER, HotY AS INTEGER)
DECLARE SUB neoMouseSetSensitivity (Xsens AS INTEGER, Ysens AS INTEGER)

DEFINT A-Z
'$DYNAMIC
'$INCLUDE: 'QB.BI'

DIM SHARED Regs AS RegType
DIM SHARED RegsX AS RegTypeX

'///////////////////////////////////////////////////////////////////////////////
' FUNCTIONS
'///////////////////////////////////////////////////////////////////////////////
FUNCTION neoMouseInit
        'initializes mouse
        'Returns:
        ' -1: mouse found
        '  0: mouse not found

	'do int 33h -> reset driver and read status
        Regs.ax = 0
        INTERRUPT &H33, Regs, Regs

        'now ax contains values: 0 = mouse not found, FFFFh = mouse found
        IF Regs.ax = 0 THEN neoMouseInit = 0 ELSE neoMouseInit = -1
END FUNCTION

FUNCTION neoMouseGetButtons
        'returns the number of buttons on mouse

        'do int 33h -> reset driver and read status
        Regs.ax = 0
        INTERRUPT &H33, Regs, Regs

        'now bx contains the number of buttons
        Butts% = 0
        SELECT CASE Regs.bx
        	CASE &H2: Butts% = 2
        	CASE &H3: Butts% = 3
        	CASE -1: Butts% = 2
        	CASE ELSE: Butts% = 3	 'not included the apple-one-button-mouse
        END SELECT
        neoMouseGetButtons = Butts%
END FUNCTION

FUNCTION neoMouseX
	'returns the 13h x-position of the mouse

	'use int33h, ax = 3
        Regs.ax = 3
        INTERRUPT &H33, Regs, Regs

        'x pos is in cx
        neoMouseX = Regs.cx \ 2
END FUNCTION

FUNCTION neoMouseY
	'returns the y-position of the mouse

	'use int33h, ax = 3
	Regs.ax = 3
        INTERRUPT &H33, Regs, Regs

        'y pos is in dx
        neoMouseY = Regs.dx
END FUNCTION

FUNCTION neoMouseLB
	'returns the status of the left-button

	'use int33h, ax = 3
	Regs.ax = 3
        INTERRUPT &H33, Regs, Regs

        'button status in in bx
        IF Regs.bx AND 1 THEN neoMouseLB = -1 ELSE neoMouseLB = 0
END FUNCTION

FUNCTION neoMouseRB
	'returns the status of the right-button

	'use int33h, ax = 3
	Regs.ax = 3
        INTERRUPT &H33, Regs, Regs

        'button status in in bx
        IF Regs.bx AND 2 THEN neoMouseRB = -1 ELSE neoMouseRB = 0
END FUNCTION

FUNCTION neoMouseMB
	'returns the status of the middle button

	'use int33h, ax = 3
	Regs.ax = 3
        INTERRUPT &H33, Regs, Regs

        'button status in in bx
        IF Regs.bx AND 4 THEN neoMouseMB = -1 ELSE neoMouseMB = 0
END FUNCTION

'///////////////////////////////////////////////////////////////////////////////
' SUBS
'///////////////////////////////////////////////////////////////////////////////
SUB neoMouseShow
	'shows the mouse cursor

	'use interrupt 33h, ax = 1
	Regs.ax = 1
	INTERRUPT &H33, Regs, Regs
END SUB

SUB neoMouseHide
	'hides the mouse cursor
	'NOTE: multiple calls to this function require multiple calls to neoMouseShow to unhide it

	'use interrupt 33h, ax = 2
	Regs.ax = 2
	INTERRUPT &H33, Regs, Regs
END SUB

SUB neoMouseSetPos (NewX AS INTEGER, NewY AS INTEGER)
	'sets the position of the mouse cursor
	' NewX = new x coordinate
	' NewY = new y coordinate

	'use int33h, ax = 4
	Regs.ax = 4
	Regs.cx = NewX * 2
	Regs.dx = NewY
	INTERRUPT &H33, Regs, Regs
END SUB

SUB neoMouseSetRange (MinX AS INTEGER, MinY AS INTEGER, MaxX AS INTEGER, MaxY AS INTEGER)
        'sets range box for the mouse
        ' MinX = left box x-coord
        ' MaxX = right box x-coord
        ' MinY = up box y-coord
        ' MaxY = down box y-coord

        'use int33h, ax = 7 and 8
        Regs.ax = 7
        Regs.cx = MinX * 2
        Regs.dx = MaxX * 2
        INTERRUPT &H33, Regs, Regs

        Regs.ax = 8
        Regs.cx = MinY
        Regs.dx = MaxY
        INTERRUPT &H33, Regs, Regs
END SUB

SUB neoMouseSetShape (NewShape AS STRING, HotX AS INTEGER, HotY AS INTEGER)
	'sets the mouse cursor shape for gfx modes
	' NewShape = a 64-byte bitmask containing a 32-byte screenmask and a 32-byte cursor mask
	' HotX = the x-coordinate on the cursor sprite which is the hotspot
	' HotY = the y-coordinate on the cursor sprite which is the hotspot

	'use int33h, ax = 9
	RegsX.ax = 9
	RegsX.bx = HotX * 2 - 16
	RegsX.cx = HotY * 2 - 16
        RegsX.es = VARSEG(NewShape)
        RegsX.dx = SADD(NewShape)
        INTERRUPTX &H33, RegsX, RegsX
END SUB

SUB neoMouseSetSensitivity (Xsens AS INTEGER, Ysens AS INTEGER)
        'sets the mouse sensitivity (number of mickeys per 8 pixels)
        ' Xsens = the number of horizontal mickeys per 8 pixels (default: 8)
        ' Ysens = the number of vertical mickeys per 8 pixels (default: 16)

        'use int33h, ax=Fh
        Regs.ax = &HF
	Regs.cx = Xsens
	Regs.dx = Ysens
	INTERRUPT &H33, Regs, Regs
END SUB
