int vga_accel(unsigned operation, ...);
The main goal is to define functions that can be used as part of certain kinds of interesting graphical operations (not necessarily interesting primitives on their own). Obvious useful primitives in their own are FillBox, ScreenCopy, DrawHLineList (solid polygon), DrawLine.
An interesting purpose is the fast drawing of color bitmaps, both straight and transparent (masked, certain color not written). For masked bitmaps ("sprites"), there is a number of possible methods, the availability of which depends on the chips. Caching in non-visible video memory is often useful. One way is to use a transparency color compare feature of a BITBLT chip, either transferring the image from system memory or cached in video memory. If transparency compare is not available, it may be possible to first clear (zeroe) the mask in the destination area, and then use BITBLT raster-operation to OR the image into the destination (this requires the mask color to be 0). A higher level (library) interface should control this kind of operation.
vga.h contains several macros which may be used for operation. Most of them accept several optional arguments which you may specify after them. The accel(6) svgalib demo shows basic usage of this function. The function returns -1 if the operation is not available and 0 if it is (or better: wasi and could be performed).
Currently the following parameters for vga_accel() are defined:
However, each pixel will all bits set to 0 is drawn in the background color, each pixel with all bits set to 1 is drawn in the foreground color. To allow many different architectures supporting this routine, behaviour is undefined for other values. Bitmap transparency might be supported as well.
You should not expect ACCEL_SCREENCOPYBITMAP handling overlapping screen areas gracefully.
Each byte at *p contains 8 pixels. The lowest order bit of each byte is leftmost on the screen (contrary to the VGA tradition), irrespective of the bitmap bit order flag. Each scanline is aligned to a multiple of 32-bits.
If the transparency mode is enabled (irrespective of the transparency color), then bits that are zero in the bitmap are not written (the background color is not used).
Alas, the sizes of the pixels in both bitmap are different. The bitmap *p must have the format corresponding to ACCEL_PUTBITMAP but will start at the screen memory location where the pixel (x1, y1) would be (probably in off screen memory).
In modes where pixel will not start at byte boundaries (typically those with less then 256 colors), the pixel (x1, y1) must start at a byte boundary (for example in a 16 color mode (4bpp rather than 8bpp for 256 colors) this means that x1 should be an even number).
The easiest way to achieve this is probably to choose x1 == 0 in these situations.
You should not expect ACCEL_SCREENCOPYBITMAP handling overlapping screen areas gracefully.
Normally flag should have the value ACCEL_START | ACCEL_END. However, if the evaluation of the points is costly, you can mix calculations and drawings. Your first call to vga_accel(ACCEL_POLYLINE, ...) must have ACCEL_START set. This will initialize the accelerator. If you do not specify ACCEL_END, you can (actually you have to) follow your call with another vga_accel(ACCEL_POLYLINE, ...) call which will give additional points to connect.
It is important that no other operations (even no color settings) take place between a call with ACCEL_START and the one with the corresponding ACCEL_END. Because of this, it is also important that you lock the console with vga_lockvc(3) and vga_unlockvc(3), s.t. you cannot be interrupted by a console switch.
It is allowed not to set ACCEL_END for your last call to vga_accel(ACCEL_POLYLINE, ...).Thiswillnotdrawthelastpixelofthelast line which is important for some raster operations when drawing closed polygons. The accelerator will automatically deinitialize when called with another operation in this situation.
It is undefined what happens when you specify other values for flag and when your polyline contains only a single point. The line segments must also not be of length zero.
For implementors: In conjunction with raster operations (ROP_XOR, ROP_INV) it is important that endpoints of inner line section are only drawn once. If you cannot achieve that, you must signal that this function cannot be used in conjunction with raster operations. In this case it is valid to always draw all points of the line segments including the endpoints regardless of the existence of a ACCEL_END parameter.
This procedure is done for n scan lines.
In addition there is a flag parameter which works similar to ACCEL_POLYLINE. Your first call to ACCEL_DRAWHLINELIST must have the ACCEL_START bit set for proper initialization. The y parameter is ignored when ACCEL_START is not given.
On contrary to ACCEL_POLYLINE it is required that the last call has the ACCEL_END bit set.
The function is intended for drawing complex filled polygons using horizontal scanlines. By issuing small and fast calls for few scanlines only it is possible to intermix drawing and calculations.
The operation of ACCEL_POLYHLINE is undefined if the x coordinates are not sorted from left to right or there are zero length segments in any scan line or if n or one of the m counters are zero, or one of the m's is not even.
When in polygon fill mode, ACCEL_DRAWLINE and ACCEL_POLYLINE will only draw a single point on each scanline of each line segment. ACCEL_SCREENCOPYMONO will horizontally scan it's source area and start drawing in the foreground color when it encounters a set pixel. When the next pixel is encountered, it will start using the background color and so on.
This can be used for hardware filled polygons:
Because this polygon drawing uses more screen read/write operations it is probably slower than using ACCEL_DRAWHLINELIST or ACCEL_POLYHLINE for drawing a polygon scanline by scanline. However, it is easier to use and it will work mostly without intervention of the CPU which can do other calculations then. See BUGS below.
It is unspecified if the left or right end points of the scanlines are drawn, and most probably some cards (like Mach32) will omit them on one end, at least. Because of that you should always draw the boundary line in the fill color (or another color) after filling the polygon.
Whenever the video screen offset is modified, the accelerator's offset will follow. However you can modify it later with this function.
The following mode values are defined for vga_accel(ACCEL_SETTRANSPARENCY, int mode, ...)
The following mode values are defined for vga_accel(ACCEL_SETRASTEROP, int mode)
IMPORTANT! Please note that a 0 returned by vga_accel(ACCEL_SETTRANSPARENCY, int mode, ...) and vga_accel(ACCEL_SETRASTEROP, int mode) simply means that the set function is available (and thus probably some of above features) but only partial functionality may be available. The VGA_AVAIL_ROPMODES and VGA_AVAIL_TRANSMODES subfunctions of vga_ext_set(3) allow you to check for valid parameters. The VGA_AVAIL_ROP and VGA_AVAIL_TRANSPARENCY subfunctions return which of the vga_accel operations are actually affected by these set functions.
Instead of calling vga_accel() for each operation to find out if it is supported, you can call:
int vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_ACCEL)
When the logical bitwise and of the return value with one of the following predefined (one bit set only) integer constants is non zero, the corresponding operation is available: ACCELFLAG_FILLBOX, ACCELFLAG_SCREENCOPY, ACCELFLAG_PUTIMAGE, ACCELFLAG_DRAWLINE, ACCELFLAG_SETFGCOLOR, ACCELFLAG_SETBGCOLOR, ACCELFLAG_SETTRANSPARENCY, ACCELFLAG_SETRASTEROP, ACCELFLAG_PUTBITMAP, ACCELFLAG_SCREENCOPYBITMAP, ACCELFLAG_DRAWHLINELIST, ACCELFLAG_SETMODE and ACCELFLAG_SYNC.
In addition, calling
int vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_TRANSPARENCY)
int vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_ROP)
does not list the supported values for raster operations and transparency but instead returns the ACCELFLAG_ values for the accelerator operations which respond the raster operation resp. transparency settings.
The availability of the operations will usually depend on the current video mode selected. You should not try to use them or check for availability prior to selecting the mode you want to use with set_mode(3).
You must ensure that the given screen coordinates lie in screen memory. Actually you may not really be sure how offscreen areas are handled, you can only really trust that coordinates which are visible are supported. For example, the Mach32 restricts the allowable x and y coordinates to the range -512 .. 1535. However, even on a 1MB VGA memory card, the offscreen point (0, 1599) would identify a valid screen memory location (if you could use it).
Where supported, the vga_accel(ACCEL_SETOFFSET, ...) directive might help to ease things a bit in such situations.
Svgalib's accelerator support is a mess. Right now, only the Ark, the Cirrus, the Chips&Technologies, and the Mach32 svga drivers really support this function. The Mach32 still also supports the old style accelerator functions vga_bitblt(3), vga_blitwait(3), vga_fillblt(3), vga_hlinelistblt(3) and vga_imageblt(3) which were first designed for the Cirrus cards and thus the Mach32 has its problems emulating them. The gl_ functions use the accelerator to some extend. Currently the use both the new and the old style accelerator. You should avoid mixing calls of the new and the old style kinds.
These functions are not well tested. You should expect weird bugs. In any case, the accelerator is of not much use in many typical svgalib applications. Best if you are not using them.
BEWARE! You should not use the graphics accelerator together with the background feature of vga_runinbackground(3). However, you can try using vga_lockvc(3) to lock the vc prior to using the accelerator.
The Mach32 driver does this on it's own, and even keeps the console locked while background accelerator functions are in progress. Other drivers might not be as graceful.
svgalib(7), vgagl(7), libvga.config(5), accel(6), vga_bitblt(3), vga_blitwait(3), vga_ext_set(3), vga_fillblt(3), vga_getmodeinfo(3), vga_hlinelistblt(3), vga_imageblt(3), vga_runinbackground(3), vga_runinbackground_version(3)
This manual page was edited by Michael Weller <email@example.com>. The exact source of the referenced function as well as of the original documentation is unknown.
It is very likely that both are at least to some extent are due to Harm Hanemaayer <H.Hanemaayer@inter.nl.net>.
Occasionally this might be wrong. I hereby asked to be excused by the original author and will happily accept any additions or corrections to this first version of the svgalib manual.