OS 4'd Example: SuperBitmap

Report errors, omissions, etc. regarding the AmigaOS Documentation Wiki here.
Post Reply
dstastny
Posts: 48
Joined: Fri Dec 16, 2016 6:31 am
Location: Atlanta GA

OS 4'd Example: SuperBitmap

Post by dstastny »

I was reviewing SuperBitmap example here: http://wiki.amigaos.net/wiki/Window_Dis ... eservation

I cleaned it up example and made it geared towards OS4 and Reaction oriented for compiling straight with GCC.

Code: Select all

/* SuperBitmap Example
gcc -o lines lines.c 
*/

/**
 **  lines.c-- Window Super bitmap example.
 **
 **  
 **/

#include <dos/dos.h>
#include <intuition/icclass.h>
#include <classes/window.h>
#include <gadgets/scroller.h>
#include <gadgets/layout.h>

#include <proto/intuition.h>
#include <proto/exec.h>
#include <proto/utility.h>
#include <proto/layers.h>
#include <proto/graphics.h>



#define WIDTH_SUPER (800)
#define HEIGHT_SUPER (600)
#define MINWIDTH (150)
#define MINHEIGHT (150)


#define LAYERXOFFSET(x) (x->RPort->Layer->Scroll_X)
#define LAYERYOFFSET(x) (x->RPort->Layer->Scroll_Y)

enum
{
    WID_MAIN = 0,
    WID_LAST
};

enum
{
    OID_MAIN = 0,
    OID_VPROP,
    OID_HPROP,
    OID_LAST
};


struct IntuitionIFace *IIntuition;
struct GraphicsIFace *IGraphics;
struct LayersIFace *ILayers;
 

static struct Window *windows[WID_LAST];
static Object *objects[OID_LAST];
static struct Hook idcmphook;

/* Prototypes for our functions */

void initBorderProps(struct Screen *screen);
void doNewSize();
void doDrawStuff();
void doMsgLoop();
void superWindow(struct Screen *screen);
void slideBitMap(struct Window *win, int16 dX, int16 dY);

int main()
{
    struct Screen* screen;

    struct Library* IntuitionBase = IExec->OpenLibrary("intuition.library", 50);
    IIntuition = (struct IntuitionIFace*)IExec->GetInterface(IntuitionBase,
        "main", 1, NULL);

    struct Library* GfxBase = IExec->OpenLibrary("graphics.library", 50);
    IGraphics = (struct GraphicsIFace*)IExec->GetInterface(GfxBase, "main", 1, NULL);

    struct Library* LayersBase = IExec->OpenLibrary("layers.library", 50);
    ILayers = (struct LayersIFace*)IExec->GetInterface(LayersBase, "main", 1, NULL);

    if (IIntuition != NULL && IGraphics != NULL && ILayers != NULL) {
        if ((screen = IIntuition->LockPubScreen(NULL)) != NULL) {
            superWindow(screen);
            IIntuition->UnlockPubScreen(NULL, screen);
        }
    }

    IExec->DropInterface((struct Interface*)ILayers);
    IExec->CloseLibrary(LayersBase);

    IExec->DropInterface((struct Interface*)IGraphics);
    IExec->CloseLibrary(GfxBase);

    IExec->DropInterface((struct Interface*)IIntuition);
    IExec->CloseLibrary(IntuitionBase);

    return 0;
}


void IDCMPHook(struct Hook *hook,Object *object, struct IntuiMessage *msg)
{
    if (msg->Class == IDCMP_IDCMPUPDATE) {
        int16 dX = 0;
        int16 dY = 0;
        int32 pos;

        struct Window *win = windows[WID_MAIN];
        if (win != NULL) {
            uint32 gadgetid = IUtility->GetTagData(GA_ID, 0,(struct TagItem *)msg->IAddress);
            if (IIntuition->GetAttr(SCROLLER_Top, objects[gadgetid],(uint32 *)&pos)) {
                switch (gadgetid) {
                case OID_VPROP:
                    dY = pos - LAYERYOFFSET(win);
                    break;
                case OID_HPROP:
                    dX = pos - LAYERXOFFSET(win);
                    break;
                }
                if (dX || dY) {
                    slideBitMap(win, dX, dY);
                }
            }
        }
    }
} 

