'===========================================================================
' Subject: QB GUI LIBRARY                     Date: 05-10-97 (12:16)       
'  Author: Brian Bacon                        Code: QB, PDS                
'  Origin: kyberteknik@geocities.com        Packet: LIBRARY.ABC
'===========================================================================
'GOOIE - QB GUI Library
'  v1.0 by Brian Bacon
'
' Well I have to give a little credit to Douglas H. Lusher for making
' the GPrint routine, which was in Tika Carr's GUI library.  I dont know
' what happend to Tika's GUI library, so I decided to make my own with
' a few functions Tika didn't have.
'
' I haven't made any documentation yet but most of the function should
' be self explanitory, if you have any problems just e-mail me (my address
' is below).
'
' I am missing a good input routine, that will take a while because
' I want to have full mouse support and everything.  Also I'm sure I
' could think of a few more function to add in like menus and stuff.
' Also, the Button drawer should be able to justify text.
'
' NOTE - I haven't added any checking, but windows should have at least
' a hieght of 20 and width of like 6 (approx) but it shouldn't need to
' be that small...
' Also, buttons should have a hieght of 15 or more and the length
' depends on the text.
'
' If anyone has anything to contribute to this PLEASE send it to:
'    kyberteknik@geocities.com
' Oh, and check out my web page..
'    http://www.geocities.com/SiliconValley/Lakes/2213/
'
'$INCLUDE: 'QB.BI'
'Constants
CONST Bit0 = &H1
CONST Bit1 = &H2
CONST Bit2 = &H4
CONST Bit3 = &H8
CONST Bit4 = &H10
CONST Bit5 = &H20
CONST Bit6 = &H40
CONST Bit7 = &H80
'Mouse button Constants
CONST mLeft = 0
CONST mRight = 1
CONST mMiddle = 2

'Types
TYPE WindowParam
	      x AS INTEGER
	      y AS INTEGER
	   Wide AS INTEGER
	   Tall AS INTEGER
	 Header AS STRING * 79
	TextClr AS INTEGER
      BorderClr AS INTEGER
  BackgroundClr AS INTEGER
END TYPE

TYPE ButtonParam
	      x AS INTEGER
	      y AS INTEGER
	   Wide AS INTEGER
	   Tall AS INTEGER
  BackgroundClr AS INTEGER
	TextClr AS INTEGER
	   Text AS STRING * 79
END TYPE

TYPE CheckParam
	      x AS INTEGER
	      y AS INTEGER
	   size AS INTEGER
   BoxBorderClr AS INTEGER
      InsideClr AS INTEGER
	  value AS INTEGER
END TYPE

'Bit functions (mostly for internal use)
DECLARE SUB SetBit (byte, bit)
DECLARE FUNCTION TestBit% (byte, bit)
DECLARE SUB ToggleBit (byte, bit)
'Mouse functions
DECLARE FUNCTION ResetMouse% ()
DECLARE SUB ShowMouse ()
DECLARE SUB HideMouse ()
DECLARE SUB GetPosition (x, y)
DECLARE SUB GetButtonDown (Left, Middle, Right)
DECLARE SUB SetPosition (x, y)
DECLARE SUB GetButtonClick (button, counter, x, y)   ' button=mLeft,mRight,
DECLARE SUB GetButtonRelease (button, counter, x, y) ' or mMiddle
DECLARE SUB SetMouseLimits (minX, minY, maxX, maxY)
DECLARE SUB SetMouseSensitivity (xsens, ysens)
DECLARE SUB GetMouseSensitivity (xsens, ysens)
'Screen Functions
DECLARE SUB ClrScr (clr)
DECLARE SUB DrawWindow (WP AS WindowParam)
DECLARE SUB DrawButton (BP AS ButtonParam)
DECLARE SUB GPrint (a$, x%, y%, C%)
DECLARE SUB DrawCheckBox (CP AS CheckParam)

DIM SHARED Regs AS RegType, RegsX AS RegTypeX

SCREEN 12
IF ResetMouse% = 0 THEN
   PRINT "Could not initialize mouse driver."
   END
END IF

