[Contents] [Index] [Help] [Retrace] [browse <] [Browse >]

/* dualplayfield.c
** Shows how to turn on dual-playfield mode in a screen.
**
** SAS/C 5.10a
** lc -b1 -cfist -v -y dualplayfield
** blink FROM LIB:c.o dualplayfield.o TO dualplayfield LIB LIB:lc.lib LIB:amiga.lib
*/

#define INTUI_V36_NAMES_ONLY

#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <graphics/displayinfo.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>

VOID doDualPF ( struct Window * );
BOOL installDualPF( struct Screen *, struct RastInfo * );
VOID drawSomething( struct RastPort * );
VOID handleIDCMP ( struct Window * );
VOID removeDualPF( struct Screen *s );

struct Library *IntuitionBase;
struct Library *GfxBase;

VOID main(int argc, char **argv)
{
struct Window *win;
struct Screen *scr;

IntuitionBase = OpenLibrary("intuition.library",37);
if (IntuitionBase != NULL)
    {
    GfxBase = OpenLibrary("graphics.library", 37);
    if (GfxBase != NULL)
        {
        scr = OpenScreenTags(NULL,
                             SA_Depth,     2,
                             SA_DisplayID, HIRES_KEY,
                             SA_Title,     "Dual Playfield Test Screen",
                             TAG_END);
        if ( scr != NULL )
            {
            win = OpenWindowTags(NULL,
                                 WA_Title,        "Dual Playfield Mode",
                                 WA_IDCMP,        IDCMP_CLOSEWINDOW,
                                 WA_Width,        200,
                                 WA_Height,       100,
                                 WA_DragBar,      TRUE,
                                 WA_CloseGadget,  TRUE,
                                 WA_CustomScreen, scr,
                                 TAG_END);
            if ( win != NULL )
                {
                doDualPF(win);

                CloseWindow(win);
                }
            CloseScreen(scr);
            }
        CloseLibrary(GfxBase);
        }
    CloseLibrary(IntuitionBase);
    }
}


/*
** Allocate all of the stuff required to add dual playfield to a screen.
*/
VOID doDualPF(struct Window *win)
{
struct Screen   *myscreen;
struct RasInfo  *rinfo2;
struct BitMap   *bmap2;
struct RastPort *rport2;

myscreen = win->WScreen;   /* Find the window's screen */

/* Allocate the second playfield's rasinfo, bitmap, and bitplane */
rinfo2 = (struct RasInfo *) AllocMem(sizeof(struct RasInfo), MEMF_PUBLIC | MEMF_CLEAR);
if ( rinfo2 != NULL )
    {
    /* Get a rastport, and set it up for rendering into bmap2 */
    rport2 = (struct RastPort *) AllocMem(sizeof(struct RastPort), MEMF_PUBLIC );
    if (rport2 != NULL )
        {
        bmap2 = (struct BitMap *) AllocMem(sizeof(struct BitMap), MEMF_PUBLIC | MEMF_CLEAR);
        if (bmap2 != NULL )
            {
            InitBitMap(bmap2, 1, myscreen->Width, myscreen->Height);

            /* extra playfield will only use one bitplane here. */
            bmap2->Planes[0] = (PLANEPTR) AllocRaster(myscreen->Width, myscreen->Height);
            if (bmap2->Planes[0] != NULL )
                {
                InitRastPort(rport2);
                rport2->BitMap = rinfo2->BitMap = bmap2;

                SetRast(rport2, 0);

                if (installDualPF(myscreen,rinfo2))
                    {
                    /* Set foreground color; color 9 is color 1 for
                    ** second playfield of hi-res viewport
                    */
                    SetRGB4(&myscreen->ViewPort, 9, 0, 0xF, 0);

                    drawSomething(rport2);

                    handleIDCMP(win);

                    removeDualPF(myscreen);
                    }
                FreeRaster(bmap2->Planes[0], myscreen->Width, myscreen->Height);
                }
            FreeMem(bmap2, sizeof(struct BitMap));
            }
        FreeMem(rport2, sizeof(struct RastPort));
        }
    FreeMem(rinfo2, sizeof(struct RasInfo));
    }
}

/*
** Manhandle the viewport:
** install second playfield and change modes
*/
BOOL installDualPF(struct Screen *scrn, struct RastInfo *rinfo2)
{
ULONG screen_modeID;
BOOL return_code = FALSE;

screen_modeID = GetVPModeID(&(scrn->ViewPort));
if( screen_modeID != INVALID_ID )
    {
    /* you can only play with the bits in the Modes field
    ** if the upper half of the screen mode ID is zero!!!
    */
    if ( (screen_modeID & 0xFFFF0000L) == 0L )
        {
        return_code = TRUE;

        Forbid();

        /* Install rinfo for viewport's second playfield */
        scrn->ViewPort.RasInfo->Next = rinfo2;
        scrn->ViewPort.Modes |= DUALPF;

        Permit();

        /* Put viewport change into effect */
        MakeScreen(scrn);
        RethinkDisplay();
        }
    }
return(return_code);
}

/*
** Draw some lines in a rast port...This is used to get some data into
** the second playfield.  The windows on the screen will move underneath
** these graphics without disturbing them.
*/
VOID drawSomething(struct RastPort *rp)
{
int width, height;
int r, c;

width = rp->BitMap->BytesPerRow * 8;
height = rp->BitMap->Rows;

SetAPen(rp, 1);

for (r = 0; r < height; r += 40)
    {
    for (c = 0; c < width; c += 40)
        {
        Move(rp, 0L, r);
        Draw(rp, c, 0L);
        }
    }
}

/*
** simple event loop to wait for the user to hit the close gadget
** on the window.
*/
VOID handleIDCMP(struct Window *win)
{
BOOL done = FALSE;
struct IntuiMessage *message = NULL;
ULONG class;
ULONG signals;

while (!done)
    {
    signals = Wait(1L << win->UserPort->mp_SigBit);
    if (signals & (1L << win->UserPort->mp_SigBit))
        {
        while ((!done) &&
               (message = (struct IntuiMessage *)GetMsg(win->UserPort)))
            {
            class = message->Class;
            ReplyMsg((struct Message *)message);

            switch (class)
                {
                case IDCMP_CLOSEWINDOW:
                    done = TRUE;
                    break;
                }
            }
        }
    }
}

/*
** remove the effects of installDualPF().
** only call if installDualPF() succeeded.
*/
VOID removeDualPF(struct Screen *scrn)
{
Forbid();

scrn->ViewPort.RasInfo->Next = NULL;
scrn->ViewPort.Modes &= ~DUALPF;

Permit();

MakeScreen(scrn);
RethinkDisplay();
}