The ggi_color struct specifies a RGB color. It has 16 bit wide entries for red (.r), green (.g), and blue (.b) values. It also has an alpha value (.a) which is unused in LibGGI, but allow LibGGI extensions to store an alpha value there.
Please scale your palette values as necessary.
For drawing operations, LibGGI uses a pixelvalue, which is the hardware-dependent representation of a pixel. The pixelvalue is represented by the type ggi_pixel.
A pixelvalue is usually obtained from a ggi_color by ggiMapColor or read from the visual by ggiGetPixel.
The relationship between a ggi_color and its associated ggi_pixel value does not change unless you change the visual or the mode or the palette for palettized modes.
You can also do calculations with ggi_pixel values. Their format is defined in the Section called ggi_pixelformat.
The ggi_pixelformat structure describes the format of a ggi_pixel. An application would use this if it wanted to directly output pixelvalues, rather than calling ggiMapColor or ggiPackColors to convert a ggi_color to a ggi_pixel value.
Other than the parameters of a ggi_graphtype that you can specifically request at mode setting, there is no other way to change the parameters of ggi_pixelformat. An application must not assume the presence of any particular pixelformat. If the application cannot handle a particular pixelformat, it should fall back on ggiMapColor, ggiPackColors or ggiCrossBlit.
/* Pixelformat for ggiGet/Put* buffers and pixellinearbuffers */ typedef struct { int depth; /* Number of significant bits */ int size; /* Physical size in bits */ /* * Simple and common things first : * * Usage of the mask/shift pairs: * If new_value is the _sizeof(ggi_pixel)*8bit_ value of the thing * you want to set, you do * * *pointer &= ~???_mask; // Mask out old bits * *pointer |= (new_value>>shift) & ???_mask; * * The reason to use 32 bit and "downshifting" is alignment * and extensibility. You can easily adjust to other datasizes * with a simple addition ... */ /* Simple colors: */ ggi_pixel red_mask; /* Bitmask of red bits */ int red_shift; /* Shift for red bits */ ggi_pixel green_mask; /* Bitmask of green bits */ int green_shift; /* Shift for green bits */ ggi_pixel blue_mask; /* Bitmask of blue bits */ int blue_shift; /* Shift for blue bits */ /* A few common attributes : */ ggi_pixel alpha_mask; /* Bitmask of alphachannel bits */ int alpha_shift; /* Shift for alpha bits */ ggi_pixel clut_mask; /* Bitmask of bits for the clut */ int clut_shift; /* Shift for bits for the clut*/ ggi_pixel fg_mask; /* Bitmask of foreground color */ int fg_shift; /* Shift for foreground color */ ggi_pixel bg_mask; /* Bitmask of background color */ int bg_shift; /* Shift for background color */ ggi_pixel texture_mask; /* Bitmask of the texture (for textmodes - the actual character) */ int texture_shift; /* Shift for texture */
The above is used to describe a pixel simply. More detailed information, if required, can be obtained from the following fields. See ggi/ggi.h for a listing of bitmeanings.
/* * Now if this doesn't suffice you might want to parse the following * to find out what each bit does: */ uint32 bitmeaning[sizeof(ggi_pixel)*8]; /* Shall we keep those ? */ uint32 flags; /* Pixelformat flags */ uint32 stdformat; /* Standard format identifier */ /* This one has only one use for the usermode application: * To quickly check, if two buffers are identical. If both * stdformats are the same and _NOT_ 0 (which means "WEIRD"), * you may use things like memcpy between them which will have * the desired effect ... */ } ggi_pixelformat; /* Pixelformat flags */ #define GGI_PF_REVERSE_ENDIAN 0x01 #define GGI_PF_HIGHBIT_RIGHT 0x02 #define GGI_PF_HAM 0x04 #define GGI_PF_EXTENDED 0x08
depth and size are same as the depth and access size information specified in the ggi_graphtype.
clut_mask is used in GT_PALETTE modes, indicating which bits correspond to an index to the CLUT (color look-up table).
fg_mask, bg_mask, and texture_mask are for text modes only, indicating the parts of the text-mode character.
LibGGI has a current context associated with each visual. This is done for performance reasons, as LibGGI can set up pointers to optimized functions when the GC changes (which can be monitored, as it may only be changed by the functions mentioned below), or switch the hardware state efficiently.
LibGGI has three basic operations on rectangular areas: (including the degenerate cases of horizontal and vertical lines and single pixels):
Set all contained pixels to the current foreground color (maybe modified by the update operations as set in the current graphics context).
Fill the area with pixelvalues from a buffer.
Read pixels from the screen into a buffer.
Get/Put buffers are the buffers used by the functions ggiGet*, ggiPut*, ggiPackColors and ggiUnpackPixels.
The format of the individual pixels in get/put buffers are defined by ggi_pixelformat (see the ggi_pixelformat section above).
Pixels are stored linearly, e.g. a rectangle with a width of three and a height of two will be stored with pixels (0,0) (1,0) (2,0) (0,1) (1,1), (2,1) in that order.
Get/put buffers use chunky pixels, unpacked, even if their representation in the framebuffer is packed (i.e. pixel size not multiple of 8 bits) or non-linear. Thus, the application does not need to know how to use planar or packed pixels for non-direct acccess.
Note: (You may specify use of packed buffers using the GT_SUB_PACKED_GETPUT ggi_graphtype flag, but as of this writing, no targets implement that yet.)
The get/put buffer passed to the LibGGI functions should be allocated for at least width * height * ((ggiGetPixelFormat()->size+7)/8) bytes.
(That is, the pixel size is obtained from ggi_pixelformat.size, rounded to a multiple of 8 bits (one byte), and is multiplied by the width and the height of the buffer.)