Aros/Developer/Docs/Libraries/CGFX

From Wikibooks, open books for an open world
Jump to: navigation, search
Navbar for the Aros wikibook
Aros User Docs
Aros User Docs
Aros User FAQs
Aros User Applications
Aros User DOS Shell
Aros/User/AmigaLegacy
Aros Dev Docs
Aros Developer Docs
Porting Software from AmigaOS/SDL
For Zune Beginners
Zune .MUI Classes
For SDL Beginners
Aros Developer BuildSystem
Specific platforms
68k Support
PPC Power Architecture Support
Arm Raspberry Pi Support
Android support
Linux and FreeBSD Support
Windows Mingw and MacOSX Support
Aros x86 Installing
Aros x86 Audio/Video Support
Aros x86 Network Support
Aros x86 Complete System HCL
Aros Storage Support IDE SATA etc
Aros Poseidon USB Support
x86-64 Support
misc
Aros Public License


Introduction[edit]

cybergraphics.library is a 15, 16, 24 or 32 bit graphics board extension for the native graphics.library. Up to OS3.1 there are no possibilities to add custom boards into the display database in a system friendly fashion and so it instead patched some of the original graphics functions in order to integrate custom graphics boards into the system.

Nearly every standard 8bit application will work on this 15/16/24 bit screen. But it only can use the additional features, if it knows of CyberGraphics, of course.



Writing Pixels[edit]

For writing pixels, reading Pixels and blitting, there are the functions FillPixelArray, MovePixelArray, ReadPixelArray, ScalePixelArray, SwapPixelArray, WritePixelArray and WriteRGBPixel.



Bitmaps[edit]

Starting with OS 3.x two new graphics calls were added to support bitmap creation and removal: AllocBitmap() (graphics library) and FreeBitmap() (graphics library). With these calls the first step was made to allow custom bitmap formats. Before it was no problem at all to directly render into the planes or to make assumptions about the structure of the bitmap data. To get more information about the bitmap data use GetBitmapAttr() (from graphics library). With this one you could get information on the width, height, depth and certain flags of the bitmap.

This was the first step into the RTG direction, ie like adding a depth attribute to AllocBitMap() etc

As soon as GetBitmapAttr(bm,BMA_FLAGS) didn't return BMF_STANDARD, the bitmap was not direct accessible anymore and could only be accessed by attachment to a rastport and subsequent rendering calls or by using blit calls with a standard bitmap as destination.

Unfortunately many programs didn't follow these guide lines and didn't check for the BMF_STANDARD flag with OS3.0 and above. Cybergrphx version of GetBitMapAttr (bitmap, P96BMA_MEMORY) has to use LockBitMapAddress() with LBMI_BASEADDRESS and don't forget use LBMI_BYTESPERROW either.


With CyberGraphX you also have to add BMF_MINPLANES in the flags field of AllocBitmap()/gfx. It is also possible now to allocate device dependant pixel format bitmaps and standard 15/16/24/32 bit depth image maps. Therefore new bits in the 32bit flags field parameter of AllocBitmap() have been added. If you specify the BMB_SPECIALFMT bit (see includes), the upper 8 bits of the flags longword contain information on the pixel format of the requested bitmap.



Lock BitMaps[edit]

Once allocated, you can attach the returned bitmap to a rastport and do rendering calls. It is NOT possible to attach this bitmap to a screen by supplying it as custom bitmap with OpenScreenTagList() !!

You are not allowed to directly poke into the bitmap image data as long as the bitmap isn't locked. The location and contents of the image data is subject to change and is only valid when it's locked by using the available locking calls. LockBitmapTags()/UnLockBitmap() has been added for this purpose. You HAVE TO supply a taglist with LockBitmapTags() which contains pointers to longwords which are filled with valid data if the call returns with a non-zero value. Only if a non-zero value is returned you are able to access the bitmap directly! Check the address you get back with the LBMI_BASEADDRESS tag. This is the base address you can do your rendering to.

which flags needed for AllocBitMap to create a lockable bitmap? anything else resulted in a "no lock" message

LONG modulo; 
APTR buffer; 
APTR lock = LockBitMapTags(bitmap, LBMI_BASEADDRESS, &buffer, LBMI_BYTESPERROW, &modulo, TAG_DONE); 
 
if (lock) 
{ 
 /* Manipulate bitmap here */ 
 
 UnlockBitMapTags(lock); 
}


#include <proto/graphics.h>
#include <cybergraphx/cybergraphics.h>
#include <proto/cybergraphics.h>

#include <stdio.h>

struct BitMap *bitmap;
APTR handle;
IPTR buffer;

int main(void)
{
    bitmap = AllocBitMap(400, 300, 32,
        /*BMF_MINPLANES | BMF_DISPLAYABLE | */ BMF_SPECIALFMT | SHIFT_PIXFMT(PIXFMT_ABGR32), NULL);
    if (bitmap)
    {
        //handle = LockBitMapTags(bitmap, LBMI_BASEADDRESS, &buffer, TAG_DONE);
        handle = LockBitMapTags(bitmap, TAG_DONE);
        if (handle)
        {
            printf("buffer %x\n", (unsigned int)buffer);
            UnLockBitMap(handle);
        }
        else
        {
            puts("no lock");
        }
        FreeBitMap(bitmap);
    }
    else
    {
        puts("no bitmap");
    }
    return 0;
}


Is there some function that returns whether a locking of the bitmap works ? No. The cgx autodocs say that LockbitMap will return 0 if the bitmap could not be locked. It does not say that a bitmap which was successfully locked once, can be successfully locked every time. So a function telling whether bitmaps are lockable or not would not really help.