void superWindow(struct Screen *myscreen)
{
    struct BitMap* bigBitMap = IGraphics->AllocBitMapTags(WIDTH_SUPER, HEIGHT_SUPER,myscreen->BitMap.Depth,
            BMATags_Friend, myscreen->BitMap, BMATags_Displayable,TRUE, BMATags_Clear,0, TAG_END);

    if (bigBitMap != NULL) {
        struct MsgPort *AppPort = IExec->AllocSysObjectTags(ASOT_PORT, TAG_DONE);

        if ( AppPort != NULL )
        {
            idcmphook.h_Entry = (uint32 (*)())IDCMPHook;
            idcmphook.h_SubEntry = NULL;

            if ((objects[OID_MAIN] = IIntuition->NewObject(NULL, "window.class",
                WA_ScreenTitle, "SuperBitmap",
                WA_Title, "Lines",
                WA_Activate, TRUE,
                WA_DepthGadget, TRUE,
                WA_DragBar, TRUE,
                WA_CloseGadget, TRUE,
                WA_SizeGadget, TRUE,
                WA_Top, 10,
                WA_Left, 10,
                WA_MinWidth, MINWIDTH,
                WA_MinHeight, MINHEIGHT,
                WA_Width, MINWIDTH,
                WA_Height, MINHEIGHT,
                WA_IDCMP, IDCMP_NEWSIZE | IDCMP_IDCMPUPDATE,
                WA_PubScreen, myscreen, WA_SuperBitMap, bigBitMap,
                WA_NoCareRefresh, TRUE,
                WA_GimmeZeroZero, TRUE,     
                WINDOW_IDCMPHook,&idcmphook,
                WINDOW_IDCMPHookBits, IDCMP_IDCMPUPDATE,
                WINDOW_HorizProp, 1,
                WINDOW_VertProp, 1,
                WINDOW_AppPort, AppPort, TAG_DONE))!= NULL) {
                //  Open the window.
                if (windows[WID_MAIN] = (struct Window *)IIntuition->IDoMethod(objects[OID_MAIN], WM_OPEN)) {   
                    /* adjust props to represent portion visible */
                    doNewSize(); 
                    doDrawStuff();
                    /* process the window, return on IDCMP_CLOSEWINDOW */
                    doMsgLoop();
                }
                IIntuition->DisposeObject(objects[OID_MAIN]);
            }
            IExec->FreeSysObject(ASOT_PORT, AppPort);
        }   
        IGraphics->FreeBitMap(bigBitMap);
    }
}





void slideBitMap(struct Window *win, int16 Dx, int16 Dy)
{
    ILayers->ScrollLayer(0, win->RPort->Layer, Dx, Dy);
}

/*
** Update the prop gadgets and bitmap positioning when the size changes.
*/

void doNewSize()
{
    struct Window *win = windows[WID_MAIN];
    if (win != NULL) {
        IIntuition->GetAttr(WINDOW_HorizObject, objects[OID_MAIN],(uint32 *)&objects[OID_HPROP]);
        if (objects[OID_HPROP]) {       
            if (win->GZZWidth >= WIDTH_SUPER)
                slideBitMap(win, -LAYERXOFFSET(win), 0);
            IIntuition->RefreshSetGadgetAttrs((APTR)objects[OID_HPROP], win,NULL,
                GA_ID, OID_HPROP,
                SCROLLER_Top, LAYERXOFFSET(win),
                SCROLLER_Total, WIDTH_SUPER,
                SCROLLER_Visible, win->GZZWidth,
                ICA_TARGET, ICTARGET_IDCMP,
                TAG_DONE);  
        }

        IIntuition->GetAttr(WINDOW_VertObject, objects[OID_MAIN],(uint32 *)&objects[OID_VPROP]);
        if (objects[OID_VPROP]) {
            if (win->GZZHeight >= HEIGHT_SUPER)
                slideBitMap(win, 0, -LAYERYOFFSET(win));

            IIntuition->RefreshSetGadgetAttrs((APTR)objects[OID_VPROP], win,NULL,
                GA_ID, OID_VPROP,
                SCROLLER_Top, LAYERYOFFSET(win),
                SCROLLER_Total, HEIGHT_SUPER,
                SCROLLER_Visible, win->GZZHeight,
                ICA_TARGET, ICTARGET_IDCMP,
                TAG_DONE);
        }
    }
}


int16 RangeRand(uint32 maxValue)
{
    static struct RandomState range = {0xFFFF,0};
    return IUtility->Random(&range) % maxValue;
}

