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 Dev Docs
Aros Developer Docs
Porting Software from AmigaOS/SDL
For Zune Beginners
Zune .MUI Classes
For SDL Beginners
Aros Developer BuildSystem
Specific platforms
Aros Intel AMD 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
Motorola 68k Amiga Support
Linux and FreeBSD Support
Windows Mingw and MacOSX Support
Android Support
Arm Raspberry Pi Support
PPC Power Architecture
Aros Public License


Apart from RootClass, all classes that are written will inherit from this base class (rootclass). Your class must either implement the rootclass methods or defer processing of these methods to the next class.


The rootclass method IDs:

OM_NEW Create a new object.
OM_DISPOSE Delete an object.
OM_SET Change an object's attributes.
OM_GET Retrieve the value of one of the object's attributes.


gadgetclass has to understand these rootclass methods and introduces these

GM_HITTEST return GMR_GADGETHIT if you are clicked on
GM_RENDER draw yourself, in the appropriate state
GM_GOACTIVE you are now going to be fed input
GM_HANDLEINPUT handle that input
GM_GOINACTIVE whether or not by choice, you are done






Boopsi's imageclass is one of the standard classes built into Intuition. As its name implies, it is a class of Intuition Images. These boopsi images can be used in place of traditional Image structure (as they contain an Intuition Image structure), but they are much more powerful. By using boopsi methods, an application or Intuition can tell an imageclass object to render itself. Because it renders itself (rather than Intuition rendering it), the imageclass object is free to render whatever it wants (well, within reason). For example, a boopsi image object can render itself according to the current display resolution, or to scale itself to any size an application requests.

Imageclass defines several methods of its own which subclasses of imageclass either have to implement or pass on to their superclass.


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().

You can use objects from IMAGECLASS (or subclasses from IMAGECLASS) as GadgetRender (etc.) in gadgets (no matter if the gadget is old-style or boopsi). You can also cast the object to (struct Image *), because the instance data contains a struct Image at the beginning.

This new image class I'm talking about is not different to what you are already doing on AOS (using the Reaction/Classact bitmap.image class which is also a subclass of IMAGECLASS). AROS doesn't have that class so one would either need to write it (it's an external class similar to colorwheel.gadget), or write a simplified class reimplementation directly in your program == the new image class I mean which doesn't need to do much more than some blitting with BltBitMapRastPort() or similar in IM_DRAW (if you are already loading the image/datatype object elsewhere, otherwise you could also do the loading in the new image class's OM_NEW).





The following worked with a 4 color IFF image. I'm assuming that I can do CopyMem for the planes of a V42 datatype bitmap.

#include <proto/exec.h> 
#include <proto/dos.h> 
#include <proto/graphics.h> 
#include <proto/intuition.h> 
#include <proto/datatypes.h> 

#include <datatypes/pictureclass.h> 

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

static struct Window *window; 
static struct RastPort *win_rp; 

static struct Image *img; 

static struct Image *load_image(CONST_STRPTR); 
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,         "Load Image", 
        WA_Activate,      TRUE, 
        WA_SmartRefresh,  TRUE, 
        WA_NoCareRefresh, TRUE, 
        WA_GimmeZeroZero, TRUE, 
        WA_CloseGadget,   TRUE, 
        WA_DragBar,       TRUE, 
        WA_DepthGadget,   TRUE, 
    if (! window) clean_exit("Can't open windown"); 
    win_rp = window->RPort; 
    img = load_image("test.iff"); 
    DrawImage(win_rp, img, 50, 50); 



    return 0; 

static struct Image *load_image(CONST_STRPTR name) 
    struct Image *newimage = NULL; 
    UBYTE *pixeldata = NULL; 
    Object *dto = NULL; 
    struct BitMapHeader *bmh = NULL; 
    struct BitMap *bm = NULL; 
    WORD width, height, depth; 
    LONG size; 
    if ((dto = NewDTObject((APTR)name, 
        PDTA_Remap, FALSE, 
        PDTA_DestMode, PMODE_V42, 
        TAG_DONE)) == NULL) 
        puts("Can't open datatype"); 
        goto cleanup; 
    if (GetDTAttrs(dto, PDTA_BitMapHeader, &bmh, PDTA_BitMap, &bm, TAG_DONE) != 2) 
        puts("Can't get bitmapheader and bitmap"); 
        goto cleanup; 
    width = bmh->bmh_Width; 
    height = bmh->bmh_Height; 
    depth = bmh->bmh_Depth; 
    size = ((width + 16) / 16) * height * depth * 2; // Bytes 

    printf("width %d height %d depth %d size %dn", width, height, depth, size); 

    if ((pixeldata = AllocVec(size, MEMF_ANY)) == NULL) 
        puts("Can't allocate memory for pixeldata"); 
        goto cleanup; 

    if ((newimage = AllocVec(sizeof (struct Image), MEMF_ANY | MEMF_CLEAR)) == NULL) 
        puts("Can't allocate memory for struct Image"); 
        goto cleanup; 

    WORD blocksize = ((width + 16) / 16) * height * 2; 
    UBYTE *ptr = pixeldata; 
    UBYTE d; 

    for (d = 0; d < depth; d++) 
        CopyMem(bm->Planes[d], ptr, blocksize); 
        ptr += blocksize; 
    newimage->ImageData = pixeldata; 
    newimage->Width = width; 
    newimage->Height = height; 
    newimage->PlanePick = (1 << depth) - 1; 
    newimage->Depth = depth; 
    if (dto) DisposeDTObject(dto); 
    return newimage; 

    if (dto) DisposeDTObject(dto); 
    return NULL; 

static void handle_events(void) 
    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; 
            ReplyMsg((struct Message *)imsg); 

static void clean_exit(CONST_STRPTR s) 
    if (s) PutStr(s); 

    if (window) CloseWindow(window); 



must understand rootclass method IDs but also these

ICM_CHECKLOOP - to manage a loop inhibition for broadcasted messages.  They increment,
decrement, and return the value of that counter