I would make the code check return value of LockBitMap(). if it is 0 (failure) do the workaround (WritePixelArray(), otherwise do direct bitmap access. Or if this for some reason is not optimal/working, make it configurable whether program shall (try to) use LockBitMap or not.

Otherwise for vice this means that will have to do a 'test' lock and see if it works, if it works the code can use the lock code and otherwise it needs to use the WritePixelArray code.

Even though that may work with current drivers, think it would be better to check the retval each time at every LockBitMap() call.

It would be so much easier if aros had some backup code for this. For example if a bitmap lock is not supported but it is called anyway, aros allocates a buffer, copies the bitmap into it, gives the caller the address of the buffer, caller does whatever, when the lock gets released aros copies back the bitmap (or if it's faster, only the changes), and releases the buffer.

As said, this would be slow. But if you want you can try that out yourself by writing your own MyLockBitMap() functions which works like you described.

It's possible, but it would be very slow as it is unknown what the LockBitMap() caller will do. What parts of the bitmap he will access. Whether he will read pixels, write pixels or do both. So the fallback code would need to alloc a pixel buffer and read the whole bitmap into it.



OffScreen BitMap[edit]

All drawing functions work on a bitmap. A rastport is basically just some structure which contains the graphics context (foreground color, line pattern, drawmode). Most drawing functions require a rastport. (a rastport does not automatically come with it's own bitmap!).

You create some rastport. You create some bitmap. You connect the two (put a pointer to the bitmap into the rastport). Then you render into rastport and it will go into your bitmap:

struct RastPort rp;
InitRastPort(&rp);
[...]
/* Use rastport */
[...]
DeinitRastPort(&rp);


struct RastPort *rp;

if ((rp = CreateRastPort()))
{
  [...]
  /* use rastport */
  FreeRastPort(rp);
}


If using a windowed application running on a 15-bit (or higher) Workbench. The application uses an offscreen BitMap for rendering, the contents are then copied to the window with a ClipBlit(). Assuming my offscreen BitMap is a friend of the Workbench screen Bitmap and is at least 15 bits deep, how do we arbitrarily set the colour we want to draw with? Basically you will need to GetColorMap(), followed by a number of SetRGB32CM().

win->WScreen->ViewPort.Colormap 

So how can we take a pointer to that and feed it to ObtainPen() to get my custom drawing colour, right? Better use ObtainBestPen().


allocating bitmap in same format as screen (wb) bitmap for best performance:

bm = AllocBitMap(width, height, depth, BMF_MINPLANES, screen->RastPort.BitMap);

Connecting rastport with bitmap:

rp->BitMap = bm;

Note tough that this way you don't get any clipping at all, so do not render outside of the bitmap dimensions or it will crash (not necessarily happens under AROS/hosted/x11 as x11 clips everything).

If you really need clipping as well then you would have to install a layerinfo plus some layer connected with your bitmap and then use layer->rp as rastport.


You need to differentiate between indexed and truecolor by force. To draw single pixel in indexed mode there is graphics.library/WritePixel(). To draw single pixel in truecolor mode using an RGB value there's cybergraphics.library/WriteRGBPixel.

To draw multiple indexed pixels there's graphics.library/WritePixelLine8() or WritePixelArray8() or WriteChunkyPixels(). On truecolor screens drawing multiple *still indexed* pixels there's cybergraphics.library/WriteLUTPixelArray().

To draw RGB pixels on truecolors screens you can use cybergraphics.library/WritePixelArray(rectfmt = RECTFMT_RGB or RECTFMT_ARGB or RECTFMT_RGBA).

RGB = R8 G8 B8 R8 G8 B8 ... ARGB = A8 R8 G8 B8 A8 R8 G8 B8 ... ...

in memory, independent of endianess of computer.

The pixel buffer will be converted to the destination bitmap pixel format automatically but this conversion may be slow as we have only one general slow conversion routine.

Better would be to use RECTFMT_RAW which means same pixel format as destination bitmap. Then you would have to do the conversion yourself before calling WritePixelArray(RECTFMT_RAW).

Unfortunately there's no special function to do something WritePixelArray()-like-but-with-mask.

line drawing: well, that's done through Move(rp, x1, y1) and Draw(rp, x2, y2). At the moment this is tough only with tricks usable using a specific RGB color of your choice on a truecolor screen. By default color is pen/indexed based, both on indexed screens and truecolor screens where color is set with SetAPen().

There's no such thing for polygon functions, unfortunately. At the moment those are rendered old-style in software by graphics.library into a 1-plane bitmap and then put into destination rp/bitmap using BltPattern().

By the way, the BitMap you get with the AllocScreenBuffer command is the same as the screen's, so it's suitable for accelerated operations. You would just link the bitmap in the screenbuffer to a RastPort to use with the graphics library commands that need one. Again, that's on the Amiga. It would be nice to get this working in AROS as well.

/*
    Example for bitmaps
*/
 
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
 
#include <graphics/gfxmacros.h>
 
#include <stdlib.h>
#include <stdio.h>
 
static struct Window *window;
static struct ColorMap *cm;
static struct RastPort *win_rp;
 
#define BMWIDTH (50)
#define BMHEIGHT (50)
struct BitMap *bm;
struct RastPort *bm_rp;
 
/*
    ObtainBestPen() returns -1 when it fails, therefore we
    initialize the pen numbers with -1 to simplify cleanup.
*/
static LONG pen1=-1;
static LONG pen2=-1;
 
static void draw_bitmap(void);
static void clean_exit(CONST_STRPTR s);
static void handle_events(void);
 
 
int main(void)
{
    window = OpenWindowTags(NULL,
        WA_Left,   50,
        WA_Top,    70,
        WA_Width,  400,
        WA_Height, 350,
 
        WA_Title,         "Bitmap Graphics",
        WA_Activate,      TRUE,
        WA_SmartRefresh,  TRUE,
        WA_NoCareRefresh, TRUE,
        WA_GimmeZeroZero, TRUE,
        WA_CloseGadget,   TRUE,
        WA_DragBar,       TRUE,
        WA_DepthGadget,   TRUE,
        WA_IDCMP,         IDCMP_CLOSEWINDOW,
        TAG_END);
 
    if (! window) clean_exit("Can't open window\n");
 
    win_rp = window->RPort;
    cm = window->WScreen->ViewPort.ColorMap;
 
    // Let's obtain two pens
    pen1 = ObtainBestPen(cm, 0xFFFF0000 , 0 , 0 , TAG_END);
    pen2 = ObtainBestPen(cm, 0 , 0 , 0xFFFF0000 , TAG_END);
    if ( !pen1 || !pen2) clean_exit("Can't allocate pen\n");
 
    draw_bitmap();
    handle_events();
 
    clean_exit(NULL);
 
    return 0;
}
 
 
static void draw_bitmap(void)
{
    /*
        Get the depth of the screen. Don't peek in the structures, always use
        GetBitMapAttr().
    */
    UWORD depth = GetBitMapAttr(win_rp->BitMap, BMA_DEPTH);
 
    /*
        Create new bitmap. With BMF_MINPLANES and the bitmap pointer we are saying
        that we want a bitmap which is similar than the target bitmap.
    */
    bm = AllocBitMap(BMWIDTH , BMHEIGHT, depth, BMF_MINPLANES, win_rp->BitMap);
    if (!bm) clean_exit("Can't allocate bitmap\n");
 
    bm_rp = CreateRastPort();      // Create rastport for our bitmap
    if (!bm_rp) clean_exit("Can't allocate rastport!\n");
    bm_rp->BitMap = bm;            // Link bitmap to rastport
 
    /*
        Now we can draw into our bitmap. Take care that the bitmap has no
        clipping rectangle. This means we must not draw over the limits.
    */
    SetRast(bm_rp, 0);                // fill whole bitmap with color 0
    SetAPen(bm_rp, pen1);
    DrawCircle(bm_rp, 24, 24, 24);
    SetAPen(bm_rp, pen2);
    Move(bm_rp, 0, 0);
    Draw(bm_rp, 49, 49);
    Move(bm_rp, 49, 0);
    Draw(bm_rp, 0, 49);
    Draw(bm_rp, 49, 49);
    Draw(bm_rp, 49, 0);
    Draw(bm_rp, 0, 0);
    Draw(bm_rp, 0, 49);
 
    int x;
    for (x=20; x<400 ; x+=30)
    {
        // Blit the bitmap into the window
        ClipBlit(bm_rp, 0, 0, win_rp, x, x/2, BMWIDTH, BMHEIGHT, 0xC0);
    }
}
 
 
static void handle_events(void)
{
    /*
        A simple event handler. This will be explained more detailed in the Intuition examples.
    */
    struct IntuiMessage *imsg;
    struct MsgPort *port = window->UserPort;
    BOOL terminated = FALSE;
 
    while (!terminated)
    {
        Wait(1L << port->mp_SigBit);
        if ((imsg = (struct IntuiMessage *)GetMsg(port)) != NULL)
        {
            switch (imsg->Class)
            {
                case IDCMP_CLOSEWINDOW:
                    terminated = TRUE;
                    break;
            }
            ReplyMsg((struct Message *)imsg);
        }
    }
}
 
 
static void clean_exit(CONST_STRPTR s)
{
    if (s) PutStr(s);
 
    // Give back allocated resourses
    if (bm) FreeBitMap(bm);
    if (bm_rp) FreeRastPort(bm_rp);
    if (pen1 != -1) ReleasePen(cm, pen1);
    if (pen2 != -1) ReleasePen(cm, pen2);
    if (window) CloseWindow(window);
 
    exit(0);
}




Buffering (Double or Multi)[edit]

Start up code


DBufInfo dbi[edit]

struct DBufInfo
        STRUCTURE DBufInfo,0
        APTR    dbi_Link1
        ULONG   dbi_Count1
        STRUCT  dbi_SafeMessage,MN_SIZE
        APTR    dbi_UserData1
        APTR    dbi_Link2
        ULONG   dbi_Count2
        STRUCT  dbi_DispMessage,MN_SIZE
        APTR    dbi_UserData2
        ULONG   dbi_MatchLong
        APTR    dbi_CopPtr1
        APTR    dbi_CopPtr2
        APTR    dbi_CopPtr3
        UWORD   dbi_BeamPos1
        UWORD   dbi_BeamPos2
        LABEL   dbi_SIZEOF

Only these are to be used dbi_SafeMessage, dbi_DispMessage, dbi_UserData1 and dbi_UserData2


The following fragment shows proper double buffering synchronization:
 
 int SafeToChange=TRUE, SafeToWrite=TRUE, CurBuffer=1;
 
 struct MsgPort *ports[2];    /* reply ports for DispMessage and SafeMessage 
 
*/
 
 struct BitMap *BmPtrs[2];
 
 struct DBufInfo *myDBI;
 
 ... allocate bitmap pointers, DBufInfo, set up viewports, etc.
 
 myDBI->dbi_SafeMessage.mn_ReplyPort=ports[0];
 
 myDBI->dbi_DispMessage.mn_ReplyPort=ports[1];
 
 while (! done)
 
 {
 
     if (! SafeToWrite)
 
  while(! GetMsg(ports[0])) Wait(1l<<(ports[0]->mp_SigBit));
 
     SafeToWrite=TRUE;
 
     ... render to bitmap # CurBuffer.
 
     if (! SafeToChange)
 
  while(! GetMsg(ports[1])) Wait(1l<<(ports[1]->mp_SigBit));
 
     SafeToChange=TRUE;
 
     WaitBlit();         /* be sure rendering has finished */
 
     ChangeVPBitMap(vp,BmPtrs[CurBuffer],myDBI);
 
     SafeToChange=FALSE;
 
     SafeToWrite=FALSE;
 
     CurBuffer ^=1; /* toggle current buffer */
 
 }
 
       if (! SafeToChange) /* cleanup pending messages */
 
     while(! GetMsg(ports[1])) Wait(1l<<(ports[1]->mp_SigBit));
 
       if (! SafeToWrite) /* cleanup */
 
     while(! GetMsg(ports[0])) Wait(1l<<(ports[0]->mp_SigBit));



ScrollVPort[edit]

here's my double buffer algorithm for cybergraphics screens: I allocate a screen twice the height (non draggable), do all my off-screen rendering in the non-viewable section (the bottom half usually) and when I'm done I do one huge blit (ClipBlit) to copy everything in the bottom half up to the top, viewable area of the screen. This works pretty quickly even on big screens with high depth.

/* multibuffering use ScrollVPort() on double height screen and sync with WaitBOV() but AVOID WaitTOF() */
/* struct Screen *screen = OpenScreenTags() with SA_HEIGHT equal to 960
Then screen->Viewport->RasInfo->RyOffset = 480; ScrollVport(screen->ViewPort); WaitBOVP(screen->ViewPort); 
   check overscan set 
RTG modes do not use sprites (except mouse) use BltBitMap functions instead */
 
 
/* Create double height display */
fb->bm = bm_create_disp(width, height*2, depth);
 
/* Screen Taglist here */
 
 
fb->screen = OpenScreen(&newScreen);
 
/* To get bitmap pointer */
bloqueo=(APTR)LockBitMapTags(*rastportptr->BitMap,LBMI_BASEADDRESS, &direccionbase,TAG_DONE);
 
/* made the double buffer changing the RasInfo->RyOffset value, and executing ScrollVPort and WaitBOVP */
fb->screen->ViewPort.RasInfo->RyOffset = fb->frame*fb->height;
 
fb->frame ^= 1;
fb->frameOffset = fb->frame*fb->height;
 
ScrollVPort(&fb->screen->ViewPort);
WaitBOVP(&fb->screen->ViewPort);



ChangeScreenBuffer (Aros Broken?)[edit]

Sources here

// Flip.
while (ChangeScreenBuffer(video_screen, screenBuffer[drawBuffer]) == 0) {
/* do nothing! */ ;
}

The idea being that ChangeScreenBuffer() returns zero if it can't do the flip and probably does the signal checking stuff internally. For double buffering you use standard Double Buffering functions like the functions around AllocScreenBuffer.



Struct ScreenBuffer


sb[0] = AllocScreenBuffer(screen, NULL, SB_SCREEN_BITMAP);
sb[1] = AllocScreenBuffer(screen, NULL, SB_COPY_BITMAP);
 
ports[0] = CreateMsgPort();
ports[1] = CreateMsgPort();
 
UBYTE toggle=0; // 
 
sb[toggle]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = ports[0];
sb[toggle]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort = ports[1];
 
Wait(1l << (ports[1]->mp_SigBit));
ChangeScreenBuffer(screen, sb[toggle]);
 
toggle ^= 1; // 
 
Wait(1l << (ports[0]->mp_SigBit));

There is also a Commodore example doublebuffer.c to look at as well as CyberAnim13.lha.



Instead you should use WritePixelArray() or WriteLUTPixelArray() from CGX API or WriteChunkyPixels() from graphisc.library. Please note WriteChunkyPixels() is available only in Kickstart 3.1 so you have to add fallback routine for 3.0 users.

Please note you can not write directly to bitmap which dont have BMF_STANDARD flag set!

Take a look at CGX devkit. It explains what restrictions you have with RTG systems, and what you should take into account (especially that BMF_STANDARD flag in bitmaps).



Is there any way to avoid the excessive blinking and have the display behave more like normal ?

AROS at the moment has only one general non optimized RGB format conversion routine which is of course slow. There are no special one for common cases like ARGB32 to RGB15. You could do the conversion yourself and then use RECTFMT_RAW.

gray bars/blinking. Do you WritePixelArray() directly into window RastPort? It's unlikely original code (if using LockBitMap()) did that, so you shouldn't either, if that's not a whole "frame" which is written at once. Either collect pixels in a whole frame pixel buffer and do WritePixelArray() to window, once a whole frame is "ready". Or WritePixelArray() into a offscreen bitmap and BltBitMapRastPort() that to the window, once a whole frame is "ready".

Or it could be the double buffering functions (AllocScreenBuffer(), ChangeScreenBuffer(), ...) which are not yet working in AROS.

Could AROS's CGFX implementation not just use an internal lookup for RECTFMTS that is "correct" for whatever arch?

Programmer writes RACTFMT_BGR32 -> CGFX interprets it before performing the normal action? or would it be too much of a slow down? There's no need to change anything in the CGFX implementation. Only some optional redefining of the pixfmt/rectfmt ids in libraries/cybergraphics.h


What exactly does WritePixelArrayAlpha do on AROS? From BM__Hidd_BitMap__PutAlphaImage() in workbench/hidds/graphics BM_Class.c. That's the fallback code when the gfx drivers do not override reeimplement it.



ScreenMode[edit]

Cybergrafix supports some very fine functions to select a screenmode, for example BestCModeIDTagList, which gets the best screenmode for a specified tag list of screen attributes.



Pixel Formats[edit]

The following pixel formats are available:

 PIXFMT_LUT8,PIXFMT_RGB15,PIXFMT_BGR15,PIXFMT_RGB15PC,PIXFMT_BGR15PC,
 PIXFMT_RGB16,PIXFMT_BGR16,PIXFMT_RGB16PC,PIXFMT_BGR16PC,PIXFMT_RGB24,
 PIXFMT_BGR24,PIXFMT_ARGB32,PIXFMT_BGRA32,PIXFMT_RGBA32 

Many of this pixel formats are device specific and should not be used, recommended formats are PIXFMT_LUT8, PIXFMT_RGB16, PIXFMT_RGB24 and PIXFMT_ARGB32.


Get the value of the LBMI_PIXFMT ULONG field to get information on the colormodel you have to use for image rendering. ALL models have to be supported! The other fields give you information on the layout of the bitmap data. It should be no problem, to directly render into the bitmap anymore. Keep in mind that all this values are only valid until a subsequent call to UnLockBitmap(). Afterwards you have to lock the bitmap again. Don't hold this lock for longer than one frame ! You may use the standard graphics.library bitmap blitting calls to copy the bitmap contents to another bitmap. Copying truecolour bitmaps into indexed colour chunky bitmaps is not supported by now.


locking the bitmap to write directly into gfx card memory will require that you use cgx functions. Otherwise you'll have to use WritePixelArray like functions. Opening cgx library is good since it works with classic miggies with rtg (both cgx & p96 will work)


how to fix direct bitmap access. First i want to remove extended pixelformat definitions:

#define PIXFMT_ABGR32 100UL
#define PIXFMT_0RGB32 101UL
#define PIXFMT_BGR032 102UL
#define PIXFMT_RGB032 103UL
#define PIXFMT_0BGR32 104UL


They can confuse programs because they don't know about them. Additionally, 0RGB32 (for example) is effectively the same as ARGB32, which is the standard definition. The only question is ABGR32 format. It is expected to be other-endian version of RGBA32. And i'd like to check if some GFX cards are actually using ABGR32.

On such cards monitorclass test will report that none of known pixelformats are supported. Monitorclass does not work with extended pixelformats, as a test. If not, i'll leave ABGR32 format in the specification but give it number 14, next to RGBA32. This will be much more comfortable for monitorclass (it uses a pixelformat-indexed array in one place).

Currently only one driver that uses RGBA32 format. It's Windows-hosted driver. Windows GDI uses this pixelformat internally. If we imagine Windows on bigendian CPU, it will become ABGR32. At the other hand, there will never be any more bigendian CPUs in the world. Additionally, this is fixable by the software.

Getting rid of bad pixelformat codes in CGX will almost do the job. The other thing will be endianess conversion removal in some software. Pixelformat describes how pixels are laid out in RAM, so there's no need to swap bytes.


  1. Rendering directly to bitmap works, but only if gfx driver supports it. Nvidia driver does, most others don't.
  2. Pixel and rectformats in AROS cybergraphics always refer to the layout in memory. So RECTFMT_ARGB means 0xAA 0xRR 0xGG 0xBB. And this is so no matter if running on big endian or little endian machine. This is important to know for when running on little endian (x86) machine, because then if you have an ULONG pixel array/buffer where you write ARGB pixels into it using pixel (ULONG) accesses then in memory it will look like 0xBB 0xGG 0xRR 0xAA and you would need to use RECTFMT_BGRA.

If you have a screen using PIXFMT_RGB16PC, but WORD pixelbuffers then on AROS little endian you would need to use RECTFMT_RGB16 and only on AROS big endinan RECTFMT_RGB16PC.

Since this actual meaning of rectfmts/pixfmts is sometimes not very nice intuitive (#if AROS_BIG_ENDIAN do_this #else do_that) there are plans to modify libraries/cybergraphics.h so that it switches meaning of rectfmts pixelformats from being "based" on memory layout to being based on pixel access.

Btw, there's also RECTFMT_RAW which means same format as bitmap format.

Could AROS's CGFX implementation not just use an internal lookup for RECTFMTS that is "correct" for whatever arch?

Programmer writes RACTFMT_BGR32 -> CGFX interprets it before performing the normal action? or would it be too much of a slow down?

Is using WritePixelArray any faster to an offscreen bitmap (one not allocated to be visible) ?

hardware accel: gfx drivers could override/reimplement PutAlphaImage() method if they want. But I do not know how much sense that makes or if it's possible at all as with WritePixelArrayAlpha() you have an ARGB pixel buffer which will likely be in RAM. Gfx cards if they can accelerate this might need the pixels to be in VRAM. I don't know.



Endian[edit]

This is an endianess thing. On AROS big endian it's exactly the same as in AOS/MOS. Because pixel access/component access/memory layout on big endian machine does not make a difference. If you write a 0xAARRGGBB ULONG to memory it will be 0xAA 0xRR 0xGG 0xBB in memory, too. Same thing. No problem.

On little endian machine it was something of a design decision whether the RECTFMTs/PIXFMTs should reflect pixel access based meaning (unit == pixel) or memory layout based meaning (unit == byte or component). Because RECTFMT_ARGB does not mean that one by force always uses ULONG pixel buffers and only ULONG pixel accesses. One may also use byte/component access. Or read/write such pixel buffers to/from disk.

But if you do not like that it can easily be fixed by adding something like this to your code:

#if !AROS_BIG_ENDIAN 
#define PIXFMT_LUT8  0UL 
#define PIXFMT_RGB15 3UL  /* RGB15PC */ 
#define PIXFMT_BGR15    4UL  /* BGR15PC */ 
#define PIXFMT_RGB15PC  1UL  /* RGB15 */ 
#define PIXFMT_BGR15PC  2UL  /* BGR15 */ 
#define PIXFMT_RGB16    7UL  /* RGB16PC */ 
#define PIXFMT_BGR16    8UL  /* BGR16PC */ 
#define PIXFMT_RGB16PC  5UL  /* RGB16 */ 
#define PIXFMT_BGR16PC  6UL  /* BGR16 */ 
#define PIXFMT_RGB24    10UL /* BGR24 */ 
#define PIXFMT_BGR24    9UL  /* RGB24 */ 
#define PIXFMT_ARGB32   12UL /* BGRA32 */ 
#define PIXFMT_BGRA32   11UL /* ARGB32 */ 
#define PIXFMT_RGBA32   113UL /* ABGR32 */ 
#endif

At least for the moment. As said it's anyway planned to add such an option to libraries/cybergraphics.h. Then you would do a #define CGX_PIXEL_BASED_FMT_IDS (or some better name) before including libraries cybergraphics.h and be done.

Apps using the original cgfx functions (and attributes for functions like GetCyberMapAttr) should never see this values.

Yes, however only GetCyberMapAttr() processes this. Other places pass them on to applications.

a CYBRMATTR_PIXFMT_ALPHA was introduced, too, which means "do not map, I know about the 0RGB32, etc. pixfmts". In case you want to keep that.

While driver_GetCyberMapAttr() for example seems to map the 0RGB32, BGR032, ... correctly to ARGB32, BGRA32, ... so that (legacy) apps get only values they expect. In other places (which callc hidd2cyber_pixfmt()) this is missing/was forgotten to be fixed.

You could (*) add a BOOL param to hidd2cyber_pixfmt() function which indicates whether or not to map the 0RGB32, etc. to ARGB32, etc. And then pass FALSE in most functions which call hidd2cyber_pixfmt().



CGFX Fix For Cairo[edit]

Cybergrafix supports a function to get some information about the (modified) Bitmap structure, but (sadly) you do not get the address of the video memory. So you can't write directly to the video memory.

For historical reasons related to the Cybergraphics API, graphics.hidd will set the alpha value to 0 when reading 24->32 bits or writing 32->24 bits. pixman will (correctly) interpret the pixels as being transparent. SO before we feed the pixel data in to cairo, we have to fix it by forcing the alpha value to 0xff.

Its complicated further by the fact that we have to handle the non-native endian RGB format as well. The two available formats are (effectively) xRGB and xBGR. For xBGR, we do an endianness swap then shift down before adding the alpha; that is xBGR->RBGx->0RGB->ARGB.

One day graphics.library will give us a way to request this from the graphics.hidd format conversion routines, and this won't be necessary.

Our CyberGraphX API has BltTemplateAlpha() and WritePixelArrayAlpha(), and they work. Other functions do not process alpha channel, because they are not intended to do it. For CGX ARGB pixelformat actually means 0RGB.

I think this is specifically about hardware alpha handling:

Fix up Hardware & Software Alpha channel support in graphics.library and gfx.hidd

  • Must enable at least one hardware alpha capable driver to demonstrate functionality.
  • Must also provide a test application demonstrating it in use.

I think currently all drivers implement PutAlphaImage via a software method. I borrowed the implementation in nouveau from nvidia if I remember correctly and the implementation is:

For each pixel of alpha enabled image, check if alpha is different than 0 or 0xff, if yes read the pixel from VRAM, apply new color with alpha and write it back. Reading from VRAM is terribly slow, thus our Decoration, which uses alpha images, seems very slow when you had several windows open and moving them around.




Examples[edit]

#include <cybergraphx/cybergraphics.h>
 
#include <proto/intuition.h>
#include <proto/cybergraphics.h>
 
#include <stdio.h>
#include <string.h>
 
#define NUM_PIXFMT 14
 
static char *pixfmt_str[14]=
{
    "LUT8",
    "RGB15",
    "BGR15",
    "RGB15PC",
    "BGR15PC",
    "RGB16",
    "BGR16",
    "RGB16PC",
    "BGR16PC",
    "RGB24",
    "BGR24",
    "ARGB32",
    "BGRA32",
    "RGBA32"
};
 
int main(void)
{
    struct Screen *scr = IntuitionBase->ActiveScreen;
 
    if (scr)
    {
    	struct BitMap *bm = scr->RastPort.BitMap;
	LONG pixfmt;
 
	pixfmt = GetCyberMapAttr(bm, CYBRMATTR_PIXFMT);
 
	printf("Pixel Format: #%ld (%s)\n",
	       pixfmt,
	       ((pixfmt >= 0) && (pixfmt < NUM_PIXFMT)) ? pixfmt_str[pixfmt] : "<unknown>");
 
    }
 
    return 0;
 
}


#include <dos/dos.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>
#include <cybergraphx/cybergraphics.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/cybergraphics.h>
#include <proto/intuition.h>
 
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
 
#define SCREENWIDTH  300
#define SCREENHEIGHT 200
#define SCREENCY (SCREENHEIGHT / 2)
 
/***********************************************************************************/
 
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *CyberGfxBase;
struct Screen *scr;
struct Window *win;
struct RastPort *rp;
 
ULONG cgfx_coltab[256];
UBYTE Keys[128];
 
/***********************************************************************************/
 
static void cleanup(char *msg)
{
    if (msg)
    {
        printf("WritePixelArray: %s\n",msg);
    }
 
    if (win) CloseWindow(win);
 
    if (scr) UnlockPubScreen(0, scr);
 
    if (CyberGfxBase) CloseLibrary(CyberGfxBase);
    if (GfxBase) CloseLibrary((struct Library *)GfxBase);
    if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
 
    exit(0);
}
 
/***********************************************************************************/
 
static void openlibs(void)
{
    if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 39)))
    {
        cleanup("Can't open intuition.library V39!");
    }
 
    if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 39)))
    {
        cleanup("Can't open graphics.library V39!");
    }
 
    if (!(CyberGfxBase = OpenLibrary("cybergraphics.library",0)))
    {
        cleanup("Can't open cybergraphics.library!");
    }
}
 