DIM W AS WindowParam
W.x = 20: W.y = 20
W.Tall = 200: W.Wide = 600
W.BorderClr = 12
W.BackgroundClr = 7
W.TextClr = 0
W.Header = "Test Window"
DrawWindow W

DIM B AS ButtonParam
B.x = 25: B.y = 80
B.Tall = 15: B.Wide = 65
B.BackgroundClr = 7
B.TextClr = 0
B.Text = "  Exit  "
DrawButton B

DIM C AS CheckParam
C.x = 25: C.y = 60
C.size = 10
C.BoxBorderClr = 0
C.InsideClr = 15
C.value = 1
DrawCheckBox C
GPrint "Check this box", 37, 59, 0

IF ResetMouse% THEN
   ShowMouse
   DO
     IF MouseTimer = 0 THEN
	GetButtonClick mLeft, counter, x, y
	MouseTimer = 8000    'adjust to your computer
     ELSE
	MouseTimer = MouseTimer - 1
     END IF
     IF counter > 0 THEN
	counter = 0
	IF x >= 25 AND x <= 35 AND y >= 60 AND y <= 70 THEN
	   IF C.value = 1 THEN C.value = 0 ELSE C.value = 1
	   HideMouse
	   DrawCheckBox C
	   ShowMouse
	END IF
	IF x >= 25 AND x <= 90 AND y >= 80 AND y <= 95 THEN
	   HideMouse
	   END
	END IF
     END IF
   LOOP
   HideMouse
ELSE
   GPrint "Cannot initialize mouse.", 30, 40, 0
END IF

SUB ClrScr (clr)
    PAINT (1, 1), clr
END SUB

SUB DrawButton (BP AS ButtonParam)
    IF BP.BackgroundClr = 7 THEN OBC = 8 ELSE OBC = 7
    LINE (BP.x, BP.y)-(BP.x + BP.Wide, BP.y), 15
    LINE (BP.x, BP.y)-(BP.x, BP.y + BP.Tall), 15
    LINE (BP.x + BP.Wide, BP.y)-(BP.x + BP.Wide, BP.y + BP.Tall), 15
    LINE (BP.x, BP.y + BP.Tall)-(BP.x + BP.Wide, BP.y + BP.Tall), 15
    PAINT (BP.x + 1, BP.y + 1), BP.BackgroundClr, 15
    LINE (BP.x + BP.Wide, BP.y)-(BP.x + BP.Wide, BP.y + BP.Tall), OBC
    LINE (BP.x, BP.y + BP.Tall)-(BP.x + BP.Wide, BP.y + BP.Tall), OBC
    GPrint BP.Text, BP.x + 2, BP.y + 1, BP.TextClr
END SUB

SUB DrawCheckBox (CP AS CheckParam)
    IF CP.InsideClr = 0 THEN cclr = 15 ELSE cclr = 0
    LINE (CP.x, CP.y)-(CP.x + CP.size, CP.y + CP.size), CP.BoxBorderClr, B
    LINE (CP.x + 1, CP.y + 1)-(CP.x + CP.size - 1, CP.y + CP.size - 1), CP.InsideClr, BF
    IF CP.value <> 0 THEN
       LINE (CP.x + 1, CP.y + 1)-(CP.x + CP.size - 1, CP.y + CP.size - 1), cclr
       LINE (CP.x + CP.size - 1, CP.y + 1)-(CP.x + 1, CP.y + CP.size - 1), cclr
    END IF
END SUB

