home *** CD-ROM | disk | FTP | other *** search
- /* 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();
- }
-