Issue #4
Saturday, October 6th, 2001

Programming SVGA graphics is a good thing to know how to do. SVGA of course allows you to use resolutions of up to 1600x1200 with 32-bit colour depth. With it you can make your games look really really colourful and I find it easier to implement such things as translucency. Of course when SVGA was first introduced, many different video cards started coming out to supoort SVGA modes. The problem with this was that there was no standard way to communicate with the video cards; each one had it's own way of interfacing with it. This was a major problem. A program usign SVGA would have to contain a whole slew of routines to do the same thing on different video cards. So VESA was introduced.

VESA stands for Video Electronics Standards Association. It was made to introduce a standard method to program SVGA. Now instead of programming different routines for different video cards, you should simply use the VGA BIOS extension which handles the work of interfacing with your video card.

Before you get to far into be aware that while you can do SVGA programming in straight QB it won't be fast enough for games and such. If you want speed you should program your graphics routines in assembly.

So lets start. Before using SVGA you must be sure it exists on the computer. We can do this by calling VESA function &H4F00 (Note that all VESA functions are prefaced with &H4F. So &H4F00 is function 0). We can get info on the SVGA card installed by creating a TYPE and passing the segment and offset of it to the function as well.

 VESASignature AS STRING * 4 
 Capabilities AS STRING * 4 
 VideoModePTR AS LONG 
 TotalMemory AS INTEGER 
 Reserved AS STRING * 236 

VESASignature always equals 'VESA' if there is a VESA card. VESAVersion returns the VESA version. OEMStringPTR is a pointer to a string that can be used to identify the different things. Capabilities describes the capabilities of the video card. VideoModePTR is a pointer to a list of video cards supported screen modes. TotalMemory the total memory which the video card contains in 64 kb blocks. Reserved is reserved for future use heheh.

So to detect a VESA compatable card we could do this in QB:

DIM regs AS regTypeX
regs.AX = &H4F00
regs.ES = VARSEG(VGAInfo) 
regs.DI = VARPTR(VGAInfo) 
CALL InterruptX (&H10, regs, regs)
IF regs.AX = &H4F THEN
 PRINT "VESA found."
 PRINT "VESA not found."

As you can see if a VESA card is found AX will contain &H4F. At the beginning of your program you would need a '$INCLUDE: 'QB.BI' and you would need to load in the QB.QLB library since we're making use of InterruptX.

So that's pretty simple. Now what about plotting a pixel? Well first we need to set a screen mode.

VESA 	Mode Resolution          Colors 
100h 	640x400		 256 
101h 	640x480		 256 
102h 	800x600		 16 
103h 	800x600		 256 
104h 	1024x768	 16 
105h 	1024x768	 256 
106h 	1280x1024	 16 
107h 	1280x1024	 256 
108h 	80x60		 text 
109h 	132x25		 text 
10Ah 	132x43		 text 
10Bh 	132x50		 text 
10Ch 	132x60		 text 
10Dh 	320x200		 32k 
10Eh 	320x200		 64k 
10Fh 	320x200		 16.8m 
110h 	640x480		 32k 
111h 	640x480		 64k 
112h 	640x480		 16.8m 
113h 	800x600		 32k 
114h 	800x600		 64k 
115h 	800x600		 16.8m 
116h 	1024x768	 32k 
117h 	1024x768	 64k 
118h 	1024x768	 16.8m 
119h 	1280x1024	 32k 
11Ah 	1280x1024	 64k 
11Bh 	1280x1024	 16.8m

Those are the available screen modes. So to set a mode we call VESA function 02h. BX will contain the mode number and AX will return &H4F if the mode was set successfully. We also can get info on the screen mode through this TYPE:

TYPE ModeInfoType 
 ModeAttributes AS INTEGER 
 WinAAttributes AS STRING * 1 
 WinBAttributes AS STRING * 1 
 WinGranularity AS INTEGER 
 WinASegment AS INTEGER 
 WinBSegment AS INTEGER 
 WinFuncPointer AS LONG 
 BytesPerScanLine AS INTEGER 
 XResolution AS INTEGER 
 YResolution AS INTEGER 
 XCharSize AS STRING * 1 
 YCharSize AS STRING * 1 
 NumberOfPlanes AS STRING * 1 
 BitsPerPixel AS STRING * 1 
 NumberOfBanks AS STRING * 1 
 MemoryModel AS STRING * 1 
 BankSize AS STRING * 1 
 NumberOfImagePages AS STRING * 1 
 SizeOfBank AS STRING * 1 
 RedMaskSize AS STRING * 1 
 RedFieldPosition AS STRING * 1 
 GreenMaskSize AS STRING * 1 
 GreenFieldPosition AS STRING * 1 
 BlueMaskSize AS STRING * 1 
 BlueFieldPosition AS STRING * 1 
 RsvdMaskSize AS STRING * 1 
 RsvdFieldPosition AS STRING * 1 
 DirectColorModeInfo AS STRING * 1 
 Reserved AS STRING * 216 

I'm not going to explain all these now. Most are self explainatory like XResolutions, and BitsPerPixel. Two of these you should know are WinGranularity and WinASegment. WinGranularity is the size of the memory banks which is important when plotting a pixel. WinASegment is the memory segment which the video memory is located at. This is usually A000h. We can retrieve this information using VESA function 01h. In CX we store the mode number we want info on. In ES:DI we store the segment and offset of the above TYPE. So we could do this to set a mode and get info on it:

'Retrieve mode information
regs.AX = &H4F01
regs.CX = (set-this-to-one-of-the-mode-numbers-listed-above)
regs.ES = VARSEG(ModeInfo)	'Set ES:DI to memory position of the mode info type
regs.DI = VARPTR(ModeInfo)
CALL INTERRUPTX(&H10, regs, regs)

'See if the video mode is supported
IF ModeInfo.ModeAttributes AND 1 = 0 THEN
 PRINT "Unsupported video mode."

'Now set the video mode
regs.AX = &H4F02
regs.BX = (set-this-to-one-of-the-mode-numbers-listed-above)
CALL INTERRUPTX(&H10, regs, regs)
IF regs.AX <> &H4F THEN
 PRINT "Couldn't set video mode."

It would be wise to put it into a function that would return True or False based on the success of setting the mode. Or you could return the number of pages available or the video memory segment, etc.

Well next time we'll learn more about memory banks and how to plot a pixel in 256 colour modes and direct colour modes. Stay tuned!

This article was written by: Fling-master -

All site content is Copyright 2001, HyperRealistic Games. This excludes content submitted by other people.