/** wbdualpf.c :ts=8 **/ /* 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 #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 #if FANCYVERSION #define VISUALTICKS 30 /* intuiticks per frame */ #define CYCLETICKS 3 /* 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 */ int it_is_done = 0; /* success flag */ int counter = 0; /* for timing the visuals */ if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0L))) { printf("NO INTUITION LIBRARY\n"); exitval = 1; goto EXITING; } if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0L))) { 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((LONG) sizeof(struct RasInfo), (LONG) MEMF_PUBLIC|MEMF_CLEAR))) { printf("alloc rasinfo failed\n"); goto EXITING; } if (!(bmap2 = (struct BitMap *) AllocMem((LONG) sizeof(struct BitMap), (LONG) MEMF_PUBLIC|MEMF_CLEAR))) { printf("alloc bitmap failed\n"); goto EXITING; } InitBitMap(bmap2, 1L, (LONG) wbscreen->Width, (LONG) wbscreen->Height); /* we'll use 1 plane. */ if (!(bmap2->Planes[0] = (UBYTE *) AllocRaster((LONG) wbscreen->Width, (LONG) 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((LONG) sizeof (struct RastPort), (LONG) MEMF_PUBLIC))) { printf("alloc rastport failed\n"); goto EXITING; } InitRastPort(rport2); rport2->BitMap = bmap2; SetRast(rport2, 0L); /* 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 = 1; Permit(); /* set my foreground color */ SetRGB4(&wbscreen->ViewPort, 9L, 0L, (LONG) 0xF, 0L); /* color 9 is color 1 for second playfield of hi-res viewport */ /* put viewport changed into effect */ MakeScreen(wbscreen); RethinkDisplay(); drawSomething(rport2); FOREVER { if ((msg = (struct IntuiMessage *)GetMsg(window->UserPort)) == NULL) { Wait((ULONG) 1<UserPort->mp_SigBit); continue; } class = msg->Class; ReplyMsg(msg); switch (class) { case INTUITICKS: #if FANCYVERSION setPrimary(&wbscreen->ViewPort); /* cycles colors */ if (counter++ > VISUALTICKS) { counter = 0; SetRast(rport2, 0L); drawSomething(rport2); } #endif break; case CLOSEWINDOW: 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, (LONG) sizeof (struct RastPort)); if (bmap2) { if (bmap2->Planes[0]) { FreeRaster(bmap2->Planes[0], (LONG) wbscreen->Width, (LONG) wbscreen->Height); } FreeMem(bmap2, (LONG) sizeof (struct BitMap)); } if (rinfo2) FreeMem(rinfo2, (LONG) sizeof (struct RasInfo)); if (window) CloseWindow(window); if (GfxBase) CloseLibrary(GfxBase); if (IntuitionBase) CloseLibrary(IntuitionBase); exit (exitval); } #if 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, 9L, 0xFL, 0L, 0L); break; case 1: SetRGB4(vp, 9L, 0L, 0xFL, 0L); break; case 2: SetRGB4(vp, 9L, 0L, 0L, 0xFL); break; } } struct pt_st { ULONG x; ULONG y; }; typedef struct pt_st Pt; drawSomething(rp) struct RastPort *rp; { int width, height; LONG RangeRand(); 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((LONG) width); vertex.x = RangeRand((LONG) width); end.x = RangeRand((LONG) width); start.y = RangeRand((LONG) height); vertex.y = RangeRand((LONG) height); end.y = RangeRand((LONG) height); SetAPen(rp, 1L); /* 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, 1L); for (r = 0; r < height; r += 40) for (c = 0; c < width; c += 40) { Move(rp, 0L, (LONG) r); Draw(rp, (LONG) c, 0L); } } #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)); }