'=========================================================================== ' Subject: VESA SVGA SCREEN ROUTINES Date: 03-10-96 (00:43) ' Author: Tyler Barnes Code: QB, PDS ' Origin: FidoNet QUIK_BAS Echo Packet: GRAPHICS.ABC '=========================================================================== ' QuickBasic High Resolution Screen Routines ' ' By D. Tyler Barnes ' ' Works(Hopefully) with any VESA compatible BIOS ' 'Intro '~~~~~ ' ' Ok,first of all,I'm not as heavily in to QuickBasic programming as 'I used to be,so I was a bit lazy writing this. I left a LOT of room for 'improvement. Second of all,when I WAS in to QuickBasic programming, graphics 'was not a specialty. I was more in to communications. The point I'm trying 'to make,is that there may be code in this thing that is extraneous,and 'there may be ways to do what this code is doing a lot faster... Infact,I 'KNOW there are ways to make it faster... I'm using the BIOS Write Pixel 'command in all the graphics commands. It would be much faster done with direct 'writes to video memory.. I'll leave the improvements up to you. 'Just do me a favour and send me your changes so that next time I post this, 'others will recieve these changes. I'll put your name on your code,so don't 'worry about me stealing your credit... 'Oh,another weird thing I've done,is I've used InterruptX almost everywhere, 'even in places where INTERRUPT would've worked. As far as I know they are 'identical anyhow,'cept INTERRUPTX can use more registers... but perhaps 'I'm wrong. Perhaps INTERRUPT is faster or something. Go ahead and change it. ' 'How to use '~~~~~~~~~~ ' '* Before doing anything,make sure you've loaded QuickBasic with the ' /L switch. '* Next detect whether or not the machine has VESA compatibility '* Set the screen mode '* Write the program here '* Use the CleanUp command '* End ' 'Commands: ' 'Border-This command is used when in text mode,and some graphic modes. ' It has one integer parameter. Depending what screen mode you're in, ' and what number you use,this will change the screen colour,the ' border,both,or neither. Just mess around with it ... ' Example Usage:Border 9 ' On my machine,the above will produce a light blue border when in ' ScreenMode 3(Basic's SCREEN 0) 'Box-This command will not work in any text modes.(Obviously) ' It has 5 parameters. 4 to define the box,and the last to define the ' colour of the box. ' Example Usage:Box 10,11,50,51,3 ' The above command would make a box with the left hand corner on point ' 10,11(X,Y) and the bottom right hand corner on 50,51. ' The last parameter is the colour and will have a different result ' depending on your screen mode. 'CleanUp-This command is used to clean up after the ScreenMode command. It ' should be run before you exit your program. Also,if you have ' allready run ScreenMode once,and you want to change to a new ' screen mode,you'll have to run this before doing so. Also,if you ' want to stop using these routines,and use BASIC's routines instead, ' and ScreenMode has allready been used in your program,you'll have ' to run this before using BASIC's SCREEN command. ' Example Usage:CleanUp 'CurVidMode-This function will return the current video mode. The number ' returned will not always correspond with the number used in the ' ScreenMode command,and will not always correspond with BASIC's ' SCREEN mode. If you want to see what the number returned means, ' look up AH=00,INT 10h in Ralf Brown's interrupt list. ' Example Usage:A%=CurVidMode% 'LowHigh-Crappy way of seperating two seperate bytes from a word. If you ' don't know what I'm talking about,don't worry about it. The only ' reason I have this in here at all,is because there are other ' routines in this source that depend on it. 'Pixel-This is like BASIC's PSET command. It plots one pixel on to the ' display. There are three parameters. Two for the X,Y coordinates of ' the dot,and one for the colour. ' Example Usage:Pixel 5,10,2 ' The above command would plot a pixel at 5,10(X,Y) with a colour ' value of 2. ' This command will not work in text modes. ' Pixel Positions start at 0,0. 'ScreenMode-This is used to switch between the screen modes. Please look ' up the CLEANUP command after reading this explanation. ' This command has one parameter;the screen mode. ' Example Usage:ScreenMode 3 ' The above command would switch the computer into 80x25x16 text ' mode.(80 columns,25 rows,16 colours) ' So that you don't have to remember all the numbers,I built in ' a bunch of constants to use for the more common modes. Of course, ' there are always modes I left out that may work,so experiment. ' If you find a mode that you want to use,try it on more than ' one machine to make sure that the mode you've selected is ' fairly compatible. Oh,and be careful. I've heard that with ' older equipment,you can actually fry your monitor by going into ' certain unsupported modes. 'VesaSupported-This function is used to detect whether or not the machine ' that the program is running on has VESA compatibility. ' Example Usage:IF VesaSupported THEN ' Ie2:IF NOT VesaSupported THEN DECLARE SUB Box (TopX%, TopY%, BottomX%, BottomY%, Colour%) DECLARE SUB Pixel (X%, Y%, Colour%) DECLARE SUB Border (Colour%) DECLARE FUNCTION Curvidmode% () DECLARE FUNCTION Readpixel% (Column%, Row%) DECLARE SUB Cleanup () DECLARE SUB Tlocate (Y%, X%) DECLARE SUB Tcolour (ForeGround%, BackGround%) DECLARE SUB ScreenMode (MODE%) DECLARE FUNCTION Vesasupported% () DECLARE SUB LowHigh (Register%, low%, High%) TYPE SVGA Sig AS STRING * 4 Version AS INTEGER OEMPtr AS LONG Capibilities AS STRING * 4 ListPtr AS LONG VidMem AS INTEGER Reserved AS STRING * 262 END TYPE '$INCLUDE: 'QB.BI' DIM SHARED Inregx AS RegTypeX, Outregx AS RegTypeX CONST GM640x400x256 = &H100, GM640x480x256 = &H101, GM800x600x16 = &H102 CONST GM800x600x256 = &H103, GM1024x768x16 = &H104, GM1024x768x256 = &H105 CONST TM80X25 = 3 CLS IF NOT Vesasupported THEN PRINT "Fatal Error: VESA was not detected." END IF 'Y=0 to 767 'X=0 to 1023 ScreenMode GM1024x768x256 Colour = -.5 FOR X% = 0 TO 1023 Colour = Colour + .5 IF INT(Colour) > 255 THEN Colour = -.5 FOR Y% = 0 TO 767 Pixel X%, Y%, INT(Colour) NEXT Y% IF LEN(INKEY$) > 0 THEN GOTO Here NEXT X% Here: Box 50, 50, 390, 590, 2 WHILE INKEY$ = "": WEND Cleanup DEFINT A-Z DEFSNG A-Z SUB Border (Colour%) DIM inreg AS RegType, outreg AS RegType 'In Text mode(3) you can only set the border colour. 'With some video modes this will also modify the background colour 'With other video modes,this may not work at all. IF Colour% > 255 THEN Colour% = 255 IF Colour% < 0 THEN Colour% = 0 inreg.AX = &HB00 inreg.BX = Colour% CALL INTERRUPT(&H10, inreg, outreg) END SUB DEFINT A-Z SUB Box (TopX, TopY, BottomX, BottomY, Colour%) FOR I% = TopX TO BottomX STEP 1 Pixel I%, TopY, Colour% Pixel I%, BottomY, Colour% NEXT I% FOR I% = TopY TO BottomY STEP 1 Pixel BottomX, I%, Colour% Pixel TopX, I%, Colour% NEXT I% END SUB SUB Cleanup SHARED StartingMode Inregx.AX = StartingMode CALL interruptx(&H10, Inregx, Outregx) END SUB DEFSNG A-Z FUNCTION Curvidmode% DEF SEG = &H40 Curvidmode% = PEEK(&H49) DEF SEG END FUNCTION DEFINT A-Z SUB GPrint (Text$) SHARED Col% Inregx.AX = &H300 CALL interruptx(&H10, Inregx, Inregx) Inregx.AX = &H1301 Inregx.BX = Col% Inregx.CX = LEN(Text$) Inregx.ES = VARSEG(Text$) Inregx.BP = SADD(Text$) CALL interruptx(&H10, Inregx, Outregx) END SUB DEFSNG A-Z SUB LowHigh (Register%, low%, High%) Full$ = HEX$(Register%) IF LEN(Full$) < 4 THEN WHILE LEN(Full$) < 4: Full$ = "0" + Full$: WEND END IF low% = VAL("&H" + RIGHT$(Full$, 2)) High% = VAL("&H" + LEFT$(Full$, 2)) END SUB SUB Makecircle (X%, Y%, Rad, Colour%) FOR I = 0 TO 6.4 STEP .005 Pixel INT(Rad * COS(I)) + X%, INT(Rad * SIN(I)) + Y%, Colour% NEXT I END SUB DEFINT A-Z SUB MakeLine (A, B, C, D, Colour%) U = C - A: v = D - B: Param = U: GOSUB Sign: D1X = Sign Param = v: GOSUB Sign: D1Y = Sign: Param = U: GOSUB Sign: D2X = Sign D2Y = 0: m = ABS(U): N = ABS(v) IF m <= N THEN D2X = 0: Param = v: GOSUB Sign: D2Y = Sign: m = ABS(v): N = ABS(U) END IF S% = m / 2 FOR I% = 0 TO m Pixel A, B, Colour%: S% = S% + N IF S% >= m THEN S% = S% - m: A = A + D1X: B = B + D1Y ELSE A = A + D2X: B = B + D2Y END IF NEXT I% EXIT SUB Sign: SELECT CASE Param CASE IS > 0: Sign = 1 CASE IS < 0: Sign = -1 CASE 0: Sign = 0 END SELECT RETURN END SUB DEFSNG A-Z SUB Pixel (X%, Y%, Colour%) DIM inreg AS RegType, outreg AS RegType C$ = HEX$(Colour%) LC% = LEN(C$) IF LC% < 2 THEN C$ = "0" + C$ IF LC% > 2 THEN C$ = LEFT$(C$, 2) inreg.AX = VAL("&HC" + C$) inreg.BX = &H0 inreg.DX = Y% inreg.CX = X% CALL INTERRUPT(&H10, inreg, outreg) END SUB DEFINT A-Z FUNCTION Readpixel (Column, Row) Inregx.AX = &HD00 Inregx.BX = 0 Inregx.CX = Column Inregx.DX = Row CALL interruptx(&H10, Inregx, Outregx) LowHigh Outregx.AX, RP, Junk Readpixel = RP END FUNCTION SUB ScreenMode (MODE%) SHARED StartingMode Inregx.AX = &HF00 CALL interruptx(&H10, Inregx, Outregx) LowHigh Outregx.AX, StartingMode, Columns Inregx.AX = &H4F03 CALL interruptx(&H10, Inregx, Outregx) LowHigh Outregx.AX, Support, Status IF Status <> 0 OR Support <> &H4F THEN ERROR (5) StartingVesaMode = Outregx.BX Inregx.AX = &H4F02 Inregx.BX = MODE% CALL interruptx(&H10, Inregx, Outregx) LowHigh Outregx.AX, Support, Status IF Support <> &H4F OR Status <> 0 THEN ERROR (5) Inregx.AX = &HF00 CALL interruptx(&H10, Inregx, Outregx) LowHigh Outregx.AX, EndResult, Columns Inregx.AX = &H4F02 Inregx.BX = StartingVesaMode CALL interruptx(&H10, Inregx, Outregx) IF Support <> &H4F OR Status <> 0 THEN ERROR (5) Inregx.AX = EndResult CALL interruptx(&H10, Inregx, Outregx) Tcolour 7, 0: Tlocate 1, 1 END SUB SUB Tcolour (ForeGround, BackGround) SHARED Col% T$ = HEX$(ForeGround): T2$ = HEX$(BackGround) IF LEN(T$) > 1 OR LEN(T2$) > 1 THEN ERROR (5) Col% = VAL("&H" + T2$ + T$) END SUB SUB Tlocate (Y, X) Y = Y - 1: X = X - 1 Y$ = HEX$(Y): X$ = HEX$(X) IF LEN(Y$) > 2 OR LEN(X$) > 2 THEN ERROR (5) IF LEN(Y$) < 2 THEN Y$ = "0" + Y$ IF LEN(X$) < 2 THEN X$ = "0" + X$ Inregx.AX = &H200 CurLoc% = VAL("&H" + Y$ + X$) Inregx.DX = CurLoc% CALL interruptx(&H10, Inregx, Outregx) X = X + 1: Y = Y + 1 END SUB FUNCTION Vesasupported DIM VInfoBuff AS SVGA Inregx.AX = &H4F00 Inregx.ES = VARSEG(VInfoBuff) Inregx.di = VARPTR(VInfoBuff) CALL interruptx(&H10, Inregx, Outregx) LowHigh Outregx.AX, Support, Status IF UCASE$(VInfoBuff.Sig) <> "VESA" OR Support <> &H4F OR Status <> 0 THEN Vesasupported = 0 ELSE Vesasupported = -1 END IF END FUNCTION 'Oh, that's it. And after all that commenting, I still neglected to say a few 'things. First of all, if you try to switch to a screen mode that isn't 'supported by your computer, most of the time it will give you an Illegal 'Function Call... Of course there are a few modes that won't be detected as 'invaid, they'll just freeze the machine or something not so nice. 'Also, In the VesaDetection function I'm using a TYPE instead of just a large 'set-length string... a large set length string would eliminate the TYPE stuff 'at the top of the file, but I put it the way i did incase someone wanted to 'use the info to add stuff. After all this time I've wasted talking abut this 'thing, I sure hope it works... .. I still haven't tested it on any machine 'but my own.L8r, 'D. Tyler Barnes