/***********************************************************************************/
 
static void getvisual(void)
{
    if (!(scr = LockPubScreen(NULL)))
    {
        cleanup("Can't lock pub screen!");
    }
 
    if (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) <= 8)
    {
        cleanup("Need hi or true color screen!");
    }
}
 
/***********************************************************************************/
 
static void makewin(void)
{
    win = OpenWindowTags(NULL, WA_CustomScreen	, (IPTR)scr, 
    			       WA_InnerWidth	, SCREENWIDTH,
    			       WA_InnerHeight	, SCREENHEIGHT,
			       WA_Title		, (IPTR)"WritePixelArray: Move mouse!",
			       WA_DragBar	, TRUE,
			       WA_DepthGadget	, TRUE,
			       WA_CloseGadget	, TRUE,
			       WA_Activate	, TRUE,
			       WA_IDCMP		, IDCMP_CLOSEWINDOW |
			       			  IDCMP_RAWKEY,
			       TAG_DONE);
 
   if (!win) cleanup("Can't open window");
 
   rp = win->RPort; 
}
 
/***********************************************************************************/
 
#define KC_LEFT         0x4F
#define KC_RIGHT     	0x4E
#define KC_UP        	0x4C
#define KC_DOWN      	0x4D
#define KC_ESC       	0x45
 
/***********************************************************************************/
 
static void getevents(void)
{
    struct IntuiMessage *msg;
 
    while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
    {
        switch(msg->Class)
	{
	    case IDCMP_CLOSEWINDOW:
	        Keys[KC_ESC] = 1;
		break;
 
	    case IDCMP_RAWKEY:
	        {
		    WORD code = msg->Code & ~IECODE_UP_PREFIX;
 
		    Keys[code] = (code == msg->Code) ? 1 : 0;
 
		}
	        break;
 
	}
        ReplyMsg((struct Message *)msg);
    }
 
}
 
/***********************************************************************************/
 