SUB DrawWindow (WP AS WindowParam)
    IF WP.BorderClr = 7 THEN OBC = 8 ELSE OBC = 7
    IF WP.BackgroundClr = 7 THEN OBC = 8
    LINE (WP.x, WP.y)-(WP.x, WP.y + WP.Tall), 15
    LINE (WP.x, WP.y)-(WP.x + WP.Wide, WP.y), 15
    LINE (WP.x + WP.Wide, WP.y)-(WP.x + WP.Wide, WP.y + WP.Tall), OBC
    LINE (WP.x, WP.y + WP.Tall)-(WP.x + WP.Wide, WP.y + WP.Tall), OBC
    FOR I = 1 TO 2
	LINE (WP.x + I, WP.y + I)-(WP.x + I, WP.y + WP.Tall - I), WP.BorderClr
	LINE (WP.x + I, WP.y + I)-(WP.x + WP.Wide - I, WP.y + I), WP.BorderClr
	LINE (WP.x + WP.Wide - I, WP.y + I)-(WP.x + WP.Wide - I, WP.y + WP.Tall - I), WP.BorderClr
	LINE (WP.x + I, WP.y + WP.Tall - I)-(WP.x + WP.Wide - I, WP.y + WP.Tall - I), WP.BorderClr
    NEXT I
    LINE (WP.x + 3, WP.y + 15)-(WP.x + 3, WP.y + WP.Tall - 3), OBC
    LINE (WP.x + 3, WP.y + 15)-(WP.x + WP.Wide - 3, WP.y + 15), OBC
    LINE (WP.x + WP.Wide - 3, WP.y + 15)-(WP.x + WP.Wide - 3, WP.y + WP.Tall - 3), 15
    LINE (WP.x + 3, WP.y + WP.Tall - 3)-(WP.x + WP.Wide - 3, WP.y + WP.Tall - 3), 15
    FOR I = 3 TO 14
	LINE (WP.x + 3, WP.y + 3)-(WP.x + WP.Wide - 3, WP.y + 14), WP.BorderClr, BF
    NEXT I
    LINE (WP.x + 4, WP.y + 16)-(WP.x + WP.Wide - 4, WP.y + WP.Tall - 4), WP.BackgroundClr, BF
    GPrint WP.Header, WP.x + 4, WP.y + 1, WP.TextClr
END SUB

SUB GetButtonClick (button, counter, x, y)
    Regs.ax = 5
    Regs.bx = button
    INTERRUPT &H33, Regs, Regs
    counter = Regs.bx
    x = Regs.cx
    y = Regs.dx
END SUB

SUB GetButtonDown (Left, Middle, Right)
    Regs.ax = 3
    INTERRUPT &H33, Regs, Regs
    Left = 0: Middle = 0: Right = 0
    IF Regs.bx AND Bit0 THEN Left = 1
    IF Regs.bx AND Bit1 THEN Right = 1
    IF Regs.bx AND Bit2 THEN Middle = 1
END SUB

SUB GetButtonRelease (button, counter, x, y)
    Regs.ax = 6
    Regs.bx = button
    INTERRUPT &H33, Regs, Regs
    counter = Regs.bx
    x = Regs.cx
    y = Regs.dx
END SUB

SUB GetMouseSensitivity (xsens, ysens)
    Regs.ax = &H1B
    INTERRUPT &H33, Regs, Regs
    xsens = Regs.bx
    ysens = Regs.cx
END SUB

SUB GetPosition (x, y)
    Regs.ax = 3
    INTERRUPT &H33, Regs, Regs
    x = Regs.cx
    y = Regs.dx
END SUB

DEFINT A-Z
SUB GPrint (a$, x, y, C)
'What this routine does, is plot the points on the screen in any pixel
'location. Unlike the PRINT/LOCATE menthod, you can put text virtually
'anywhere on the screen by defining the pixel location. And, unlike
'the PRINT/LOCATE method, you can put text over anything on the screen
'and not mess up what was behind it. PRINT always prints things over
'background color #0.
'
'The font used is the VGA font that is in the BIOS. This routine reads
'the BIOS font table and replots it on the screen, thus replacing the
'PRINT statement, and adding features not available in PRINT.

 'this routine allows printing text at any pixel location
 '     in the graphics modes without disturbing the background
 'by Douglas H. Lusher, 06-08-1996

 ' 8 x 8 char box, CGA

 'CharSegment% = &HFFA6: CharOffset% = &HE
 'CharWid% = 8: CharHgt% = 8

 ' 8 x 14 char box, EGA
 'CharSegment% = &HC000: CharOffset% = &H4ED5
 'CharWid% = 8: CharHgt% = 14

 ' 8 x 16 char box, VGA
 RegsX.ax = &H1130
 RegsX.bx = &H600
 CALL INTERRUPTX(&H10, RegsX, RegsX)
 CharSegment% = RegsX.es: CharOffset% = RegsX.BP
 CharWid% = 8: CharHgt% = 16

 DEF SEG = CharSegment%
 XX% = x
 FOR Char% = 1 TO LEN(a$)
   Ptr% = CharHgt% * ASC(MID$(a$, Char%, 1)) + CharOffset%
   FOR Ln% = 0 TO CharHgt% - 1
     BitPattern& = PEEK(Ptr% + Ln%) * 256&
     LineFormat% = (BitPattern& - 32768) XOR -32768
     LINE (XX%, y + Ln%)-STEP(CharWid% - 1, 0), C, , LineFormat%
   NEXT
   XX% = XX% + CharWid%
 NEXT
 DEF SEG
