'=========================================================================== ' Subject: SNUGGLE OS ALPHA! Date: 07-25-99 (12:02) ' Author: Alexander Schrab Code: QB, QBasic, PDS ' Origin: santa@tir.com Packet: DEMOS.ABC '=========================================================================== 'SNUGGLE OS ALPHA! 'Copyright 1999 Alexander Schrab 'Thanks to: 'UPA for help and ideas 'Mark K. Kim for the Vmouse routine (Couldn't have done it without you!!) DECLARE FUNCTION CheckIfWinBtn% (who%) DECLARE FUNCTION CheckIfWinBttn% (who%) DECLARE SUB mouse.setgcr (data$) DECLARE SUB refresh () DECLARE SUB StartXYDrag (what%, who%) DECLARE FUNCTION CheckIfBorder% (what%, who%) DECLARE SUB StartXDrag (who%) DECLARE SUB WinPutTop (who%) DECLARE FUNCTION CheckIfWinArea% (who%) DECLARE FUNCTION CheckWinArea% (who%) DECLARE SUB WinMakeHighest (num%) DECLARE SUB WinUnDrw (who%) DECLARE SUB StartDrag (who%) DECLARE SUB mouse.getpos (x%, y%) DECLARE FUNCTION CheckIfTitle% (who%) DECLARE SUB NewWin (text$, x%, y%, w%, h%) DECLARE SUB DrwBtn (x%, y%, w%, h%, up%) DECLARE SUB GetStats (who%, text$, x%, y%, w%, h%, state%) DECLARE SUB WinDrwMng (who%) DECLARE SUB WinDrw (text$, x%, y%, w%, h%, state%, btnA%, btnB%, ctnC%) DECLARE SUB MaxButton (x%, y%) DECLARE SUB MinButton (x%, y%) DECLARE SUB QuitButton (x%, y%) DECLARE SUB cout (text$, sx%, sy%, colo%, Lengh%, break%) DECLARE SUB Init () DECLARE SUB CoutSetup () DECLARE FUNCTION StringFind% (Strng$, start%, what$) DECLARE SUB mouse.show () DECLARE SUB mouse.hide () DECLARE FUNCTION mouse.enable% () DECLARE FUNCTION mouse.getbutton% () DECLARE FUNCTION mouse.loadgcr$ (filename$) DECLARE FUNCTION mouse.loadTCR$ (filename$) DECLARE FUNCTION shift.getstate% () DECLARE SUB WinDrwBrd (x1%, y1%, x2%, y2%) DECLARE SUB WinDrwTtl (x1%, y1%, x2%, y2%) '*************** CONST LB = &H1 'constant for left button CONST RB = &H2 'constant for right button CONST CB = &H4 'constant for center button CONST DC = &H8 'constant for double click (reserved for next release) CONST shift = &H3 CONST CTRL = &H4 CONST ALT = &H8 '*************** CONST TtlHeight = 18 DIM SHARED font(100, 8, 16) AS INTEGER DIM SHARED font2(155, 8, 16) AS INTEGER DIM SHARED WNMax AS INTEGER WNMax = 10 DIM SHARED WNumber AS INTEGER DIM SHARED WGData(WNMax, 6) AS INTEGER DIM SHARED WTData(WNMax) AS STRING DIM SHARED WOrder(WNMax) AS INTEGER DIM SHARED move AS STRING move = mouse.loadgcr("move") DIM SHARED pointer AS STRING pointer = mouse.loadgcr("pointer") DIM SHARED vertical AS STRING vertical = mouse.loadgcr("vertical") DIM SHARED horizont AS STRING horizont = mouse.loadgcr("horizont") DIM SHARED diagonal AS STRING diagonal = mouse.loadgcr("diagonal") DIM SHARED SnuggleFolder AS STRING 'SnuggleFolder = "c:\develop\qbasic\snuggle\" 'CHDIR (SnuggleFolder) DEFINT A-Z SCREEN 12 enabled% = mouse.enable mouse.setgcr pointer mouse.show Init NewWin "Alfa", 90, 90, 300, 70 NewWin "Beta", 100, 100, 300, 70 NewWin "Ceta", 110, 110, 300, 70 refresh DO IF mouse.getbutton = LB THEN FOR Cyc = 1 TO WNumber CW = WOrder(Cyc) GetStats CW, crap$, wx, wy, ww, wh, wstate IF CheckIfWinBtn(CW) > 0 THEN LOCATE 1, 1 DO: LOOP WHILE mouse.getbutton = LB WinPutTop CW SELECT CASE CheckIfWinBtn(CW) CASE 1 CASE 2 mouse.hide WinUnDrw CW IF WGData(CW, 5) <> 2 THEN WGData(CW, 5) = 2 ELSE WGData(CW, 5) = 1 WinDrwMng CW mouse.show CASE 3 mouse.hide WinUnDrw CW IF WGData(CW, 5) <> 0 THEN WGData(CW, 5) = 0 ELSE WGData(CW, 5) = 1 WinDrwMng CW mouse.show CASE ELSE END SELECT EXIT FOR END IF IF CheckIfTitle(CW) THEN WinPutTop CW IF wstate <> 2 THEN StartDrag CW EXIT FOR END IF Ext = 0 FOR temp = 3 TO 1 STEP -1 IF CheckIfBorder(temp, CW) THEN WinPutTop CW IF wstate <> 2 THEN StartXYDrag temp, CW Ext = 1 END IF NEXT IF Ext = 1 THEN EXIT FOR IF CheckIfWinArea(CW) THEN DO: LOOP WHILE mouse.getbutton = LB WinPutTop CW EXIT FOR END IF NEXT END IF IF UCASE$(INKEY$) = "R" THEN refresh LOOP UNTIL UCASE$(INKEY$) = "Q" FUNCTION CheckIfBorder (what, who) GetStats who, crap$, wx, wy, ww, wh, wstate mouse.getpos x, y SELECT CASE what CASE 1 MinX = wx + ww - 3 MaxX = wx + ww MinY = wy + 19 MaxY = wy + wh CASE 2 MinX = wx MaxX = wx + ww MinY = wy + wh - 3 MaxY = wy + wh CASE 3 MinX = wx + ww - 3 MaxX = wx + ww MinY = wy + wh - 3 MaxY = wy + wh CASE ELSE END SELECT IF x >= MinX AND x <= MaxX AND y >= MinY AND y <= MaxY THEN CheckIfBorder = 1 END IF END FUNCTION FUNCTION CheckIfTitle (who) mouse.getpos mx, my GetStats who, crap$, x, y, w, h, state IF mx >= x AND mx <= x + w AND my >= y AND my <= y + TtlHeight THEN CheckIfTitle = 1 END FUNCTION FUNCTION CheckIfWinArea (who) mouse.getpos mx, my GetStats who, crap$, x, y, w, h, state IF state = 0 THEN CheckIfWinArea = 0 ELSE IF mx >= x AND mx <= x + w AND my >= y AND my <= y + h THEN CheckIfWinArea = 1 END IF END FUNCTION FUNCTION CheckIfWinBtn (who) mouse.getpos mx, my GetStats who, crap$, x, y, w, h, state FOR CW = 1 TO 3 MinX = x + w - TtlHeight * CW MinY = y + 3 MaxX = MinX + TtlHeight - 6 MaxY = MinY + TtlHeight - 6 IF mx >= MinX AND mx <= MaxX AND my >= MinY AND my <= MaxY THEN CheckIfWinBtn = CW EXIT FOR END IF NEXT END FUNCTION SUB cout (text$, sx, sy, colo, Lengh, break) DIM charlengh AS INTEGER charlengh = (Lengh - (Lengh MOD 8)) / 8 RowChar = 0 FOR Char = 1 TO LEN(text$) RowChar = RowChar + 1 IF RowChar > charlengh THEN IF break = 1 THEN sy = sy + 16: RowChar = 1 ELSE GOTO stopthis END IF num = ASC(MID$(text$, Char, 1)) FOR y = 1 TO 16 FOR x = 1 TO 8 IF num > 100 THEN col = font2(num - 100, x, y) ELSE col = font(num, x, y) IF col = 1 THEN PSET (sx + (x - 1) + (RowChar - 1) * 8, sy + y), colo NEXT NEXT NEXT stopthis: END SUB SUB CoutSetup COLOR 1 OUT &H3C8, 1 OUT &H3C9, 0 OUT &H3C9, 0 OUT &H3C9, 0 FOR a = 15 TO 255 LOCATE 1, 1 PRINT CHR$(a) FOR y = 0 TO 15 FOR x = 0 TO 7 pnt = POINT(x, y) IF pnt <> 0 THEN pnt = 1 IF a <= 100 THEN font(a, x + 1, y + 1) = pnt ELSE font2(a - 100, x + 1, y + 1) = pnt END IF NEXT NEXT NEXT END SUB SUB DrwBtn (x, y, w, h, up) IF up = 1 THEN Col1 = 1: Col2 = 3 ELSE Col2 = 1: Col1 = 3 LINE (x, y)-(x + w, y + h), 2, BF LINE (x, y)-(x, y + h - 1), Col2 LINE (x, y)-(x + h - 1, y), Col2 LINE (x + w, y + h)-(x + 1, y + h), Col1 LINE (x + w, y + h)-(x + w, y + 1), Col1 END SUB SUB GetStats (who, text$, x, y, w, h, state) text$ = WTData(who) x = WGData(who, 1) y = WGData(who, 2) IF WGData(who, 3) < 90 THEN WGData(who, 3) = 90 IF WGData(who, 4) < TtlHeight + 6 THEN WGData(who, 4) = TtlHeight + 6 w = WGData(who, 3) h = WGData(who, 4) state = WGData(who, 5) IF state = 0 THEN h = TtlHeight IF state = 1 THEN END IF IF state = 2 THEN w = 640: h = 480: x = 0: y = 0 END SUB SUB Init CoutSetup OUT &H3C8, 0 OUT &H3C9, 0 OUT &H3C9, 0 OUT &H3C9, 0 OUT &H3C8, 1 OUT &H3C9, 22 OUT &H3C9, 22 OUT &H3C9, 22 OUT &H3C8, 2 OUT &H3C9, 32 OUT &H3C9, 32 OUT &H3C9, 32 OUT &H3C8, 3 OUT &H3C9, 42 OUT &H3C9, 42 OUT &H3C9, 42 OUT &H3C8, 4 OUT &H3C9, 0 OUT &H3C9, 40 OUT &H3C9, 40 OUT &H3C8, 5 OUT &H3C9, 0 OUT &H3C9, 0 OUT &H3C9, 22 OUT &H3C8, 6 OUT &H3C9, 0 OUT &H3C9, 0 OUT &H3C9, 32 OUT &H3C8, 7 OUT &H3C9, 0 OUT &H3C9, 0 OUT &H3C9, 42 END SUB SUB MaxButton (x, y) LINE (x + 2, y + 4)-(x + 10, y + 4), 1 LINE (x + 3, y + 3)-(x + 9, y + 3), 6 LINE (x + 2, y + 2)-(x + 10, y + 10), 1, B LINE (x + 3, y + 5)-(x + 9, y + 9), 15, BF END SUB SUB MinButton (x, y) LINE (x + 3, y + 6)-(x + 9, y + 6), 6 LINE (x + 2, y + 5)-(x + 10, y + 7), 1, B END SUB 'Disable mouse. 'EXAMPLE: ' enabled% = mouse.enable 'enable mouse ' mouse.show 'show mouse ' a$ = INPUT$(1) 'pause ' mouse.disable 'disable mouse SUB mouse.disable SHARED mouse.exist AS INTEGER IF mouse.exist THEN mouse.hide mouse.exist = 0 END IF END SUB 'Enable mouse for usage. Must be run before any mouse functions (other than 'cursor-loading functions) or none will work. 'RETURN: ' -1 (&hFFFF) if mouse found, else 0. 'EXAMPLE: ' IF NOT mouse.enable THEN PRINT "No mouse" ELSE PRINT "Mouse found" FUNCTION mouse.enable% SHARED mouse.exist AS INTEGER 'store machine language data SHARED mouse.asm$ mouse.asm$ = "" mouse.asm$ = mouse.asm$ + CHR$(&H55) 'push bp mouse.asm$ = mouse.asm$ + CHR$(&H89) + CHR$(&HE5) 'mov bp, sp mouse.asm$ = mouse.asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HE) 'mov bx, [bp+0e] mouse.asm$ = mouse.asm$ + CHR$(&H8B) + CHR$(&H7) 'mov ax, [bx] mouse.asm$ = mouse.asm$ + CHR$(&H50) 'push ax mouse.asm$ = mouse.asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HC) 'mov bx, [bp+0c] mouse.asm$ = mouse.asm$ + CHR$(&H8B) + CHR$(&H7) 'mov cx, [ax] mouse.asm$ = mouse.asm$ + CHR$(&H50) 'push ax mouse.asm$ = mouse.asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HA) 'mov bx, [bp+0a] mouse.asm$ = mouse.asm$ + CHR$(&H8B) + CHR$(&HF) 'mov cx, [bx] mouse.asm$ = mouse.asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8) 'mov bx, [bp+08] mouse.asm$ = mouse.asm$ + CHR$(&H8B) + CHR$(&H17) 'mov dx, [bx] ' mouse.asm$ = mouse.asm$ + CHR$(&H1E) 'push ds ' mouse.asm$ = mouse.asm$ + CHR$(&H7) 'pop es mouse.asm$ = mouse.asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6) 'mov bx, [bp+06] mouse.asm$ = mouse.asm$ + CHR$(&H8E) + CHR$(&H7) 'mov es, [bx] mouse.asm$ = mouse.asm$ + CHR$(&H5B) 'pop bx mouse.asm$ = mouse.asm$ + CHR$(&H58) 'pop ax mouse.asm$ = mouse.asm$ + CHR$(&HCD) + CHR$(&H33) 'int 33h mouse.asm$ = mouse.asm$ + CHR$(&H53) 'push bx mouse.asm$ = mouse.asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HE) 'mov bx, [bp+0e] mouse.asm$ = mouse.asm$ + CHR$(&H89) + CHR$(&H7) 'mov [bx], ax mouse.asm$ = mouse.asm$ + CHR$(&H58) 'pop ax mouse.asm$ = mouse.asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HC) 'mov bx, [bp+0c] mouse.asm$ = mouse.asm$ + CHR$(&H89) + CHR$(&H7) 'mov [bx], ax mouse.asm$ = mouse.asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&HA) 'mov bx, [bp+0a] mouse.asm$ = mouse.asm$ + CHR$(&H89) + CHR$(&HF) 'mov [bx], cx mouse.asm$ = mouse.asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8) 'mov bx, [bp+08] mouse.asm$ = mouse.asm$ + CHR$(&H89) + CHR$(&H17) 'mov [bx], dx mouse.asm$ = mouse.asm$ + CHR$(&H5D) 'pop bp mouse.asm$ = mouse.asm$ + CHR$(&HCA) + CHR$(&H12) + CHR$(&H0) 'retf 12 'initialize and check mouse existance mouse.asmseg% = VARSEG(mouse.asm$) mouse.asmoff% = SADD(mouse.asm$) ax% = 0 DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, ax%, 0, 0, 0, 0, mouse.asmoff%) DEF SEG mouse.exist = ax% mouse.enable = mouse.exist END FUNCTION 'Gets mouse status (coordinates and button status.) 'COMMENT: '* Coordinates are in pixels, even if the screen is in text mode. 'INPUT: '* x% = integer variable to store x coordinate '* y% = integer variable to store y coordinate '* buttons% = integer variable to store buttons status where: ' * buttons% becomes LB if left button is pressed ' * buttons% becomes RB if right button is pressed ' * buttons% becomes CB if center buttons is pressed ' * or combination (left button and right button makes buttons% = LB + RB) ' including double clicks (ie - LB + DC). '* LB, RB, and CB are mouse constants found in the main module. 'EXAMPLE: ' CLS ' enabled% = mouse.enable ' mouse.show ' DO ' mouse.get x%, y%, buttons% ' LOCATE 1, 1: PRINT USING "#### #### ####"; x%; y%; buttons% ' LOOP WHILE INKEY$ = "" ' mouse.disable SUB mouse.get (x%, y%, buttons%) SHARED mouse.exist AS INTEGER SHARED mouse.asm$ mouse.asmseg% = VARSEG(mouse.asm$) mouse.asmoff% = SADD(mouse.asm$) IF mouse.exist THEN DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, &H3, bx%, x%, y%, 0, mouse.asmoff%) DEF SEG END IF buttons% = 0 IF bx% AND &H1 THEN buttons% = buttons% OR LB IF bx% AND &H2 THEN buttons% = buttons% OR RB IF bx% AND &H4 THEN buttons% = buttons% OR CB END SUB 'Gets the status of mouse buttons. 'COMMENT: '* Using mouse.get() function is recommended instead when using both ' mouse.getbutton() and mouse.getpos() functions. 'RETURN: '* An integer value: ' * LB for Left Button ' * RB for Right Button ' * CB for Center Button (if any) ' * or combination (left button and right button makes buttons% = LB + RB) ' including double clicks (ie - LB + DC). '* LB, RB, and CB are mouse constants found in the main module. 'EXAMPLE: ' CLS ' enabled% = mouse.enable ' mouse.show ' DO ' buttons% = mouse.getbutton ' LOCATE 1, 1: PRINT USING "####"; buttons% ' LOOP WHILE INKEY$ = "" ' mouse.disable FUNCTION mouse.getbutton% SHARED mouse.exist AS INTEGER SHARED mouse.asm$ mouse.asmseg% = VARSEG(mouse.asm$) mouse.asmoff% = SADD(mouse.asm$) IF mouse.exist THEN DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, &H3, bx%, 0, 0, 0, mouse.asmoff%) DEF SEG END IF ret% = 0 IF bx% AND &H1 THEN ret% = ret% OR LB IF bx% AND &H2 THEN ret% = ret% OR RB IF bx% AND &H4 THEN ret% = ret% OR CB mouse.getbutton% = ret% END FUNCTION 'Gets the last coordinate where a mouse button was pressed 'COMMENT: '* Coordinates are in pixels, even if the screen is in text mode. 'INPUT: '* mouse.constant% is a mouse constant of LB (left button), RB (right ' button), or CB (center button) for button press check. No combination ' allowed. Any values other than LB, RB, and CB will default to LB. '* x% and y% are the variables to store x and y corrdinates where the mouse ' button was pressed. 'EXAMPLE: ' CLS ' enabled% = mouse.enable ' mouse.show ' DO ' mouse.getlastdown LB, x%, y% ' LOCATE 1, 1: PRINT USING "#### ####"; x%; y% ' LOOP WHILE INKEY$ = "" ' mouse.disable SUB mouse.getlastdown (mouse.constant%, x%, y%) SHARED mouse.exist AS INTEGER SHARED mouse.asm$ mouse.asmseg% = VARSEG(mouse.asm$) mouse.asmoff% = SADD(mouse.asm$) IF mouse.exist THEN SELECT CASE mouse.constant% CASE LB: Button% = 0 CASE RB: Button% = 1 CASE CB: Button% = 2 CASE ELSE: Button% = 0 END SELECT DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, &H5, Button%, cx%, dx%, 0, mouse.asmoff%) DEF SEG x% = cx% y% = dx% END IF END SUB 'Gets the last coordinate where a mouse button was released 'COMMENT: '* Coordinates are in pixels, even if the screen is in text mode. 'INPUT: '* mouse.constant% is a mouse constant of LB (left button), RB (right ' button), or CB (center button) for button release check. No combination ' allowed. '* x% and y% are the variables to store x and y corrdinates where the mouse ' button was released. 'EXAMPLE: ' CLS ' enabled% = mouse.enable ' mouse.show ' DO ' mouse.getlastup LB, x%, y% ' LOCATE 1, 1: PRINT USING "#### ####"; x%; y% ' LOOP WHILE INKEY$ = "" ' mouse.disable SUB mouse.getlastup (mouse.constant%, x%, y%) SHARED mouse.exist AS INTEGER SHARED mouse.asm$ mouse.asmseg% = VARSEG(mouse.asm$) mouse.asmoff% = SADD(mouse.asm$) IF mouse.exist THEN SELECT CASE mouse.constant% CASE LB: Button% = 0 CASE RB: Button% = 1 CASE CB: Button% = 2 CASE ELSE: Button% = 0 END SELECT DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, &H6, Button%, cx%, dx%, 0, mouse.asmoff%) DEF SEG x% = cx% y% = dx% END IF END SUB 'Gets the movement of the mouse since last call 'COMMENT: '* Coordinates are in pixels, even if the screen is in text mode. 'INPUT: '* x% and y% are variables to store the horizontal and vertical movements, ' respectively. '* Right and Down are positives, Left and Up are negatives 'EXAMPLE: ' CLS ' enabled% = mouse.enable ' mouse.show ' DO ' mouse.getmovement x%, y% ' LOCATE 1, 1: PRINT USING "#### ####"; x%; y% ' SLEEP 1 ' LOOP WHILE INKEY$ = "" ' mouse.disable SUB mouse.getmovement (x%, y%) SHARED mouse.exist AS INTEGER SHARED mouse.asm$ mouse.asmseg% = VARSEG(mouse.asm$) mouse.asmoff% = SADD(mouse.asm$) IF mouse.exist THEN DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, &HB, 0, cx%, dx%, 0, mouse.asmoff%) DEF SEG x% = cx% y% = dx% END IF END SUB 'Gets mouse coordinates. 'COMMENT: '* Coordinates are in pixels, even if the screen is in text mode. 'COMMENT: '* Using mouse.get() function is recommended instead when using both ' mouse.getpos() and mouse.getbutton() functions. 'INPUT: '* x% = integer variable to store x coordinate '* y% = integer variable to store y coordinate 'EXAMPLE: ' CLS ' enabled% = mouse.enable ' mouse.show ' DO ' mouse.getpos x%, y% ' LOCATE 1, 1: PRINT USING "#### ####"; x%; y% ' LOOP WHILE INKEY$ = "" ' mouse.disable SUB mouse.getpos (x%, y%) SHARED mouse.exist AS INTEGER SHARED mouse.asm$ mouse.asmseg% = VARSEG(mouse.asm$) mouse.asmoff% = SADD(mouse.asm$) IF mouse.exist THEN DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, &H3, 0, x%, y%, 0, mouse.asmoff%) DEF SEG END IF END SUB 'Hides mouse cursor 'EXAMPLE: ' enabled% = mouse.enable 'enable mouse ' mouse.show 'show mouse ' a$ = INPUT$(1) 'pause ' mouse.hide 'hide mouse ' a$ = INPUT$(1) 'pause ' mouse.disable 'disable mouse SUB mouse.hide SHARED mouse.exist AS INTEGER SHARED mouse.asm$ mouse.asmseg% = VARSEG(mouse.asm$) mouse.asmoff% = SADD(mouse.asm$) SHARED mouse.visible AS INTEGER IF mouse.exist AND mouse.visible THEN DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, &H2, 0, 0, 0, 0, mouse.asmoff%) DEF SEG mouse.visible = 0 END IF END SUB 'Loads the graphics cursor 'COMMENT: '* Requies MS Mouse driver version 3.0 or compatible 'INPUT: '* filename$ is the file name to input the graphics cursor's data from. '* If filename$ has no extention, it defaults to .GCR (Graphics CuRsor) ' extention. 'RETURN: '* Returns the graphics cursor data in the string form. 'EXAMPLE: ' SCREEN 9 'requires EGA or better ' enabled% = mouse.enable ' mouse.show ' data$ = mouse.loadGCR$("cursor.gcr") ' mouse.setGCR data$ FUNCTION mouse.loadgcr$ (filename$) IF INSTR(filename$, ".") = 0 THEN filename$ = filename$ + ".GCR" filenumber% = FREEFILE OPEN filename$ FOR BINARY AS filenumber% strn$ = SPACE$(3) GET #filenumber%, 1, strn$ IF strn$ = "GCR" THEN strn$ = SPACE$(69) GET #filenumber%, 1, strn$ ELSE strn$ = "" END IF CLOSE filenumber% mouse.loadgcr$ = strn$ END FUNCTION 'Loads the text cursor 'COMMENT: '* Requies MS Mouse driver version 3.0 or compatible 'INPUT: '* filename$ is the file name to input the graphics cursor's data from. '* If filename$ has no extention, it defaults to .TCR (Text CuRsor) extention. 'RETURN: '* Returns the text cursor data in the string form. 'EXAMPLE: ' enabled% = mouse.enable ' mouse.show ' data$ = mouse.loadTCR$("cursor.tcr") ' mouse.setTCR data$ FUNCTION mouse.loadTCR$ (filename$) IF INSTR(filename$, ".") = 0 THEN filename$ = filename$ + ".TCR" filenumber% = FREEFILE OPEN filename$ FOR BINARY AS filenumber% strn$ = SPACE$(3) GET #filenumber%, 1, strn$ IF strn$ = "TCR" THEN strn$ = SPACE$(8) GET #filenumber%, 1, strn$ ELSE strn$ = "" END IF CLOSE filenumber% mouse.loadTCR$ = strn$ END FUNCTION 'Changes the graphics cursor 'COMMENT: '* Requies MS Mouse driver version 3.0 or compatible 'INPUT: '* data$ is the graphics cursor data gotten from a file using the function ' mouse.loadGCR(). 'EXAMPLE: ' SCREEN 9 'requires EGA or better ' enabled% = mouse.enable ' mouse.show ' data$ = mouse.loadGCR$("cursor.gcr") ' mouse.setGCR data$ SUB mouse.setgcr (data$) SHARED mouse.exist AS INTEGER SHARED mouse.asm$ mouse.asmseg% = VARSEG(mouse.asm$) mouse.asmoff% = SADD(mouse.asm$) IF mouse.exist AND LEN(data$) = 69 AND LEFT$(data$, 3) = "GCR" THEN 'get hotx value hotxstr$ = MID$(data$, 68, 1) DEF SEG = VARSEG(hotxstr$) bx% = PEEK(SADD(hotxstr$)) DEF SEG 'get hoty value hotystr$ = MID$(data$, 69, 1) DEF SEG = VARSEG(hotystr$) cx% = PEEK(SADD(hotystr$)) DEF SEG 'get image shape values dx% = SADD(data$) + 3 es% = VARSEG(data$) 'execute DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, &H9, bx%, cx%, dx%, es%, mouse.asmoff%) DEF SEG END IF END SUB 'Sets a "boxed" area for the mouse to move around. It cannot go beyond. 'COMMENT: '* Coordinates are in pixels, even if the screen is in text mode. 'INPUT: '* (x1%, y1%) is the top-left coordinate of the box. '* (x2%, y2%) is the bottom-right coordinate of the box. 'EXAMPLE: ' enabled% = mouse.enable ' mouse.show ' mouse.setlimit 50, 50, 300, 100 ' a$ = INPUT$(1) 'wait for a key ' mouse.disable SUB mouse.setlimit (x1%, y1%, x2%, y2%) SHARED mouse.exist AS INTEGER SHARED mouse.asm$ mouse.asmseg% = VARSEG(mouse.asm$) mouse.asmoff% = SADD(mouse.asm$) IF mouse.exist THEN cx% = x1% dx% = x2% DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, &H7, 0, cx%, dx%, 0, mouse.asmoff%) DEF SEG cx% = y1% dx% = y2% DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, &H8, 0, cx%, dx%, 0, mouse.asmoff%) DEF SEG END IF END SUB 'Moves the mouse position to (x%, y%) 'COMMENT: '* Coordinates are in pixels, even if the screen is in text mode. 'NOTES: '* The inputted values, x% and y%, must be in "pixels", not in "blocks", even ' in text mode. 'EXAMPLE: ' enabled% = mouse.enable ' mouse.show ' DO ' mouse.setpos 100, 100 ' SLEEP 1 ' LOOP WHILE INKEY$ = "" ' mouse.disable SUB mouse.setpos (x%, y%) SHARED mouse.exist AS INTEGER SHARED mouse.asm$ mouse.asmseg% = VARSEG(mouse.asm$) mouse.asmoff% = SADD(mouse.asm$) IF mouse.exist THEN cx% = x% dx% = y% DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, &H4, 0, cx%, dx%, 0, mouse.asmoff%) DEF SEG END IF END SUB 'Changes the mouse speed 'COMMENT: '* This interrupt service actually sets the ratio between mickey (the small- ' est movement the mouse can detect) and the pixels. This function does ' some calculations to make it simulate a speed setting interrupt service. ' There is aactually a speed setting interrupt service, but it is available ' to MS Mouse Driver version 6.0 and compatibles so I didn't want to do ' that. All the functions in this QBASIC functions are MS Mouse Driver ver- ' sion 1.0 and compatible with the exception of graphics cursor setting ' functions and text cursor setting functions. 'INPUT: '* x% is the new horizontal mouse speed '* y% is the new vertical mouse speed '* The minimum value is -32,768 (go backwards) and the maximum value is ' 32,767, same as the minimum and the maximum value limit of integers. 'EXAMPLE: ' enabled% = mouse.enable ' mouse.show ' mouse.setspeed &H7FFF, &H7FFF ' a$ = INPUT$(1) 'wait for a key ' mouse.disable SUB mouse.setspeed (x%, y%) SHARED mouse.exist AS INTEGER SHARED mouse.asm$ mouse.asmseg% = VARSEG(mouse.asm$) mouse.asmoff% = SADD(mouse.asm$) IF mouse.exist THEN DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, &HF, 0, (x% XOR &H7FFF), (y% XOR &H7FFF), 0, mouse.asmoff%) DEF SEG END IF END SUB 'Changes the text cursor 'COMMENT: '* Requies MS Mouse driver version 3.0 or compatible 'INPUT: '* data$ is the text cursor data gotten from a file using the function ' mouse.loadTCR(). 'EXAMPLE: ' enabled% = mouse.enable ' mouse.show ' data$ = mouse.loadTCR$("cursor.tcr") ' mouse.setTCR data$ SUB mouse.setTCR (data$) SHARED mouse.exist AS INTEGER SHARED mouse.asm$ IF NOT (mouse.exist AND LEN(data$) = 8 AND LEFT$(data$, 3) = "TCR") THEN EXIT SUB 'get cursor type value cursortype$ = MID$(data$, 4, 1) DEF SEG = VARSEG(cursortype$) bx% = PEEK(SADD(cursortype$)) DEF SEG 'get arg1 value arg1h$ = MID$(data$, 5, 1) DEF SEG = VARSEG(arg1h$) argh% = PEEK(SADD(arg1h$)) DEF SEG arg1l$ = MID$(data$, 6, 1) DEF SEG = VARSEG(arg1l$) argl% = PEEK(SADD(arg1l$)) DEF SEG cx% = (argh% AND &H7F) * &H100 + argl% IF argh% AND &H80 THEN cx% = cx% OR &H8000 'get arg2 value arg2h$ = MID$(data$, 7, 1) DEF SEG = VARSEG(arg2h$) argh% = PEEK(SADD(arg2h$)) DEF SEG arg2l$ = MID$(data$, 8, 1) DEF SEG = VARSEG(arg2l$) argl% = PEEK(SADD(arg2l$)) DEF SEG dx% = (argh% AND &H7F) * &H100 + argl% IF argh% AND &H80 THEN dx% = dx% OR &H8000 'execute mouse.asmseg% = VARSEG(mouse.asm$) mouse.asmoff% = SADD(mouse.asm$) DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, &HA, bx%, cx%, dx%, 0, mouse.asmoff%) DEF SEG END SUB 'Shows the mouse. Must have been enabled first. 'EXAMPLE: ' enabled% = mouse.enable 'enable mouse ' mouse.show 'show mouse ' a$ = INPUT$(1) 'pause ' mouse.disable 'disable mouse SUB mouse.show SHARED mouse.exist AS INTEGER SHARED mouse.asm$ mouse.asmseg% = VARSEG(mouse.asm$) mouse.asmoff% = SADD(mouse.asm$) SHARED mouse.visible AS INTEGER IF mouse.exist AND NOT mouse.visible THEN DEF SEG = mouse.asmseg% CALL absolute(dummy%, dummy%, dummy%, dummy%, &H1, 0, 0, 0, 0, mouse.asmoff%) DEF SEG mouse.visible = 1 END IF END SUB SUB NewWin (text$, x, y, w, h) WNumber = WNumber + 1 WGData(WNumber, 1) = x WGData(WNumber, 2) = y WGData(WNumber, 3) = w WGData(WNumber, 4) = h WGData(WNumber, 5) = 1 WGData(WNumber, 0) = 0 WTData(WNumber) = text$ WOrder(WNumber) = WNumber WinMakeHighest WNumber END SUB SUB QuitButton (x, y) LINE (x + 5, y + 2)-(x + 7, y + 6), 1, B LINE (x + 5, y + 8)-(x + 7, y + 10), 1, B LINE (x + 6, y + 3)-(x + 6, y + 5), 6 PSET (x + 6, y + 9), 6 END SUB SUB refresh mouse.hide CLS LINE (0, 0)-(640, 480), 4, BF FOR Cyc = WNumber TO 1 STEP -1 CW = WOrder(Cyc) WinDrwMng CW NEXT mouse.show END SUB 'Gets shift state. 'RETURN: '* 0 if no shift key pressed '* ALT if Alt key pressed '* CTRL if Ctrl key pressed '* SHIFT if Shift key pressed '* These may be in combination. For example, if Ctrl-Alt is pressed, then ' return is CTRL + ALT. '* ALT, CTRL, and SHIFT are shift constants defined in the main module. 'EXAMPLE: ' CLS ' enabled% = mouse.enable ' mouse.show ' DO ' mouse.get x%, y%, buttons% ' shiftstate% = shift.getstate% ' IF buttons% THEN ' LOCATE 1, 1: PRINT SPACE$(79); : LOCATE 1, 1 ' SELECT CASE shiftstate% ' CASE 0: PRINT "Mouse button was pressed without any shift keys." ' CASE ALT: PRINT "Mouse button and Alt key pressed." ' CASE CTRL: PRINT "Mouse button and Ctrl key pressed." ' CASE SHIFT: PRINT "Mouse button and Shift key pressed." ' END SELECT ' END IF ' LOOP WHILE INKEY$ = "" FUNCTION shift.getstate% DEF SEG = 0 state% = PEEK(&H417) AND &HF DEF SEG IF (state% AND &H3) THEN state% = (state% OR &H3) shift.getstate% = state% END FUNCTION SUB StartDrag (who) mouse.setgcr move mouse.getpos ox, oy x = ox: y = oy GetStats who, crap$, wx, wy, ww, wh, wstate DO lx = x: ly = y mouse.getpos x, y IF lx = x AND ly = y THEN ELSE mouse.hide WinUnDrw (who) WGData(who, 1) = wx + (x - ox) WGData(who, 2) = wy + (y - oy) WinDrwMng (who) ELSE mouse.show END IF LOOP UNTIL mouse.getbutton <> LB mouse.hide mouse.setgcr pointer mouse.show END SUB SUB StartXYDrag (what, who) mouse.hide IF what = 1 THEN mouse.setgcr horizont IF what = 2 THEN mouse.setgcr vertical IF what = 3 THEN mouse.setgcr diagonal mouse.getpos ox, oy x = ox: y = oy GetStats who, crap$, wx, wy, ww, wh, wstate DO lx = x: ly = y mouse.getpos x, y IF lx = x AND ly = y THEN ELSE mouse.hide WinUnDrw (who) IF what <> 2 THEN WGData(who, 3) = ww + (x - ox) IF what <> 1 THEN WGData(who, 4) = wh + (y - oy) WinDrwMng (who) mouse.show END IF LOOP UNTIL mouse.getbutton <> LB mouse.hide mouse.setgcr pointer mouse.show END SUB FUNCTION StringFind (Strng$, start, what$) FOR a = start TO LEN(Strng$) + 1 IF a <= LEN(Strng$) THEN IF MID$(Strng$, a, 1) = LTRIM$(RTRIM$(what$)) THEN EXIT FOR END IF END IF NEXT StringFind = a END FUNCTION SUB WinDrw (text$, x, y, w, h, state, btnA, btnB, btnC) WinDrwTtl x, y, x + w, y + TtlHeight Lengh = w - TtlHeight * 3 - 2 - 5 CharsVis = (Lengh - (Lenght MOD 8)) / 8 print$ = MID$(text$, 1, CharsVis) IF LEN(text$) <> LEN(print$) AND LEN(print$) >= 3 THEN MID$(print$, LEN(print$) - 2, 3) = "..." cout print$, x + 5, y, 2, Lengh + 8, 0 DrwBtn x + w - TtlHeight * 3, y + 3, TtlHeight - 6, TtlHeight - 6, btnA DrwBtn x + w - TtlHeight * 2, y + 3, TtlHeight - 6, TtlHeight - 6, btnB DrwBtn x + w - TtlHeight * 1, y + 3, TtlHeight - 6, TtlHeight - 6, btnC MinButton x + w - TtlHeight * 3, y + 3 MaxButton x + w - TtlHeight * 2, y + 3 QuitButton x + w - TtlHeight * 1, y + 3 IF state <> 0 THEN WinDrwBrd x, y + TtlHeight + 1, x + w, y + h END SUB SUB WinDrwBrd (x1, y1, x2, y2) LINE (x1, y1)-(x2, y2), 15, BF LINE (x1, y1)-(x2, y2), 3, B LINE (x1 + 1, y1 + 1)-(x2 - 1, y2 - 1), 2, B LINE (x1 + 2, y1 + 2)-(x2 - 2, y2 - 2), 1, B LINE (x2 - 2, y2 - 2)-(x2 - 2, y1 + 3), 3 LINE (x2 - 2, y2 - 2)-(x1 + 3, y2 - 2), 3 LINE (x2, y2)-(x2, y1 + 1), 1 LINE (x2, y2)-(x1 + 1, y2), 1 LINE (x2, y1)-(x2 - 2, y1 + 2), 2 LINE (x1, y2)-(x1 + 2, y2 - 2), 2 END SUB SUB WinDrwMng (who) GetStats who, text$, x, y, w, h, state WinDrw text$, x, y, w, h, state, 1, 1, 1 END SUB SUB WinDrwTtl (x1, y1, x2, y2) LINE (x1, y1)-(x2, y2), 6, BF LINE (x1, y1)-(x2 - 1, y1), 7 LINE (x1, y1)-(x1, y2 - 1), 7 LINE (x2, y2)-(x1 + 1, y2), 5 LINE (x2, y2)-(x2, y1 + 1), 5 END SUB SUB WinMakeHighest (num) FOR a = 1 TO WNumber IF WOrder(a) = num THEN where = a END IF NEXT FOR a = where - 1 TO 1 STEP -1 WOrder(a + 1) = WOrder(a) NEXT WOrder(1) = num END SUB SUB WinPutTop (who) mouse.hide IF WOrder(1) <> who THEN WinMakeHighest who WinUnDrw who WinDrwMng who END IF mouse.show END SUB SUB WinUnDrw (who) GetStats who, crap$, x, y, w, h, state IF state <> 0 THEN height = h ELSE height = TtlHeight LINE (x, y)-(x + w, y + height), 4, BF DIM ReDrawn(WNumber) AS INTEGER ReDrawn(who) = 1 FOR Cyc = WNumber TO 1 STEP -1 CW = WOrder(Cyc) IF CW <> who THEN GetStats CW, crap$, x, y, w, h, state FOR TCW = 1 TO WNumber GetStats TCW, crap$, tx, ty, tw, th, tstate IF x + w >= tx AND x <= tx + tw AND y + h >= ty AND y <= ty + th AND TCW <> CW AND ReDrawn(TCW) THEN ReDrawn(CW) = 1 WinDrwMng CW EXIT FOR END IF NEXT END IF NEXT END SUB