static void action(void)
{
    static LONG tab[SCREENWIDTH * SCREENHEIGHT];
    LONG x, y;
    LONG ar1, ar2, ar3, ar4;
    LONG ag1, ag2, ag3, ag4;
    LONG ab1, ab2, ab3, ab4;
    LONG r1, r2, r3, r4;
    LONG g1, g2, g3, g4;
    LONG b1, b2, b3, b4;
    LONG tr1, tg1, tb1;
    LONG tr2, tg2, tb2;
    LONG tr3, tg3, tb3;
    LONG tr4, tg4, tb4;
    LONG ttr1, ttg1, ttb1;
    LONG ttr2, ttg2, ttb2;
    LONG tttr, tttg, tttb;
 
    LONG col;
 
    ar1 = 0xFF; ag1 = 0xFF; ab1 = 0xFF; 
    ar2 = 0xFF; ag2 = 0x00; ab2 = 0x00; 
    ar3 = 0x00; ag3 = 0xFF; ab3 = 0x00; 
    ar4 = 0x00; ag4 = 0x00; ab4 = 0xFF; 
 
    r1 = 0xFF; g1 = 0xFF; b1 = 0xFF; 
    r2 = 0xFF; g2 = 0x00; b2 = 0x00; 
    r3 = 0x00; g3 = 0xFF; b3 = 0x00; 
    r4 = 0x00; g4 = 0x00; b4 = 0xFF; 
 
    while(!Keys[KC_ESC])
    {
        x = scr->MouseX;
	if (x < 0) x = 0; else if (x >= scr->Width) x = scr->Width - 1;
 
	r1 = ar1 + (ar2 - ar1) * x / (scr->Width - 1);
	g1 = ag1 + (ag2 - ag1) * x / (scr->Width - 1);
	b1 = ab1 + (ab2 - ab1) * x / (scr->Width - 1);
 
	r2 = ar2 + (ar3 - ar2) * x / (scr->Width - 1);
	g2 = ag2 + (ag3 - ag2) * x / (scr->Width - 1);
	b2 = ab2 + (ab3 - ab2) * x / (scr->Width - 1);
 
	r3 = ar3 + (ar4 - ar3) * x / (scr->Width - 1);
	g3 = ag3 + (ag4 - ag3) * x / (scr->Width - 1);
	b3 = ab3 + (ab4 - ab3) * x / (scr->Width - 1);
 
	r4 = ar4 + (ar1 - ar4) * x / (scr->Width - 1);
	g4 = ag4 + (ag1 - ag4) * x / (scr->Width - 1);
	b4 = ab4 + (ab1 - ab4) * x / (scr->Width - 1);
 
 
        for(y = 0; y < SCREENHEIGHT; y ++)
	{
	    for(x = 0; x < SCREENWIDTH; x++)
	    {
	        tr1 = r1 + (r2 - r1) * x / (SCREENWIDTH - 1);
		tg1 = g1 + (g2 - g1) * x / (SCREENWIDTH - 1);
		tb1 = b1 + (b2 - b1) * x / (SCREENWIDTH - 1);
 
		tr2 = r3 + (r4 - r3) * x / (SCREENWIDTH - 1);
		tg2 = g3 + (g4 - g3) * x / (SCREENWIDTH - 1);
		tb2 = b3 + (b4 - b3) * x / (SCREENWIDTH - 1);
 
		tr3 = r1 + (r3 - r1) * y / (SCREENHEIGHT - 1);
		tg3 = g1 + (g3 - g1) * y / (SCREENHEIGHT - 1);
		tb3 = b1 + (b3 - b1) * y / (SCREENHEIGHT - 1);
 
		tr4 = r2 + (r4 - r2) * y / (SCREENHEIGHT - 1);
		tg4 = g2 + (g4 - g2) * y / (SCREENHEIGHT - 1);
		tb4 = b2 + (b4 - b2) * y / (SCREENHEIGHT - 1);
 
		ttr1 = tr1 + (tr2 - tr1) * y / (SCREENHEIGHT - 1);
		ttg1 = tg1 + (tg2 - tg1) * y / (SCREENHEIGHT - 1);
		ttb1 = tg1 + (tg2 - tg1) * y / (SCREENHEIGHT - 1);
 
		ttr2 = tr3 + (tr4 - tr3) * x / (SCREENWIDTH - 1);
		ttg2 = tg3 + (tg4 - tg3) * x / (SCREENWIDTH - 1);
		ttb2 = tb3 + (tb4 - tb3) * x / (SCREENWIDTH - 1);
 
		tttr = (ttr1 + ttr2) / 2;
		tttg = (ttg1 + ttg2) / 2;
		tttb = (ttb1 + ttb2) / 2;
 
#if AROS_BIG_ENDIAN
		col = (tttr << 16) + (tttg << 8) + tttb;
#else		
		col = (tttb << 24) + (tttg << 16) + (tttr << 8);
#endif		
		//kprintf("col[%d,%d] = %08x\n", x,y,col);
	        tab[y * SCREENWIDTH + x] = col;
 
	    } /* for(y = 0; y < SCREENHEIGHT; y ++) */
 
	} /* for(y = 0; y < SCREENHEIGHT; y ++) */
 
	WritePixelArray(tab, 0, 0, SCREENWIDTH * sizeof(LONG), 
			win->RPort, win->BorderLeft, win->BorderTop, SCREENWIDTH, SCREENHEIGHT,
			RECTFMT_ARGB);
 
        getevents();
 
    } /* while(!Keys[KC_ESC]) */
}
 
/***********************************************************************************/
 
int main(void)
{
    openlibs();
    getvisual();
    makewin();
    action();
    cleanup(0);
 
    return 0; /* keep compiler happy */
}
 
/***********************************************************************************/


On the other hand to draw in the screen you could also use a generic function like: WritePixelArray8(rastportptr, 0, (bufferactual-1)*(pantalla->Height/numerodebuffers ),319,199,(UBYTE *)chunkybuffer, NULL);



WritePixelArray ( ) ? Look up on the cybergfx functions, they are very easy and do a lot of pixel conversions for you.

http://thomas-rapp.homepage.t-online.de/examples/dtwin.c


struct BitMap *copy_bitmap (struct BitMap *oldbm);
 
BOOL load_pic (char *filename,struct BitMap **bitmap_ptr,ULONG **palette_ptr)
{
    Object *o;
    long ncols = 0;
    struct BitMap *bitmap;
    ULONG *palette;
 
    o = NewDTObject (filename,
        DTA_GroupID,GID_PICTURE,
        PDTA_Remap,FALSE,
        TAG_END);
    if (!o) return (FALSE);
 
    DoDTMethod (o,NULL,NULL,DTM_PROCLAYOUT,NULL,TRUE);
 
    GetDTAttrs (o,
        PDTA_NumColors, (long unsigned int)&ncols,
        PDTA_CRegs,(long unsigned int) &palette,
        PDTA_DestBitMap,(long unsigned int) &bitmap,
        TAG_END);
 
    if (ncols)
    {
        long size = ncols * 3 * sizeof(ULONG);
 
        *palette_ptr = (ULONG*)AllocVec (size,0);
        *palette_ptr = AllocVec (size,0);
        if (*palette_ptr) memcpy (*palette_ptr,palette,size);
    }
 
    *bitmap_ptr = copy_bitmap (bitmap);
 
    DisposeDTObject (o);
 
    return (TRUE);
}

The tags ... PDTA_Remap,TRUE,PDTA_Screen,scr,PDTA_DestMode,PMODE_V43 ... should enable palette remapping.


/*
gcc -noixemul -Wall -O2 truecolortest.c -o truecolortest
quit
*/
/*
 * Quick'n'dirty example on how to use MorphOS truecolor rendering
 *
 * Written by Harry "Piru" Sintonen <sintonen@iki.fi>.
 * Public Domain.
 *
 */
 
#include <graphics/rastport.h>
#include <graphics/rpattr.h>
#include <graphics/modeid.h>
#include <intuition/screens.h>
 
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/dos.h>
 
#define MKRGB(r,g,b) (((r) << 16) | ((g) << 8) | (b))
 
#define WIDTH   640
#define HEIGHT  480
#define DEPTH   24
 
int main(void)
{
  struct Screen *scr;
  ULONG modeid;
  int ret = RETURN_ERROR;
 
  modeid = BestModeID(BIDTAG_NominalWidth,  WIDTH,
                      BIDTAG_NominalHeight, HEIGHT,
                      BIDTAG_Depth,         DEPTH,
                      TAG_DONE);
 
  if (modeid == INVALID_ID)
  {
    Printf("could not find modeid for %lux%lux%lu mode\n",
           WIDTH, HEIGHT, DEPTH);
 
    return RETURN_WARN;
  }
 
  scr = OpenScreenTags(NULL,
                       SA_DisplayID, modeid,
                       SA_Width,     WIDTH,
                       SA_Height,    HEIGHT,
                       SA_Depth,     DEPTH,
                       SA_Quiet,     TRUE,
                       TAG_DONE);
  if (scr)
  {
    struct BitMap *cookiebm;
 
    cookiebm = AllocBitMap(WIDTH, HEIGHT, 1, 0, NULL);
    if (cookiebm)
    {
      struct RastPort tmprp, *cookierp = &tmprp;
      struct RastPort *rp = &scr->RastPort;
      STRPTR txt;
      WORD len;
      LONG xmid = WIDTH / 2;
      LONG ymid = HEIGHT / 2;
 
      /* Init cookie rastport */
      InitRastPort(cookierp);
      cookierp->BitMap = cookiebm;
      SetABPenDrMd(cookierp, 1, 0, JAM1);
 
      /* Set screen background */
      SetRPAttrs(rp, RPTAG_PenMode, FALSE,
                     RPTAG_FgColor, MKRGB(0xaa, 0xbb, 0xcc),
                     TAG_DONE);
      RectFill(rp, 0, 0, WIDTH - 1, HEIGHT - 1);
 
 
      /* Draw filled ellipse to cookiebm */
      SetRast(cookierp, 0);
      DrawEllipse(cookierp, xmid, ymid, 200, 200);
      Flood(cookierp, 0, xmid, ymid);
 
      /* Blast the cookie cut image to display */
      SetRPAttrs(rp, RPTAG_DrMd, JAM1,
                     RPTAG_PenMode, FALSE,
                     RPTAG_FgColor, MKRGB(222, 100, 70),
                     TAG_DONE);
      BltTemplate(cookiebm->Planes[0], 0,
                  GetBitMapAttr(cookiebm, BMA_WIDTH) / 8,
                  rp, 0, 0, WIDTH, HEIGHT);
 
 
      /* Draw filled box */
      SetRPAttrs(rp, RPTAG_PenMode, FALSE,
                     RPTAG_FgColor, MKRGB(40, 70, 90),
                     TAG_DONE);
      RectFill(rp, xmid - 100, ymid - 100, xmid + 100, ymid + 100);
 
 
      /* Put some text on screen, too */
      SetRPAttrs(rp, RPTAG_DrMd, JAM1,
                     RPTAG_PenMode, FALSE,
                     RPTAG_FgColor, MKRGB(255, 244, 244),
                     TAG_DONE);
      txt = "MorphOS rules!";
      len = strlen(txt);
      Move(rp, xmid - TextLength(rp, txt, len) / 2, ymid);
      Text(rp, txt, len);
 
      /* Wait a bit */
      Delay(5 * 50);
 
      ret = RETURN_OK;
 
      FreeBitMap(cookiebm);
    }
    else Printf("no memory for %lux%lux1 cookie bitmap\n",
                 WIDTH, HEIGHT);
 
    CloseScreen(scr);
  }
  else Printf("could not open %lux%lux%lu screen\n",WIDTH, HEIGHT, DEPTH);
 
  return ret;
}



Reference[edit]

ImageClass[edit]

You create a new boopsi class which is subclass of Intuition's IMAGECLASS (like this bitmap class) and in the IM_DRAW method you do the painting in whatever way you want. If you have some Bitmap from the datatype object use that with BltBitMapRastPort(), if you have some chunky pixel array, use WritePixelArray().

See compiler/coolimages/imageclass.c

Objects created from classes derived from IMAGECLASS can be passed to DrawImage(). from Converting struct BitMap into struct Image


If using native format bitmaps for the gfx hardware but how can it ensure they have Alpha? And since its impossible to lock access to the bitmap in most drivers how can it get access to the raw array of pixel data to pass into the Alpha functions in AROS? the pixfmt to use with the function can easily be obtained from the bitmap but until theres some way to get the data to use its pointless.

