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.
TYPE VGAInfoType VESASignature AS STRING * 4 VESAVersion AS INTEGER OEMStringPTR AS LONG Capabilities AS STRING * 4 VideoModePTR AS LONG TotalMemory AS INTEGER Reserved AS STRING * 236 END TYPE
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 VGAInfo AS VGAInfoType 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." ELSE PRINT "VESA not found." END IF
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 WinSize 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 END TYPE
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." END END IF '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." END END IF
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 - http://www.qbrpgs.com
All site content is © Copyright 2001, HyperRealistic Games. This excludes content submitted by other people. |