END SUB

DEFSNG A-Z
SUB HideMouse
    Regs.ax = 2
    INTERRUPT &H33, Regs, Regs
END SUB

FUNCTION ResetMouse%
    Regs.ax = 0
    INTERRUPT &H33, Regs, Regs
    IF Regs.ax = &HFFFF THEN
       ResetMouse% = Regs.bx
    ELSE
       ResetMouse% = 0
    END IF
END FUNCTION

SUB SetBit (byte, bit)
    SELECT CASE bit
	   CASE 0
		byte = byte AND Bit0
	   CASE 1
		byte = byte AND Bit1
	   CASE 2
		byte = byte AND Bit2
	   CASE 3
		byte = byte AND Bit3
	   CASE 4
		byte = byte AND Bit4
	   CASE 5
		byte = byte AND Bit5
	   CASE 6
		byte = byte AND Bit6
	   CASE 7
		byte = byte AND Bit7
    END SELECT
END SUB

SUB SetMouseLimits (minX, minY, maxX, maxY)
    Regs.ax = 7
    Regs.cx = minX
    Regs.dx = maxX
    INTERRUPT &H33, Regs, Regs
    Regs.ax = 8
    Regs.cx = minY
    Regs.dx = maxY
    INTERRUPT &H33, Regs, Regs
END SUB

SUB SetMouseSensitivity (xsens, ysens)
    Regs.ax = &H1A
    Regs.bx = xsens
    Regs.cx = ysens
    INTERRUPT &H33, Regs, Regs
END SUB

SUB SetPosition (x, y)
    Regs.ax = 4
    Regs.cx = x
    Regs.dx = y
    INTERRUPT &H33, Regs, Regs
END SUB

SUB ShowMouse
    Regs.ax = 1
    INTERRUPT &H33, Regs, Regs
END SUB

FUNCTION TestBit% (byte, bit)
    SELECT CASE bit
	   CASE 0
		IF byte AND Bit0 THEN TestBit% = 1 ELSE TestBit% = 0
	   CASE 1
		IF byte AND Bit1 THEN TestBit% = 1 ELSE TestBit% = 0
	   CASE 2
		IF byte AND Bit2 THEN TestBit% = 1 ELSE TestBit% = 0
	   CASE 3
		IF byte AND Bit3 THEN TestBit% = 1 ELSE TestBit% = 0
	   CASE 4
		IF byte AND Bit4 THEN TestBit% = 1 ELSE TestBit% = 0
	   CASE 5
		IF byte AND Bit5 THEN TestBit% = 1 ELSE TestBit% = 0
	   CASE 6
		IF byte AND Bit6 THEN TestBit% = 1 ELSE TestBit% = 0
	   CASE 7
		IF byte AND Bit7 THEN TestBit% = 1 ELSE TestBit% = 0
    END SELECT
END FUNCTION

SUB ToggleBit (byte, bit)
    SELECT CASE bit
	   CASE 0
		byte = byte XOR Bit0
	   CASE 1
		byte = byte XOR Bit1
	   CASE 2
		byte = byte XOR Bit2
	   CASE 3
		byte = byte XOR Bit3
	   CASE 4
		byte = byte XOR Bit4
	   CASE 5
		byte = byte XOR Bit5
	   CASE 6
		byte = byte XOR Bit6
	   CASE 7
		byte = byte XOR Bit7
    END SELECT
END SUB