All the normal blit operations should respect alpha anyhow - and apps should determine if they will use it by allocating bitmaps without alpha etc (since they should know if they support/need it or not).

All gadgets will be drawn using PutImageAlpha (slow) while if using BltNewImageSubImageRastPort as previous, an attempt is made to check if the subimage of bitmap has no alpha channel pixels and if yes, a regular bitmap copy (CopyBox) is being done (faster). The image conversion method it is checked whether a subimage has not alpha pixels and if yes this subimage is marked as "able to copy from bitmap" instead of using WritePixelArrayAlpha. As a solution is the following:

  • in the CreateNewImageContainerMatchingScreen function move the "transparency per subimage" test to main code path out of truecolor only
  • don't assume that in LUT case all subimages can be read from bitmap, but re-use results of "transparency per subimage" check

This way you will cover all cases with BltNewImageSubImageRastPort, because it will detect (->subimageinbm[i]) that some images can't be copied from *bitmap and have to be drawn using WritePixelArrayAlpha regardless if the screen is LUT or truecolor. This also means BltNewImageSubImageRastPortSimple can again be based on BltNewImageSubImageRastPort.

If you want to keep the background pattern, you should move the WritePixelArrayAlpha in place of the ClearScreen.

if (gfxdata)
{
WritePixelArrayAlpha (...);
}
else
{
SetRPAttrs(RP, RPTAG_BgColor, 0xFFFFFF, TAG_DONE); 
Move (rp,0,0);
ClearScreen (rp);
}

Also, note that ClearScreen() doesn't do what you seem to think it does - it does *not* clear the entire window, it clears from the current position, which since you haven't done a Move() after writing the text will be *after* where the text is located. ClearScreen only clears from the current cursor position to the lower right end. In order to clear the entire drawing area you have to do Move(0,0) first.




 AllocCModeListTagList -- get an exec list with requested modes.
 AllocCModeListTags -- Varargs stub for AllocCModeListTagList

        result = AllocCModeListTagList( TagItems )
        D0                               A1

        APTR AllocCModeListTagList( struct TagItem * );

        result = AllocCModeListTags( Tag1, ... )

        APTR AllocCModeListTags( Tag Tag1, ... );


Allocates a list structure which contains all requested modes (All nodes are of type CyberModeNode). See defines for more information about the structure of this nodes.

Tags available are:

 CYBRMREQ_MinWidth (ULONG) - The minimum display width to let the user choose. Default is 320.

 CYBRMREQ_MaxWidth (ULONG) - The maximum display width to let the user choose. Default is 1600.

 CYBRMREQ_MinHeight (ULONG) - The minimum display height to let the user choose. Default is 240.

 CYBRMREQ_MaxHeight (ULONG) - The maximum display height to let the user choose. Default is 1200.

 CYBRMREQ_MinDepth (UWORD) - The minimum display depth to let the user choose. Default is 8.

 CYBRMREQ_MaxDepth (UWORD) - The maximum display depth to let the user choose. Default is 32.

 CYBRMREQ_CModelArray (UWORD *) - Array of color models which should be available for screenmode selection. Currently supported colormodels are:

                         PIXFMT_LUT8
                         PIXFMT_RGB15
                         PIXFMT_BGR15
                         PIXFMT_RGB15PC
                         PIXFMT_BGR15PC
                         PIXFMT_RGB16
                         PIXFMT_BGR16
                         PIXFMT_RGB16PC
                         PIXFMT_BGR16PC
                         PIXFMT_RGB24
                         PIXFMT_BGR24
                         PIXFMT_ARGB32
                         PIXFMT_BGRA32
                         PIXFMT_RGBA32
 default is all colormodels available, nothing filtered

The result - 0 if no modes are available, a pointer to a exec list if there
                 are modes which fit your needs.

where A is AlphaChannel, R is Red, B is Blue, G is Green and the number is bits per...


BestCModeListTagList ()
BestCModeIDTagList( TagItems )
void FreeCModeList ( struct List * );


GetBitmapAttr()

CModeRequestTagList ()




ULONG GetCyberMapAttr(struct BitMap *bitMap, ULONG attribute) 

 attribute - a number telling cybergraphics which attribute of the bitmap should be returned:
 CYBRMATTR_XMOD        returns bytes per row of the supplied bitmap
 CYBRMATTR_BPPIX       returns number of bytes per pixel
 CYBRMATTR_PIXFMT      return the pixel format of the bitmap
 CYBRMATTR_WIDTH       return width of the bitmap in pixels
 CYBRMATTR_HEIGHT      return the height in lines
 CYBRMATTR_DEPTH       returns bits per pixel
 CYBRMATTR_ISCYBERGFX  returns TRUE if supplied bitmap is a CyberGraphics one
 CYBRMATTR_ISLINEARMEM returns TRUE if the related display buffer supports linear memory access

ULONG GetCyberIDAttr(ULONG attribute, ULONG DisplayModeID) 

 attribute - A number telling cybergraphics which attribute of the displaymode id should be returned:
 CYBRIDATTR_PIXFMT return the pixel format of the supplied screenmode id
 CYBRIDATTR_WIDTH  returns visible width in pixels
 CYBRIDATTR_HEIGHT returns visible height in lines
 CYBRIDATTR_DEPTH  returns bits per pixel
 CYBRIDATTR_BPPIX  returns bytes per pixel




ULONG ReadRGBPixel(struct RastPort *rp, UWORD x, UWORD y) 

LONG WriteRGBPixel(struct RastPort *rp, UWORD x, UWORD y, ULONG pixel) 

ULONG ReadPixelArray(IPTR dst, UWORD destx, UWORD desty, UWORD dstmod, struct RastPort *rp, UWORD srcx, 
                     UWORD srcy, UWORD width, UWORD height, UBYTE dstformat) 

        destRect - pointer to an array of pixels where to write the pixel
                   data to. The pixel format is specified in DestFormat
        (DestX,DestY) - starting point in the destination rectangle
        DestMod - The number of bytes per row in the destination rectangle.
        RastPort -  pointer to a RastPort structure
        (SrcX,SrcY) - starting point in the RastPort
        (SizeX,SizeY) - size of the rectangle that should be transfered
        DestFormat - pixel format in the destination rectangle
                    Currently supported formats are:

                    RECTFMT_RGB  3 bytes per pixel, one byte red, one blue
                                 and one byte green component

                    RECTFMT_RGBA 4 bytes per pixel, one byte red, one blue,
                                 one byte green component and the last
                                 byte is alpha channel information which
                                 is 0 if the board does not support alpha
                                 channel

                    RECTFMT_ARGB 4 bytes per pixel, one byte red, one blue,
                                 one byte green component and the first
                                 byte is alpha channel information. If the
                                 board does not support alpha channel a 
                                 0 is returned for alpha channel information


ULONG WritePixelArray(IPTR src, UWORD srcx, UWORD srcy, UWORD srcmod, struct RastPort *rp, UWORD destx, 
                      UWORD desty, UWORD width, UWORD height, UBYTE srcformat) 

ULONG MovePixelArray(UWORD SrcX, UWORD SrcY, struct RastPort *RastPort, UWORD DstX, UWORD DstY, 
                     UWORD SizeX, UWORD SizeY) 

ULONG InvertPixelArray(struct RastPort *rp, UWORD destx, UWORD desty, UWORD width, UWORD height) 

ULONG FillPixelArray(struct RastPort *rp, UWORD destx, UWORD desty, UWORD width, UWORD height, ULONG pixel) 





void DoCDrawMethodTagList(struct Hook *hook, struct RastPort *rp, struct TagItem *tags) 

void CVideoCtrlTagList(struct ViewPort *vp, struct TagItem *tags) 





IPTR LockBitMapTagList(IPTR bitmap, struct TagItem *tags) 

 Tags LBMI_WIDTH (ULONG *) - points to a longword which contains the bitmap                                       
                             width after a succesful call
      LBMI_HEIGHT (ULONG *) - points to a longword which contains the bitmap
                                height after a succesful call
        LBMI_DEPTH (ULONG *) - points to a longword which contains the bitmap
                               depth after a successful call
        LBMI_PIXFMT (ULONG *) - points to a longword which contains the used
                                pixel format.

                        Possibly returned colormodels are:

                        PIXFMT_LUT8
                        PIXFMT_RGB15
                        PIXFMT_BGR15
                        PIXFMT_RGB15PC
                        PIXFMT_BGR15PC
                        PIXFMT_RGB16
                        PIXFMT_BGR16
                        PIXFMT_RGB16PC
                        PIXFMT_BGR16PC
                        PIXFMT_RGB24
                        PIXFMT_BGR24
                        PIXFMT_ARGB32
                        PIXFMT_BGRA32
                        PIXFMT_RGBA32

        LBMI_BYTESPERPIX (ULONG *) - points to a longword which contains the
                                     amount of bytes per pixel data.
        LBMI_BYTESPERROW (ULONG *) - points to a longword which contains the
                                     number of bytes per row for one bitmap
                                     line
        LBMI_BASEADDRESS (ULONG *) - points to a longword which contains the
                                     bitmap base address. THIS ADDRESS IS ONLY
                                     VALID INSIDE OF THE LOCK/UNLOCKBITMAP
                                     CALL!!!!!!!!!

void UnLockBitMap(IPTR Handle) 

void UnLockBitMapTagList(IPTR Handle, struct TagItem *Tags) 



ULONG ExtractColor(struct RastPort *RastPort, struct BitMap *SingleMap, ULONG Colour, ULONG sX, ULONG sY, 
                   ULONG Width, ULONG Height) 

LONG ScalePixelArray(IPTR srcRect, UWORD SrcW, UWORD SrcH, UWORD SrcMod, struct RastPort *RastPort, 
                     UWORD DestX, UWORD DestY, UWORD DestW, UWORD DestH, UBYTE SrcFormat) 

LONG WriteLUTPixelArray(IPTR srcRect, UWORD SrcX, UWORD SrcY, UWORD SrcMod, struct RastPort *rp, 
                        IPTR CTable, UWORD DestX, UWORD DestY, UWORD SizeX, UWORD SizeY, UBYTE CTabFormat) 

ULONG WritePixelArrayAlpha(IPTR src, UWORD srcx, UWORD srcy, UWORD srcmod, struct RastPort *rp, 
                           UWORD destx, UWORD desty, UWORD width, UWORD height, ULONG globalalpha) 



void BltTemplateAlpha(IPTR src, LONG srcx, LONG srcmod, struct RastPort *rp, LONG destx, LONG desty, 
                      LONG width, LONG height) 




cybergraphics.library/AllocCModeListTagList cybergraphics.library/AllocCModeListTagList

   NAME
        AllocCModeListTagList -- get an exec list with requested modes.
        AllocCModeListTags -- Varargs stub for AllocCModeListTagList

   SYNOPSIS
        result = AllocCModeListTagList( TagItems )
        D0                               A1

        APTR AllocCModeListTagList( struct TagItem * );

        result = AllocCModeListTags( Tag1, ... )

        APTR AllocCModeListTags( Tag Tag1, ... );

   FUNCTION
        Allocates a list structure which contains all requested modes (All nodes
        are of type CyberModeNode). See defines for more information about the
        structure of this nodes.

   INPUTS
        TagItems - pointer to an optional tag list which may be used to
                   control the number of returned modes

   TAGS
        Tags available are:

        CYBRMREQ_MinWidth (ULONG) - The minimum display width to let the user
                        choose. Default is 320.

        CYBRMREQ_MaxWidth (ULONG) - The maximum display width to let the user
                        choose. Default is 1600.

        CYBRMREQ_MinHeight (ULONG) - The minimum display height to let the user
                        choose. Default is 240.

        CYBRMREQ_MaxHeight (ULONG) - The maximum display height to let the user
                        choose. Default is 1200.

        CYBRMREQ_MinDepth (UWORD) - The minimum display depth to let the user
                        choose. Default is 8.

        CYBRMREQ_MaxDepth (UWORD) - The maximum display depth to let the user
                        choose. Default is 32.

        CYBRMREQ_CModelArray (UWORD *) - Array of color models which should be
                        available for screenmode selection. Currently supported
                        colormodels are:
                         PIXFMT_LUT8
                         PIXFMT_RGB15
                         PIXFMT_BGR15
                         PIXFMT_RGB15PC
                         PIXFMT_BGR15PC
                         PIXFMT_RGB16
                         PIXFMT_BGR16
                         PIXFMT_RGB16PC
                         PIXFMT_BGR16PC
                         PIXFMT_RGB24
                         PIXFMT_BGR24
                         PIXFMT_ARGB32
                         PIXFMT_BGRA32
                         PIXFMT_RGBA32
                        default is all colormodels available, nothing filtered

   RESULT
        result - 0 if no modes are available, a pointer to a exec list if there
                 are modes which fit your needs.

   SEE ALSO
        FreeCModeList()

