/* rainbow.c : Marauder-style rainbow generator - (c) 1987 DJH As some would put it, this program is a "parlour trick" very similar to that used in the Marauder II disk copier. Quite a simple concept, actually; install a user copper list such that the background color (hardware color 0) is changed every few scan lines. I was even able to change the background color every WORD during testing! Try filling the screen with WorkBench color 1 and rendering text in color 0 for a Genlock- style effect; the rainbow shows through the letters themselves! P.S. This program compiled under Manx 3.4; no need to declare RKM includes if you condense them all into one big precompiled symbol table! P.P.S. Sorry for the lack of comments; but then again, this program was a fast hack. Should be highly readable anyway. */ void *IntuitionBase,*GfxBase; #define NUMCOLORS 66 UWORD colors[NUMCOLORS] = { 0xce3,0xae3,0x8e3,0x7e3,0x5e3,0x4e3,0x3e4,0x3e5,0x3e7,0x3e8, 0x3ea,0x3eb,0x3ec,0x3ee,0x3de,0x3ce,0x3ae,0x39e,0x37e,0x34e, 0x33e,0x43e,0x63e,0x73e,0x83e,0xa3e,0xb3e,0xc3e,0xe3e,0xe3d, 0xe3b,0xe3a,0xe39,0xe37,0xe36,0xe34,0xe33,0xe53,0xe63,0xe83, 0xe93,0xea3,0xeb3,0xec3,0xee3,0xde3,0xbe3,0x8e3,0x7e3,0x4e3, 0x3e4,0x3e5,0x3e6,0x3e8,0x3e9,0x3ea,0x3ec,0x3ed,0x3ee,0x3de, 0x3be,0x3ae,0x38e,0x37e,0x36e,0x34e }; main(argc,argv) int argc; char *argv[]; { struct Window *window; struct ViewPort *vp; struct UCopList *ucop; void *dspins,*sprins,*clrins; /* intermediate Copper cache ptrs */ struct NewWindow nw; UWORD bgpen=0,i,j=1; if (argc==2) bgpen=*argv[1]-'0'; if (bgpen>3) { puts("Usage : rainbow [default color (0-3)]"); exit(0); } GfxBase=OpenLibrary("graphics.library",0); IntuitionBase=OpenLibrary("intuition.library",0); setmem(&nw,sizeof(nw),0); nw.Height=50; nw.Width=316; nw.DetailPen=nw.BlockPen=-1; nw.Flags=WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|SMART_REFRESH; nw.IDCMPFlags=CLOSEWINDOW; nw.Title=(UBYTE *)"Rainbow (c) 1987 John Hodgson"; nw.Type=WBENCHSCREEN; /* 'cuz we want the WB Screen ptr */ window=OpenWindow(&nw); vp=ViewPortAddress(window); /* look into CINIT for 1.2 or later */ while (!GetMsg(window->UserPort)) { /* the goal is to assemble all the Copper lists and THEN update the ViewPort pointer so Intuition won't see any partially constructed lists. Note use of double-buffering; we don't want funny effects if user tries to drag the screen around! */ ucop=AllocMem(sizeof(struct UCopList),MEMF_CHIP|MEMF_CLEAR); for (i=0;iDspIns; sprins=vp->SprIns; clrins=vp->ClrIns; Forbid(); /* don't let Intuition see our cleanup */ vp->DspIns=vp->SprIns=vp->ClrIns=0; /* hide these from FVPCL() */ FreeVPortCopLists(vp); /* free UCopIns from previous pass */ /* cleanup done, uncover "hidden" copper lists */ vp->DspIns=dspins; vp->SprIns=sprins; vp->ClrIns=clrins; vp->UCopIns=ucop; /* install new UCopIns */ Permit(); RethinkDisplay(); } /* No need to optimize for cleanup; free ALL lists & recreate 'em */ FreeVPortCopLists(vp); RemakeDisplay(); CloseWindow(window); CloseLibrary(IntuitionBase); CloseLibrary(GfxBase); }