void doDrawStuff()
{
    struct Window *win = windows[WID_MAIN];
    if (win != NULL) {
        /* clear the bitplanes */
        IGraphics->SetRast(win->RPort, 0);
        IGraphics->SetDrMd(win->RPort, JAM1);
        int16 x1, y1, x2, y2;
        int16 pen, ncolors, deltx, delty;
        ncolors = 1 << win->WScreen->BitMap.Depth;
        deltx = RangeRand(6) + 2;
        delty = RangeRand(6) + 2;
        pen = RangeRand(ncolors - 1) + 1;
        IGraphics->SetAPen(win->RPort, pen);
        for (x1 = 0, y1 = 0, x2 = WIDTH_SUPER - 1, y2 = HEIGHT_SUPER - 1;
            x1 < WIDTH_SUPER; x1 += deltx, x2 -= deltx) {
            IGraphics->Move(win->RPort, x1, y1);
            IGraphics->Draw(win->RPort, x2, y2);
        }

        pen = RangeRand(ncolors - 1) + 1;
        IGraphics->SetAPen(win->RPort, pen);
        for (x1 = 0, y1 = 0, x2 = WIDTH_SUPER - 1, y2 = HEIGHT_SUPER - 1;
             y1 < HEIGHT_SUPER; y1 += delty, y2 -= delty) {
            IGraphics->Move(win->RPort, x1, y1);
            IGraphics->Draw(win->RPort, x2, y2);
        }
    }
}

void doMsgLoop()
{                   
    // Obtain the window wait signal mask.
    uint32 signal = 0;
    IIntuition->GetAttr(WINDOW_SigMask, objects[OID_MAIN], &signal);
    // Input Event Loop
    BOOL done = FALSE;
    while (!done){
        uint32 wait = IExec->Wait(signal | SIGBREAKF_CTRL_C);
        if ( wait & SIGBREAKF_CTRL_C ){
            done = TRUE;
            break;
        }

        if ( wait & signal ) {
            uint32 result = WMHI_LASTMSG;
            int16 code = 0;
            while ((result = IIntuition->IDoMethod(objects[OID_MAIN], WM_HANDLEINPUT, &code)) != WMHI_LASTMSG){
                switch (result & WMHI_CLASSMASK) {
                case WMHI_NEWSIZE:
                    doNewSize();
                    doDrawStuff();
                    break;
                case WMHI_CLOSEWINDOW:
                    windows[WID_MAIN] = NULL;
                    done = TRUE;
                    break;
                case WMHI_ICONIFY:
                    IIntuition->IDoMethod(objects[OID_MAIN], WM_ICONIFY);
                    windows[WID_MAIN] = NULL;
                    break;
                case WMHI_UNICONIFY:
                    windows[WID_MAIN] = (struct Window *)IIntuition->IDoMethod(objects[OID_MAIN], WM_OPEN);
                    doNewSize();
                    doDrawStuff();      
                    break;
                }
            }
        }
    }
}



User avatar
javierdlr
Beta Tester
Beta Tester
Posts: 389
Joined: Sun Jun 19, 2011 10:13 pm
Location: Donostia (GUIPUZCOA) - Spain
Contact:

Re: OS 4'd Example: SuperBitmap

Post by javierdlr »

THX recompiled/tried without problems.

Now, if someone with wiki edit rights, could update/upload to the wiki please :-)
User avatar
trixie
Posts: 409
Joined: Thu Jun 30, 2011 2:54 pm
Location: Czech Republic

Re: OS 4'd Example: SuperBitmap

Post by trixie »

@javierdlr
Done.

@dstastny
Thank you for updating the example code! I've also added you to the list of wiki contributors:
http://wiki.amigaos.net/wiki/Wiki_Author_Credits
The Rear Window blog

AmigaOne X5000 @ 2GHz / 4GB RAM / Radeon RX 560 / ESI Juli@ / AmigaOS 4.1 Final Edition
SAM440ep-flex @ 667MHz / 1GB RAM / Radeon 9250 / AmigaOS 4.1 Final Edition
dstastny
Posts: 48
Joined: Fri Dec 16, 2016 6:31 am
Location: Atlanta GA

Re: OS 4'd Example: SuperBitmap

Post by dstastny »

@Trixie - your welcome. I am trying to get up to speed on OS4 as my programming of Amiga is long ago so I am referencing examples so Ill probably send more as I work through various concepts.

Doug
User avatar
trixie
Posts: 409
Joined: Thu Jun 30, 2011 2:54 pm
Location: Czech Republic

Re: OS 4'd Example: SuperBitmap

Post by trixie »

@dstastny

Please do!
The Rear Window blog

AmigaOne X5000 @ 2GHz / 4GB RAM / Radeon RX 560 / ESI Juli@ / AmigaOS 4.1 Final Edition
SAM440ep-flex @ 667MHz / 1GB RAM / Radeon 9250 / AmigaOS 4.1 Final Edition
Post Reply