�cybergraphics.library/BestCModeIDTagList   cybergraphics.library/BestCModeIDTagList

   NAME
        BestCModeIDTagList -- calculate the best ModeID with given parameters
        BestCModeIDTags -- Varags stub for BestCModeIDTagList

   SYNOPSIS
        ID = BestCModeIDTagList( TagItems )
        D0                          A0

        ULONG BestCModeIDTagList( struct TagItem * );

        ID = BestCModeIDTags( Tag1, ...)

        ULONG BestCModeIDTags( Tag, ... );

   FUNCTION
        Returns the CyberGraphX displaymode ID which fits best for the parameters
        supplied in the TagList.

   INPUTS
        TagItems - pointer to an array of TagItems

   TAGS
        CYBRBIDTG_Depth (ULONG) - depth the returned ModeID must support
                                  Default is 8

        CYBRBIDTG_NominalWidth (UWORD),
        CYBRBIDTAG_NominalHeight (UWORD) - desired width and height the ModeID
                                           should have

        CYBRBIDTG_MonitorID (ULONG) - if multiple graphics boards are
                                      installed in the system, you can choose
                                      the desired one with this tag

                                Currently supported boards are:

                                        CVision64 [1]
                                        Piccolo [2]
                                        PicassoII [3]
                                        Spectrum [4]
                                        Domino [5]
                                        RetinaZ3/DraCoAltais [6]
                                        PiccoSD64 [7]
                                        A2410 [8]
                                        CVision3D [13] (V41)
                                        Inferno [14] (V41)
                                        PicassoIV [15] (V41)

        CYBRBIDTG_BoardName (STRPTR) - Specify the card name directly. For
                                example, pass "CVision3D" to get a
                                CyberVision64/3D board ID

   RESULT
        ID - id of the best mode to use, or INVALID_ID if a match could
             not be found.

   BUGS
        Older versions return displaymode ids with wrong depth if the
        desired color depth is not available.
        If you specify very small widths/heights (e.g. 50/20 icon size) this
        call returns INVALID_ID instead of the smallest available lowres
        ID 

�cybergraphics.library/CModeRequestTagList    cybergraphics.library/CModeRequestTagList

   NAME
        CModeRequestTagList -- get screenmode from user using a requester.
        CModeRequestTags -- Varargs stub for CModeRequestTagList

   SYNOPSIS
        result = CModeRequestTagList( Requester, TagItems )
        D0                                A0        A1

        LONG CModeRequestTagList( APTR, struct TagItem * );

        result = CModeRequestTags( Requester, Tag1, ... )

        LONG CModeRequestTags( APTR, Tag, ...);

   FUNCTION
        Prompts the user for input by showing all available CyberGraphX
        screenmodes in a requester.
        If the user cancels or the system aborts the request, FALSE is returned,
        otherwise the displaymode id of the selected screenmode.

   INPUTS
        Requester - not used currently. You have to set it to NULL!
        TagItems - pointer to an optional tag list which may be used to
                   control features of the requester

   TAGS
        Tags used for the screen mode requester

        CYBRMREQ_Screen (struct Screen *) - Screen on which to open the requester.
                        default locale will be used.

        CYBRMREQ_WinTitle (STRPTR) - Title to use for the requesting window.

        CYBRMREQ_OKText (STRPTR) - Label of the positive gadget in the
                        requester. English default is "OK".

        CYBRMREQ_CancelText (STRPTR) - Label of the negative gadget in the
                        requester. English default is "Cancel".

        CYBRMREQ_MinWidth (ULONG) - The minimum display width to let the user
                        choose. Default is 320.

        CYBRMREQ_MaxWidth (ULONG) - The maximum display width to let the user
                        choose. Default is 1600.

        CYBRMREQ_MinHeight (ULONG) - The minimum display height to let the user
                        choose. Default is 240.

        CYBRMREQ_MaxHeight (ULONG) - The maximum display height to let the user
                        choose. Default is 1200.

        CYBRMREQ_MinDepth (UWORD) - The minimum display depth to let the user
                        choose. Default is 8.

        CYBRMREQ_MaxDepth (UWORD) - The maximum display depth to let the user
                        choose. Default is 32.

        CYBRMREQ_CModelArray (UWORD *) - Array of color models which should
                        be available for screenmode selection. Currently
                        supported colormodels are:

                        PIXFMT_LUT8
                        PIXFMT_RGB15
                        PIXFMT_BGR15
                        PIXFMT_RGB15PC
                        PIXFMT_BGR15PC
                        PIXFMT_RGB16
                        PIXFMT_BGR16
                        PIXFMT_RGB16PC
                        PIXFMT_BGR16PC
                        PIXFMT_RGB24
                        PIXFMT_BGR24
                        PIXFMT_ARGB32
                        PIXFMT_BGRA32
                        PIXFMT_RGBA32

                        default is all colormodels available, nothing filtered

   RESULT
        result - 0 if the user cancelled the requester or if something
                 prevented the requester from opening. If!= 0 the displaymode
                 id of the selected screenmode is returned.

   BUGS
        The requester structure is not supported.

   NOTES
        You should better use asl.library/AslRequest() instead.

�cybergraphics.library/CVideoCtrlTagList cybergraphics.library/CVideoCtrlTagList

   NAME
        CVideoCtrlTagList -- Control video output
        CVideoCtrlTags -- Varargs stub for CVideoCtrlTagList

   SYNOPSIS
        CVideoCtrlTagList( ViewPort, TagItems )
                              A0        A1

        void CVideoCtrlTagList( struct ViewPort *, struct TagItem * );

        CVideoCtrlTags( ViewPort, Tag1, ... )

        void CVideoCtrlTags( struct ViewPort *, Tag tag1, ... );

   FUNCTION
        This function controls the video output of the gfx board to which the
        specified ViewPort belongs to.

   INPUTS
        ViewPort - pointer to a ViewPort of a CyberGraphX screen
        TagItems - taglist to control operation

   TAGS

        SETVC_DPMSLevel (ULONG)  Set the DPMS level for the specified viewport
                Supported levels are:
                 DPMS_ON        Full operation
                 DPMS_STANDBY   Optional state of minimal power reduction
                 DPMS_SUSPEND   Significant reduction of power consumption
                 DPMS_OFF       Lowest level of power consumption

   EXAMPLE
        CVideoCtrlTags (&Scr->ViewPort,SETVC_DPMSLevel,DPMS_OFF,TAG_DONE);
        /* set DPMS level */

   NOTES
        Some DPMS levels are not implemented for certain graphics cards


�cybergraphics.library/DoCDrawMethodTagList cybergraphics.library/DoCDrawMethodTagList

   NAME
        DoCDrawMethodTagList -- Do the given hook for the supplied rastport
        DoCDrawMethodTags -- Varargs stub for DoCDrawMethodTagList

   SYNOPSIS
        DoCDrawMethodTagList( Hook, RastPort, TagItems )
                               A0      A1        A2

        void DoCDrawMethodTagList( struct Hook *, struct RastPort *,
                                   struct TagItem * )

        DoCDrawMethodTags( Hook, RastPort, Tag1, ... )

        void DoCDrawMethodTags( struct Hook *, struct RastPort *,
                                Tag1, ... )

   FUNCTION
        This function will call the given hook for the given rastport. Is is
        mainly used to do direct bitmap modifications in a locked graphics
        environment. You have to support ALL known color models, so only use
        this call if you really need it!!
        

   INPUTS
        Hook - pointer to callback hook which will be called
               with object == (struct RastPort *)
               and message == [ (APTR) memptr,
                                (ULONG) offsetx, (ULONG) offsety,
                                (ULONG) xsize, (ULONG) ysize,
                                (UWORD) bytesperrow, (UWORD) bytesperpix,
                                (UWORD) colormodel]
               Where colormodel is one of the following:
                        PIXFMT_LUT8
                        PIXFMT_RGB15
                        PIXFMT_BGR15
                        PIXFMT_RGB15PC
                        PIXFMT_BGR15PC
                        PIXFMT_RGB16
                        PIXFMT_BGR16
                        PIXFMT_RGB16PC
                        PIXFMT_BGR16PC
                        PIXFMT_RGB24
                        PIXFMT_BGR24
                        PIXFMT_ARGB32
                        PIXFMT_BGRA32
                        PIXFMT_RGBA32
        RastPort- A pointer to a cybergraphics RastPort
        TagItems - optional taglist, currently not used. Set it to NULL!

   NOTES
        Use this call only if you want high speed. Keep in mind that you have
        to handle all color models! Do not use ANY os functions in your hook.
        They would cause unpredictable results.

   BUGS
        In previous autodocs, the bytesperrow message field was described as
        an (ULONG) which in fact was an (UWORD). 

   SEE ALSO
        LockBitMap(), LockBitMapTagList()

�cybergraphics.library/FreeCModeList       cybergraphics.library/FreeCModeList

   NAME
        FreeCModeList -- frees a previously allocated ModeList

   SYNOPSIS
        FreeCModeList( ModeList );
                          A0

        void FreeCModeList( struct List * );

   FUNCTION
        frees all data which was previously allocated by AllocCModeListTagList()

   INPUTS
        ModeList - a list structure which contains all the mode data.

   SEE ALSO
        AllocCModeListTagList()

�cybergraphics.library/GetCyberMapAttr    cybergraphics.library/GetCyberMapAttr

   NAME
        GetCyberMapAttr -- Returns information about a cybergraphics bitmap

   SYNOPSIS
        value = GetCyberMapAttr( BitMap, Attribute );
         D0                        A0       D0

        ULONG GetCyberMapAttr( struct BitMap *, ULONG );

   FUNCTION
        Gets information about an extended cybergraphics bitmap.
        This function should be used instead of making any assumptions about
        fields in the bitmap structure. This will provide future
        compatibility.

   INPUTS
        BitMap - pointer to a cybergraphics bitmap structure

        Attribute - a number telling cybergraphics which attribute
                    of the bitmap should be returned:

                    CYBRMATTR_XMOD        returns bytes per row of the
                                          supplied bitmap

                    CYBRMATTR_BPPIX       returns number of bytes per pixel

                    CYBRMATTR_PIXFMT      return the pixel format of the
                                          bitmap

                    CYBRMATTR_WIDTH       return width of the bitmap in
                                          pixels

                    CYBRMATTR_HEIGHT      return the height in lines

                    CYBRMATTR_DEPTH       returns bits per pixel

                    CYBRMATTR_ISCYBERGFX  returns TRUE if supplied bitmap is
                                          a CyberGraphX one

                    CYBRMATTR_ISLINEARMEM returns TRUE if the related display
                                          buffer supports linear memory access

   NOTES
        Unknown attributes are reserved for future use, and return (-1L).

        You should know what you are doing if you call this function!
        Always use the CYBRMATTR_ISCYBERGFX attribute first to check if the
        bitmap is a CyberGraphX one.

   SEE ALSO
        graphics.library/GetBitMapAttr()

