/** wbdualpf.c **/ /* Turn the workbench into dual playfield. * * You can use the same trick for your own screens, * which is the recommended method for creating dual-playfield * screens. * * -Start with a new, single-playfield screen * (don't set DUALPF in NewScreen.ViewModes) * -Allocate a second playfield, set up a rastport for * rendering into it, and install it into your open screen * as shown here. Intuition will never know about or use your * second playfield for its rendering (menus, gadgets, etc.). * -Be sure to remove evidence of your deed before CloseScreen(). */ #include #include #include #ifdef ORIGINALCODE #define printf kprintf #endif struct Remember *rememberkey = NULL; struct Window *getNewWind(); struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; ULONG flg = ACTIVATE | WINDOWCLOSE | NOCAREREFRESH | WINDOWDRAG | WINDOWDEPTH | SIMPLE_REFRESH; ULONG iflg = CLOSEWINDOW | INTUITICKS ; #define FANCYVERSION 1 #ifdef FANCYVERSION #define VISUALTICKS 30 /* intuiticks per frame */ #define CYCLETICKS 5 /* intuiticks per pen color */ #endif main() { struct IntuiMessage *msg; struct Window *window = NULL; WORD exitval = 0; /* hold data from *msg */ ULONG class; /* specific for this test */ struct Screen *wbscreen; struct RasInfo *rinfo2 = NULL; /* second playfield rasinfo ... */ struct BitMap *bmap2 = NULL; /* ... and bitmap */ struct RastPort *rport2 = NULL; /* for rendering into bmap2 */ BOOL it_is_done = FALSE; /* success flag */ int counter = 0; /* for timing the visuals */ if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0))) { printf("NO INTUITION LIBRARY\n"); exitval = 1; goto EXITING; } if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0))) { printf("NO GRAPHICS LIBRARY\n"); exitval = 2; goto EXITING; } /* get a window on the workbench */ window = getNewWind(320, 20, 300, 50, flg, iflg); if (window == NULL) { printf("test: can't get window.\n"); exitval = 1; goto EXITING; } /* ------ Add a second playfield for Workbench ------------ */ wbscreen = window->WScreen; /* find it */ /* allocate second playfield's rasinfo, bitmap, and bitplane */ if (!(rinfo2 = (struct RasInfo *) AllocMem(sizeof(struct RasInfo), MEMF_PUBLIC|MEMF_CLEAR))) { printf("alloc rasinfo failed\n"); goto EXITING; } if (!(bmap2 = (struct BitMap *) AllocMem(sizeof(struct BitMap), MEMF_PUBLIC|MEMF_CLEAR))) { printf("alloc bitmap failed\n"); goto EXITING; } InitBitMap(bmap2, 1, wbscreen->Width, wbscreen->Height); /* we'll use 1 plane. */ if (!(bmap2->Planes[0] = (UWORD *) AllocRaster(wbscreen->Width, wbscreen->Height))) { printf("alloc raster failed\n"); goto EXITING; } /* get a rastport, and set it up for rendering into bmap2 */ if (!(rport2 = (struct RastPort *) AllocMem(sizeof (struct RastPort), MEMF_PUBLIC))) { printf("alloc rastport failed\n"); goto EXITING; } InitRastPort(rport2); rport2->BitMap = bmap2; SetRast(rport2, 0); /* manhandle viewport: install second playfield and change modes */ Forbid(); rinfo2->BitMap = bmap2; /* install my bitmap in my rasinfo */ wbscreen->ViewPort.RasInfo->Next = rinfo2; /* install rinfo for viewport's second playfield */ wbscreen->ViewPort.Modes |= DUALPF; /* convert viewport */ it_is_done = TRUE; Permit(); /* set my foreground color */ SetRGB4(&wbscreen->ViewPort, 9, 0, 0xF, 0); /* color 9 is color 1 for second playfield of hi-res viewport */ /* put viewport changed into effect */ MakeScreen(wbscreen); RethinkDisplay(); drawSomething(rport2); printf("test program ok\n"); FOREVER { if ((msg = (struct IntuiMessage *)GetMsg(window->UserPort)) == NULL) { Wait(1<UserPort->mp_SigBit); continue; } class = msg->Class; ReplyMsg(msg); switch (class) { case INTUITICKS: #ifdef FANCYVERSION setPrimary(&wbscreen->ViewPort); /* cycles colors */ if (counter++ > VISUALTICKS) { counter = 0; SetRast(rport2, 0); drawSomething(); } #endif break; case CLOSEWINDOW: printf("event CLOSEWINDOW\n"); goto EXITING; default: printf("unknown event: class %lx\n", class); } } EXITING: /* clean up dual-playfield trick */ if (it_is_done) { Forbid(); wbscreen->ViewPort.RasInfo->Next = NULL; wbscreen->ViewPort.Modes &= ~DUALPF; Permit(); MakeScreen(wbscreen); RethinkDisplay(); } if (rport2) FreeMem(rport2, sizeof (struct RastPort)); if (bmap2) { if (bmap2->Planes[0]) { FreeRaster(bmap2->Planes[0], wbscreen->Width, wbscreen->Height); } FreeMem(bmap2, sizeof (struct BitMap)); } if (rinfo2) FreeMem(rinfo2, sizeof (struct RasInfo)); if (window) CloseWindow(window); if (GfxBase) CloseLibrary(GfxBase); if (IntuitionBase) CloseLibrary(IntuitionBase); exit (exitval); } #ifdef FANCYVERSION /* cycle pen 1's color */ setPrimary(vp) struct ViewPort *vp; { static int current = 0; /* pen 1 is color 9 for second playfield in hires */ /* feel free too do this elegantly */ if (!(current++ % CYCLETICKS)) return; switch ((current/CYCLETICKS)%3) { case 0: SetRGB4(vp, 9, 0xF, 0, 0); break; case 1: SetRGB4(vp, 9, 0, 0xF, 0); break; case 2: SetRGB4(vp, 9, 0, 0, 0xF); break; } } struct pt_st { int x; int y; }; typedef struct pt_st Pt; drawSomething(rp) struct RastPort *rp; { int width, height; int i; Pt start, vertex, end; /* random reference lines */ Pt p0, p1; /* endpoints to be drawn */ width = rp->BitMap->BytesPerRow * 8; height = rp->BitMap->Rows; /* set up two random reference lines */ start.x = RangeRand(width); vertex.x = RangeRand(width); end.x = RangeRand(width); start.y = RangeRand(height); vertex.y = RangeRand(height); end.y = RangeRand(height); SetAPen(rp, 1); /* draw lines connecting intermediate points */ for (i = 0; i <= 0x100; i += 0x10) { /* point between start and vertex */ p0.x = (start.x * (0xFF - i) + vertex.x * i) >> 8; p0.y = (start.y * (0xFF - i) + vertex.y * i) >> 8; /* point between vertex and end */ p1.x = (vertex.x * (0xFF - i) + end.x * i) >> 8; p1.y = (vertex.y * (0xFF - i) + end.y * i) >> 8; Move(rp, p0.x, p0.y); Draw(rp, p1.x, p1.y); } } #else drawSomething(rp) 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, 0, r); Draw(rp, c, 0); } } #endif struct Window * getNewWind(left, top, width, height, flg, iflg) SHORT left, top, width, height; ULONG flg, iflg; { struct Window *OpenWindow(); struct NewWindow nw; nw.LeftEdge = (SHORT) left; nw.TopEdge = (SHORT) top; nw.Width = (SHORT) width; nw.Height = (SHORT) height; nw.DetailPen = (UBYTE) -1; nw.BlockPen = (UBYTE) -1; nw.IDCMPFlags = (ULONG) iflg; nw.Flags = (ULONG) flg; nw.FirstGadget = (struct Gadget *) NULL; nw.CheckMark = (struct Image *) NULL; nw.Title = (UBYTE *) " Dual Playfield Mole "; nw.Screen = (struct Screen *) NULL; nw.BitMap = (struct BitMap *) NULL; nw.MinWidth = (SHORT) 50; nw.MinHeight= (SHORT) 30; /* work around bug */ nw.MaxWidth = (SHORT) nw.Width; nw.MaxHeight = (SHORT) nw.Height; nw.Type = (USHORT) WBENCHSCREEN; return ((struct Window *) OpenWindow(&nw)); }