�cybergraphics.library/GetCyberIDAttr    cybergraphics.library/GetCyberIDAttr

   NAME
        GetCyberIDAttr -- Returns information about a cybergraphics id

   SYNOPSIS
        value = GetCyberIDAttr( Attribute, DisplayModeID )
          D0                       D0            D1

        ULONG GetCyberIDAttr( ULONG, ULONG );

   FUNCTION
        Returns information about a specified displaymode id.

   INPUTS
        Attribute - A number telling cybergraphics which attribute
                    of the displaymode id should be returned:

                    CYBRIDATTR_PIXFMT return the pixel format of the supplied
                                      screenmode id

                    CYBRIDATTR_WIDTH  returns visible width in pixels
                    CYBRIDATTR_HEIGHT returns visible height in lines
                    CYBRIDATTR_DEPTH  returns bits per pixel
                    CYBRIDATTR_BPPIX  returns bytes per pixel

        DisplayModeID - CyberGraphX displaymode id

   NOTES
        Unknown attributes are reserved for future use, and return (-1L).

        You should know what you are doing if you call this function!
        Don't apply it on a non cybergraphics displaymode!

�cybergraphics.library/IsCyberModeID       cybergraphics.library/IsCyberModeID

   NAME
        IsCyberModeID -- returns whether supplied ModeID is a cybergraphics id

   SYNOPSIS
        result = IsCyberModeID( DisplayModeID )
        D0                            D0

        BOOL IsCyberModeID( ULONG );

   FUNCTION
        returns whether the supplied ModeID is a cybergraphics.library mode
        identifier (TRUE) or not (FALSE).

   INPUTS
        DisplayModeID -- a 32 bit display identifier.

   RESULT
        result - Flag to indicate if DisplayModeID is a CyberGraphX id

�cybergraphics.library/ExtractColor          cybergraphics.library/ExtractColor

   NAME
        ExtractColor -- Extract the specified colour/CLUT value from a given
                CyberGraphX RastPort into a single plane bitmap starting at
                a certain x,y location and using the specified width and
                height. (V41)

   SYNOPSIS
        result = ExtractColor(RastPort,SingleMap,Colour,sX,sY, Width, Height)
        D0                     A0         A1      D0   D1 D2   D3      D4
                        

        LONG ExtractColor(struct RastPort *,struct BitMap *,ULONG, ULONG,
                                ULONG, ULONG, ULONG );

   FUNCTION
        ExtractColor -- Extract the specified colour/CLUT value from a given
                CyberGraphX RastPort into a single plane bitmap starting at
                a certain x,y location and using the specified width and
                height. Use this function if you want to create masks.
                (V41)

   INPUTS
        RastPort -  pointer to a CyberGraphX RastPort structure

        SingleMap - planar destination bitmap that has at least a depth of
                one and the minimum width and height specified.

        Colour - the color that should be extracted in AARRGGBB format for
                true color rastports or in indexed mode for CLUT rastports.
                The ULONG coding is as follows (for rgb screens):
                 AA - 8-bit alpha channel component
                      (set it to 00 if you do not use it!)
                 RR - 8-bit red component of the pixel
                 GG - 8-bit green component
                 BB - 8-bit blue component

                For CLUT rastports only the lowest byte is used as an index
                value to a 256 colour lookup table
                
        sX,sY - starting point in the RastPort that should be analyzed
        Width,Height - size of the rectangle that should be analyzed

   RESULT
        result - returns TRUE if colour could be extraced, FALSE if not

   NOTES
        This call was a no-op in very early revisions of cybergraphics v41

�cybergraphics.library/FillPixelArray     cybergraphics.library/FillPixelArray

   NAME
        FillPixelArray -- fill a rectangular area with the supplied ARGB value
        starting at a specified x,y location and continuing through to another
        x,y location within a certain RastPort

   SYNOPSIS
        count = FillPixelArray(RastPort,DestX, DestY,SizeX,SizeY,ARGB)
        D0                        A1    D0:16  D1:16 D2:16 D3:16 D4:32
                        

        LONG FillPixelArray( struct RastPort *, UWORD, UWORD,
                             UWORD, UWORD, ULONG );

   FUNCTION
        For each pixel in a rectangular region, write the supplied color value
        into the bitmap used to describe a particular rastport.

   INPUTS
        RastPort -  pointer to a RastPort structure
        (DestX,DestY) - starting point in the RastPort
        (SizeX,SizeY) - size of the rectangle that should be transfered
        ARGB  - the desired color in AARRGGBB format for true color rastports
                or in indexed mode for CLUT rastports. Every component
                uses 8 bits in the supplied longword. The coding is as
                follows (for rgb screens):
                 AA - 8-bit alpha channel component
                      (set it to 00 if you do not use it!)
                 RR - 8-bit red component of the pixel
                 GG - 8-bit green component
                 BB - 8-bit blue component

                For CLUT rastports only the blue component is used as an
                index value to a 256 colour lookup table
                

   RESULT
        count will be set to the number of pixels plotted

   NOTES
        This function should only be used on screens depths > 8 bits in
        cybergraphics versions prior v41.

   BUGS
        The returned count value is wrong up to and including v41 of the
        cybergraphics.library

   SEE ALSO
        InvertPixelArray()
�cybergraphics.library/InvertPixelArray   cybergraphics.library/InvertPixelArray

   NAME
        InvertPixelArray -- invert a rectangular area

   SYNOPSIS
        count = InvertPixelArray(RastPort,DestX, DestY,SizeX,SizeY)
        D0                         A1     D0:16  D1:16 D2:16 D3:16
                        

        LONG InvertPixelArray( struct RastPort *, UWORD, UWORD,
                               UWORD,UWORD );

   FUNCTION
        Invert each pixel in a rectangular region.

   INPUTS
        RastPort -  pointer to a RastPort structure
        (DestX,DestY) - starting point in the RastPort
        (SizeX,SizeY) - size of the rectangle that should be transfered

   RESULT
        count will be set to the number of pixels plotted

   NOTES
        This function should only be used on screens depths > 8 bits with
        cybergraphics versions prior v41.

   BUGS
        The count value returned is totally wrong.

   SEE ALSO
        FillPixelArray()
�cybergraphics.library/LockBitmapTagList cybergraphics.library/LockBitMapTagList

   NAME
        LockBitMapTagList -- Lock supplied BitMap for a short amount of time
                             to allow direct memory access

   SYNOPSIS
        handle = LockBitmapTagList(bitmap,tags);
        D0                           A0    A1

        APTR LockBitMapTagList( APTR,struct TagItem * );

        APTR LockBitMapTags( APTR,Tag1, ... );

   FUNCTION

   INPUTS
        bitmap - pointer to a CyberGraphX bitmap pointer. please check if it is
                 a cybermap by calling GetCyberMapAttr() first.
        tags - pointer to a mandatory taglist which's tagdata pointer fields
               contain valid longwords after a successful call.

   TAGS
        Tags used for the screen mode requester

        LBMI_WIDTH (ULONG *) - points to a longword which contains the bitmap
                               width after a succesful call
        LBMI_HEIGHT (ULONG *) - points to a longword which contains the bitmap
                                height after a succesful call
        LBMI_DEPTH (ULONG *) - points to a longword which contains the bitmap
                               depth after a successful call
        LBMI_PIXFMT (ULONG *) - points to a longword which contains the used
                                pixel format.

                        Possibly returned colormodels are:

                        PIXFMT_LUT8
                        PIXFMT_RGB15
                        PIXFMT_BGR15
                        PIXFMT_RGB15PC
                        PIXFMT_BGR15PC
                        PIXFMT_RGB16
                        PIXFMT_BGR16
                        PIXFMT_RGB16PC
                        PIXFMT_BGR16PC
                        PIXFMT_RGB24
                        PIXFMT_BGR24
                        PIXFMT_ARGB32
                        PIXFMT_BGRA32
                        PIXFMT_RGBA32

        LBMI_BYTESPERPIX (ULONG *) - points to a longword which contains the
                                     amount of bytes per pixel data.
        LBMI_BYTESPERROW (ULONG *) - points to a longword which contains the
                                     number of bytes per row for one bitmap
                                     line
        LBMI_BASEADDRESS (ULONG *) - points to a longword which contains the
                                     bitmap base address. THIS ADDRESS IS ONLY
                                     VALID INSIDE OF THE LOCK/UNLOCKBITMAP
                                     CALL!!!!!!!!!


   RESULT
        handle - 0 if the bitmap could not be locked,!= 0 it contains a handle
                 which should be passed to UnLockBitMap afterwards

   NOTES
        Only use this call if you really NEED the rendering speed, DON'T lock the
        bitmap longer than for one frame. DON'T use any library calls while the
        bitmap is locked! This function is considered low level.

   BUGS
        The LBMI_DEPTH tagitem pointer will always contain 8 even for deeper
        bitmaps. Use GetCyberMapAttr() or graphics.library/GetBitMapAttr() to
        get the correct depth.

   SEE ALSO
        UnLockBitMap(), UnLockBitMapTagList()

�cybergraphics.library/MovePixelArray     cybergraphics.library/MovePixelArray

   NAME
        MovePixelArray -- move the color values of a rectangular area of
        pixels starting at a specified x,y location and continuing through
        to another x,y location within a certain RastPort

   SYNOPSIS
        count = MovePixelArray(SrcX, SrcY, RastPort,DstX , DstY ,SizeX, SizeY)
        D0                     D0:16 D1:16  A1      D2:16  D3:16 D4:16  D5:16

        LONG MovePixelArray(UWORD,UWORD,struct RastPort *,UWORD,UWORD,UWORD,
                                UWORD)

   FUNCTION
        For each pixel in a rectangular region, move the pixel value from a
        specified source to a specified destination

   INPUTS
        (SrcX,SrcY) - starting point in the source rectangle
        RastPort -  pointer to a RastPort structure
        (DestX,DestY) - starting point in the destination rectangle
        (SizeX,SizeY) - size of the rectangle that should be transfered

   RESULT
        count will be set to the number of pixels moved

   NOTES
        This function should only be used on screens depths > 8 bits with
        cybergraphics versions up to v40.
        The blitter can be used to move the data if the bitmap is in display
        memory. This is why you should use this call.

   BUGS
        The count value returned is totally wrong.

   SEE ALSO
        FillPixelArray(), InvertPixelArray(),
        graphics.library/BltBitMapRastPort()
�cybergraphics.library/ReadPixelArray     cybergraphics.library/ReadPixelArray

   NAME
        ReadPixelArray -- Read the color values of a rectangular array of
        pixels starting at a specified x,y location and continuing through
        to another x,y location within a certain RastPort

   SYNOPSIS
        count = ReadPixelArray(destRect,DestX,DestY,DestMod,RastPort,SrcX ,
        D0                        A0    D0:16 D1:16 D2:16     A1     D3:16
                                SrcY ,SizeX,SizeY,DestFormat)
                                D4:16 D5:16 D6:16    D7

        LONG ReadPixelArray(APTR,UWORD,UWORD,UWORD,struct RastPort *,UWORD,
                            UWORD,UWORD,UWORD,UBYTE)

   FUNCTION
        For each pixel in a rectangular region, write the color value to a
        linear array of color values from the bitmap used to describe a
        particular rastport.

   INPUTS
        destRect - pointer to an array of pixels where to write the pixel
                   data to. The pixel format is specified in DestFormat
        (DestX,DestY) - starting point in the destination rectangle
        DestMod - The number of bytes per row in the destination rectangle.
        RastPort -  pointer to a RastPort structure
        (SrcX,SrcY) - starting point in the RastPort
        (SizeX,SizeY) - size of the rectangle that should be transfered
        DestFormat - pixel format in the destination rectangle
                    Currently supported formats are:

                    RECTFMT_RGB  3 bytes per pixel, one byte red, one blue
                                 and one byte green component

                    RECTFMT_RGBA 4 bytes per pixel, one byte red, one blue,
                                 one byte green component and the last
                                 byte is alpha channel information which
                                 is 0 if the board does not support alpha
                                 channel

                    RECTFMT_ARGB 4 bytes per pixel, one byte red, one blue,
                                 one byte green component and the first
                                 byte is alpha channel information. If the
                                 board does not support alpha channel a 
                                 0 is returned for alpha channel information

   RESULT
        count will be set to the number of pixels read

   NOTES
        This function should only be used on screens depths > 8 bits.

   BUGS
        The count value returned is totally wrong.

   SEE ALSO
        WritePixelArray(), graphics.library/ReadPixelArray8()

�cybergraphics.library/ReadRGBPixel          cybergraphics.library/ReadRGBPixel

   NAME
        ReadRGBPixel -- Reads a pixel from a specified location

   SYNOPSIS
        color = ReadRGBPixel(RastPort,x ,y )
        D0                     A1     D0 D1

        ULONG ReadRGBPixel(struct RastPort *,UWORD,UWORD);

   FUNCTION
        Read the alpha,red,green & blue 8-bit color components of the pixel at
        a specified x,y location within a certain RastPort

   INPUTS
        rp -  pointer to a RastPort structure
        x,y    - the coordinates of the pixel

   RESULT
        color  - the desired color in AARRGGBB format. Every component
                 allocates 8 bits in the returned longword. The coding is as
                 follows:

                 AA - 8-bit alpha channel component
                      (boards which do not have an alpha channel return 00)
                 RR - 8-bit red component of the pixel
                 GG - 8-bit green component
                 BB - 8-bit blue component

  NOTES
        This function should only be used on screens depths > 8 bits. Use
        ReadPixel() on 8 bit screens!

  SEE ALSO
        WriteRGBPixel()
�cybergraphics.library/ScalePixelArray   cybergraphics.library/ScalePixelArray

   NAME
       ScalePixelArray -- Scale the colors values of a rectangular array of
        pixels starting at a specified x,y location and continuing through
        to another x,y location within a certain RastPort (V41)

   SYNOPSIS
        count = ScalePixelArray(srcRect,SrcW,SrcH ,SrcMod,RastPort,DestX,
        D0                         A0   D0:16 D1:16 D2:16     A1    D3:16
                                DestY,DestW,DestH,SrcFormat)
                                D4:16 D5:16 D6:16    D7

        LONG ScalePixelArray(APTR,UWORD,UWORD,UWORD,struct RastPort *,UWORD,
                             UWORD,UWORD,UWORD,UBYTE)

   FUNCTION
        For each pixel in a rectangular region, scale the color values from a
        linear array of color values into the bitmap used to describe a
        particular rastport.

   INPUTS
        srcRect - pointer to an array of pixels from which to fetch the
                  pixel data. The pixel format is specified in SrcFormat
        (SrcW,SrcH) - Width and Height of the source rectangle
        SrcMod - The n umber of bytes per row in the source rectangle.
        RastPort -  pointer to a RastPort structure
        (DestX,DestY) - starting point in the RastPort
        (DestW,DestH) - size of the destination area
        SrcFormat - pixel format in the source rectangle
                    Currently supported formats are:

                    RECTFMT_RGB  3 bytes per pixel, one byte red, one blue
                                 and one byte green component

                    RECTFMT_RGBA 4 bytes per pixel, one byte red, one blue,
                                 one byte green component and the last
                                 byte is alpha channel information. If you
                                 do not use alpha channel set this byte to
                                 0!!!

                    RECTFMT_ARGB 4 bytes per pixel, one byte red, one blue,
                                 one byte green component and the first
                                 byte is alpha channel information. If you
                                 do not use alpha channel set this byte to
                                 0!!!

                    RECTFMT_LUT8  1 byte per pixel, specifying the pen
                                  number. On screen depths > 8 bits the
                                  data is converted using the actual color
                                  lookup table.

                    RECTFMT_GREY8 1 byte per pixel, specifying grey scale
                                  value.
   RESULT
        count will be set to the number of pixels plotted

   NOTES
        Up to v40, this function only worked on screens depths > 8 bits.
        You may specify RECTFMT_LUT8 on 8bit screens, too now if v41 is
        available

   BUGS
        Very early v40 revision did not support RECTFMT_LUT8 and
        RECTFMT_GREY8.
        Scaling is not very accurate. If you need high quality, use
        graphics.library/BitMapScale() instead or custom code.
        The count value returned is totally wrong.

   SEE ALSO
        graphics.library/BitMapScale()

�cybergraphics.library/WriteLUTPixelArray      cybergraphics/WriteLUTPixelArray

   NAME
        WriteLUTPixelArray -- write the color value generated from a given
        color table of a rectangular array of pixels starting at a specified
        x,y location and continuing through to another x,y location within
        a certain RastPort (V41)

   SYNOPSIS
        count = WriteLUTPixelArray(srcRect,SrcX ,SrcY ,SrcMod,RastPort,
        D0                            A0   D0:16 D1:16 D2:16     A1
                        CTable,DestX,DestY,SizeX,SizeY,CTabFormat)
                          A2   D3:16 D4:16 D5:16 D6:16      D7

        LONG WriteLUTPixelArray(APTR,UWORD,UWORD,UWORD,struct RastPort *,APTR,
                             UWORD, UWORD,UWORD,UWORD,UBYTE)

   FUNCTION
        For each pixel in a rectangular region, write the color value
        generated with a given color lookup table from a linear array of
        indexed pixel values into the bitmap used to describe a particular
        rastport.

   INPUTS
        srcRect - pointer to an array of pixels from which to fetch the
                  CLUT data. Pixels are specified in bytes, 8bits/pixel.
        (SrcX,SrcY) - starting point in the source rectangle
        SrcMod - The number of bytes per row in the source rectangle.
        RastPort -  pointer to a RastPort structure
        CTable - pointer to the color table using the format specified
                with CTabFormat
        (DestX,DestY) - starting point in the RastPort
        (SizeX,SizeY) - size of the rectangle that should be transfered
        CTabFormat - color table format in the source rectangle
                Currently supported formats are:
                 CTABFMT_XRGB8 - CTable is a pointer to a ULONG table
                        which contains 256 entries. Each entry specifies the
                        rgb colour value for the related index. The format
                        is XXRRGGBB.

                         XX - unused
                         RR - 8-bit red component of the pixel
                         GG - 8-bit green component
                         BB - 8-bit blue component

    
   RESULT
        count will be set to the number of pixels plotted

   NOTES
        Does only work on rastports with depth > 8bits

   BUGS
        The count value returned is totally wrong.
        With cgxsystem.library up to version 41.19, the call returns
        immediately with CTABFMT_XRGB8 due to a bug in the code

   SEE ALSO
        ReadPixelArray(), WritePixelArray(), 
        graphics.library/WritePixelArray8()

�cybergraphics.library/WritePixelArray   cybergraphics.library/WritePixelArray

   NAME
        WritePixelArray -- write the color value of a rectangular array of
        pixels starting at a specified x,y location and continuing through
        to another x,y location within a certain RastPort

   SYNOPSIS
        count = WritePixelArray(srcRect,SrcX ,SrcY ,SrcMod,RastPort,DestX,
        D0                         A0   D0:16 D1:16 D2:16     A1    D3:16
                                DestY,SizeX,SizeY,SrcFormat)
                                D4:16 D5:16 D6:16    D7

        LONG WritePixelArray(APTR,UWORD,UWORD,UWORD,struct RastPort *,UWORD,
                             UWORD,UWORD,UWORD,UBYTE)

   FUNCTION
        For each pixel in a rectangular region, write the color value from a
        linear array of color values into the bitmap used to describe a
        particular rastport.

   INPUTS
        srcRect - pointer to an array of pixels from which to fetch the
                  pixel data. The pixel format is specified in SrcFormat
        (SrcX,SrcY) - starting point in the source rectangle
        SrcMod - The number of bytes per row in the source rectangle.
        RastPort -  pointer to a RastPort structure
        (DestX,DestY) - starting point in the RastPort
        (SizeX,SizeY) - size of the rectangle that should be transfered
        SrcFormat - pixel format in the source rectangle
                    Currently supported formats are:

                    RECTFMT_RGB   3 bytes per pixel, one byte red, one blue
                                  and one byte green component

                    RECTFMT_RGBA  4 bytes per pixel, one byte red, one
                                  blue, one byte green component and the
                                  last byte is alpha channel information.
                                  If you do not use alpha channel set this
                                  byte to 0!!!

                    RECTFMT_ARGB  4 bytes per pixel, one byte red, one
                                  blue, one byte green component and the
                                  first byte is alpha channel information.
                                  If you do not use alpha channel set this
                                  byte to 0!!!

                    RECTFMT_LUT8  1 byte per pixel, specifying the pen
                                  number. On screen depths > 8 bits the
                                  data is converted using the actual color
                                  lookup table.

                    RECTFMT_GREY8 1 byte per pixel, specifying grey scale
                                  value.

   RESULT
        count will be set to the number of pixels plotted

   NOTES
        Only RECTFMT_LUT8 can be used on screen depths <= 8 bits.
        For > 8 bit rastport RECTFMT_LUT8 uses the actual colormap "attached"
        to the bitmap. If the bitmap is a friend bitmap of a screen bitmap
        or the screen bitmap itself, it uses the screen's viewport colormap.
        
   BUGS
        The count value returned is totally wrong.

   SEE ALSO
        ReadPixelArray(), WriteLUTPixelArray(),
        graphics.library/WritePixelArray()

�cybergraphics.library/WriteRGBPixel        cybergraphics.library/WriteRGBPixel

   NAME
        WriteRGBPixel -- Writes a pixel to a specified location

   SYNOPSIS
        error = WriteRGBPixel(RastPort,x ,y ,color)
        D0                      A1     D0 D1 D2

        ULONG WriteRGBPixel(struct RastPort *,UWORD,UWORD,ULONG);

   FUNCTION
        Write the alpha,red,green and blue 8-bit color component of the given
        color to a specified x,y location within a certain RastPort

   INPUTS
        rp     - pointer to a RastPort structure
        x,y    - the coordinates of the pixel
        color  - the desired color in AARRGGBB format. Every component
                 allocates 8 bits of the returned longword. The coding is as
                 follows:

                 AA - 8-bit alpha channel component
                      (set it to 00 if you dont want to use it!)
                 RR - 8-bit red component of the pixel
                 GG - 8-bit green component
                 BB - 8-bit blue component

   RESULT
        error = 0 if pixel succesfully changed
              = -1 if (x,y) is outside the rastport

   NOTES
        This function should only be used on screens depths > 8 bits. Use
        WritePixel() on 8 bit screens!

   SEE ALSO
        ReadRGBPixel(), graphics.library/WritePixel()

�cybergraphics.library/UnLockBitmap           cybergraphics.library/UnLockBitMap

   NAME
        UnLockBitMap -- Unlock CyberGraphX BitMap that was previously locked

   SYNOPSIS
        UnLockBitmap( Handle )
                        A0

        void UnLockBitMap( APTR );

   FUNCTION
        Unlock CyberGraphX BitMap that was previously locked

   INPUTS
        handle - handle to the previously locked BitMap

   SEE ALSO
        LockBitMapTagList()

�cybergraphics.library/UnLockBitmapTagList    cybergraphics/UnLockBitMapTagList

   NAME
        UnLockBitMapTagList -- Unlock CyberGraphX BitMap that was previously
                locked
        UnLockBitMapTags -- Varargs stub for UnLockBitMapTagList

   SYNOPSIS
        UnLockBitmapTagList( Handle, Tags )
                              A0      A1

        void UnLockBitMapTagList( APTR, struct TagItem * );

        void UnLockBitMapTags( APTR, Tag1, ... );

   FUNCTION
        Unlock CyberGraphX BitMap that was previously locked

   INPUTS
        handle - handle to the previously locked BitMap

        Tags - pointer to a mandatory taglist
   TAGS
        UBMI_UPDATERECTS (struct RectList *) - pointer to a rectlist which
                contains rectangles that should be updated. This is needed for
                cards that don't have a linear display memory address space
                The RectList structure looks like this:
                        struct RectList
                        {
                         ULONG rl_num;             // no. of rects in this list
                         struct RectList *rl_next; // pointer to next list
                         struct Rectangle rect1;   // This is the first
                                ..                 // rectangle followed by
                                ..                 // rl_num-1 rectangles
                                ..
                        }
        UBMI_REALLYUNLOCK (BOOL) - Specifies whether bitmap should really be
                unlocked (TRUE) or not (FALSE) in case you just want to update
                certain rectangles and unlock later.

   BUGS
        Very early v40 revisions did not support this call

   SEE ALSO
        LockBitMapTagList(), UnLockBitMap()