doc@s.cc.purdue.edu (Craig Norborg) (06/18/87)
Once again Leo comes up with something neat! I don't think I will use this when I work as often as robotroff though... -Doc > Here's the source to Viacom. Any questions regarding the quality of >this code should be directed to British Airways. > #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # README # Makefile # viacom.c # oddblit.c # rnd.asm # This archive created: Sun Jun 7 02:30:53 1987 # By: Leo 'Bols Ewhac' Schwab () export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'README' then echo shar: "will not over-write existing file 'README'" else cat << \SHAR_EOF > 'README' And you thought I was running out of ideas. Welcome to my latest endeavor, "Viacom". Viacom is the name of a cable TV service local to the San Francisco Bay Area. This program is more or less a political statement regarding their service. MANUFACTURE This is written for the Manx compiler. It *should* work under all versions (tested with 3.4b, which will be available RSN). To make the program, you say: 1> make Easy, isn't it? USEAGE Type 'viacom' at a CLI prompt. It takes no arguments. When done, click on the close gadget in Viacom's window. I highly recommend that you run it without first trying to determine what it does. It's more fun that way. CAVEATS This program has been designed to work with stuff like 'morerows', 'DropShadow', etc. However, if you use Viacom with 'DropShadow', it is vital that you remember to exit them in the *REVERSE* order in which you invoked them. Otherwise, you'll lose your screen. The recommended way of doing things is to start 'DropShadow', then start Viacom. When done, exit Viacom first, followed by 'DropShadow'. This is necessary because of the way both programs muck about with the WorkBench display. Hope you like it. Oh, and if you work for Viacom, and are insulted by this program, I refer you to The First Amendment.... _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ Leo L. Schwab -- The Guy in The Cape ihnp4!ptsfa -\ \_ -_ Bike shrunk by popular demand, dual ---> !{well,unicom}!ewhac O----^o But it's still the only way to fly. hplabs / (pronounced "AE-wack") "Work FOR? I don't work FOR anybody! I'm just having fun." -- The Doctor SHAR_EOF fi if test -f 'Makefile' then echo shar: "will not over-write existing file 'Makefile'" else cat << \SHAR_EOF > 'Makefile' # :ts=8 # Makefile for viacom # Leo L. Schwab 8706.6 OBJECTS = viacom.o oddblit.o rnd.o viacom: $(OBJECTS) ln $(OBJECTS) -lc SHAR_EOF fi if test -f 'viacom.c' then echo shar: "will not over-write existing file 'viacom.c'" else cat << \SHAR_EOF > 'viacom.c' /* :ts=8 bk=0 * * viacom.c: Another display hack based on common real-life experience * with Viacom cable service. Viacom is a registered tradmark * of Viacom Cablevision (probably). * * Leo L. Schwab 8706.4 (415)-456-6565 * * (-: Some people accuse me of being sick. :-) * (-: This should convince any doubters. :-) */ #include <exec/types.h> #include <intuition/intuition.h> #include <hardware/blit.h> #define MINTERM ((int) (NABC | ANBC | NABNC | ANBNC)) #define PLUSX 100 #define PLUSY 50 extern void *OpenLibrary(), *OpenScreen(), *OpenWindow(), *GetMsg(), *AllocRaster(), *CreatePort(), *FindPort(); extern long VBeamPos(); extern int rnd(); struct NewWindow windef = { 0, 15, 200, 10, -1, -1, CLOSEWINDOW, WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG | ACTIVATE, NULL, NULL, (UBYTE *) "Patching in...", NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN }; struct Screen *scr; struct Window *win; struct BitMap noisemap, phonymap; struct RastPort nrp; struct MsgPort *flagport; long nwide, nhigh; int wide, high; void *IntuitionBase, *GfxBase; char *PORTNAME = "Viacom Public Port"; main () { register struct Screen *wbs; register struct BitMap *wbbm; register int i; int deep, xoff, yoff; int ox[8], oy[8]; void *msg; openstuff (); rnd ((short) -VBeamPos()); /* Glean important information from system structures */ wbs = win -> WScreen; wide = wbs -> Width; high = wbs -> Height; wbbm = wbs -> ViewPort.RasInfo -> BitMap; deep = wbbm -> Depth; /* Make the bitplane with the noise in it. */ nwide = wide + PLUSX; nhigh = high + PLUSY; InitBitMap (&noisemap, 1L, nwide, nhigh); if (!(noisemap.Planes[0] = AllocRaster (nwide, nhigh))) die ("Noise bitmap allocation failed."); InitRastPort (&nrp); nrp.BitMap = &noisemap; mknoise (nwide, nhigh); /* Replace the workbench you see with my phony one. */ makephony (wide, high, deep); wbs -> ViewPort.RasInfo -> BitMap = &phonymap; MakeScreen (wbs); RethinkDisplay (); SetWindowTitles (win, "\273> Viacom <\253", "Viacom Cablevision"); while (1) { if (msg = GetMsg (win -> UserPort)) { ReplyMsg (msg); break; } OwnBlitter (); for (i=0; i<deep; i++) { while (abs ((xoff = rnd (PLUSX)) - ox[i]) < 10) ; while (abs ((yoff = rnd (PLUSY)) - oy[i]) < 10) ; oddblit (wbbm -> Planes[i], phonymap.Planes[i], wide, high, noisemap.Planes[0], (int) nwide, (int) nhigh, xoff, yoff, MINTERM); ox[i] = xoff; oy[i] = yoff; } DisownBlitter (); WaitTOF (); } /* Return to normal */ wbs -> ViewPort.RasInfo -> BitMap = wbbm; MakeScreen (wbs); RethinkDisplay (); closestuff (); } mknoise (wide, high) long wide, high; { register unsigned int x, i; SetRast (&nrp, 0L); SetDrMd (&nrp, COMPLEMENT); for (x=0; x<wide; x++) for (i=0; i<20; i++) WritePixel (&nrp, (long) x, (long) rnd ((short) high)); } abs (x) int x; { return (x < 0 ? -x : x); } makephony (wide, high, deep) int wide, high, deep; { InitBitMap (&phonymap, (long) deep, (long) wide, (long) high); while (deep--) /* deep decremented after test */ if (!(phonymap.Planes[deep] = AllocRaster ((long) wide, (long) high))) die ("Couldn't allocate clone bitmap."); } openstuff () { /* * Running Viacom multiple times at once could really muck things * up, especially if you exit them in the wrong order. So we do * this so that only one Viacom process is active at any given time. */ if (FindPort (PORTNAME)) die ("You are already connected to Viacom."); else flagport = CreatePort (PORTNAME, NULL); initblitdata (); if (!(IntuitionBase = OpenLibrary ("intuition.library", 0L))) die ("-=RJ=- is on vacation."); if (!(GfxBase = OpenLibrary ("graphics.library", 0L))) die ("Dale? Are you there?"); if (!(win = OpenWindow (&windef))) die ("Window painted shut."); } closestuff () { register int i; for (i=0; i<phonymap.Depth; i++) if (phonymap.Planes[i]) FreeRaster (phonymap.Planes[i], (long) wide, (long) high); if (noisemap.Planes[0]) FreeRaster (noisemap.Planes[0], nwide, nhigh); if (win) CloseWindow (win); if (scr) CloseScreen (scr); if (GfxBase) CloseLibrary (GfxBase); if (IntuitionBase) CloseLibrary (IntuitionBase); if (flagport) DeletePort (flagport); } die (str) char *str; { puts (str); closestuff (); exit (20); } SHAR_EOF fi if test -f 'oddblit.c' then echo shar: "will not over-write existing file 'oddblit.c'" else cat << \SHAR_EOF > 'oddblit.c' /* :ts=8 bk=0 * * oddblit.c: Custom blitter routine. Stolen from Tomas Rokicki's LIFE * program and mashed up beyond all recognition. Nearly all * comments are Tom's. * * Leo L. Schwab 8706.4 */ #include <exec/types.h> /* * This include file includes the defines for all the blitter functions. * It only allows use of the `blit' operations; for area fills or line * drawing, it will need to be extended. * * Information gleaned from the Hardware Reference Manual. */ #define BLTADD (0xdff040L) /* * This structure contains everything we need to know. * Do not do a structure copy into this! Instead, assign * each field. The last field assigned must be bltsize; that * starts up the blitter. Also note that all of these are * write only, and you can't read them. */ struct bltstruct { short con0; short con1; short afwm; short alwm; short *csource, *bsource, *asource, *dsource; short bltsize; short dmy1, dmy2, dmy3; short cmod, bmod, amod, dmod; } *blitter = BLTADD; /* * We need an array which tells what to use for all 256 possible operations. */ #define USEA (0x8) #define USEB (0x4) #define USEC (0x2) #define USED (0x1) char touse[256]; char fwma[16]; char lwma[16]; /* * Call initblitdata() once on startup before you ever call oddblit. */ initblitdata() { register int i; register int s; for (i=0; i<256; i++) { s = USED; if ((i >> 4) != (i & 15)) s += USEA; if (((i >> 2) & 51) != (i & 51)) s += USEB; if (((i >> 1) & 85) != (i & 85)) s += USEC; touse[i] = s; } s = 0xffff; for (i=0; i<16; i++) { fwma[i] = s; s = (s >> 1) & ~0x8000 ; lwma[i] = 0xffff - s; } } /* * (Tom's original speech:) * This is the major user interface. Takes addresses and offsets for * all four locations, a modulo and sizes, and a function. * Assumes the modulos for all sources and destination are the same. * You might want to add some arguments or delete some. * * All arguments are in pixels (except the addresses and function.) * * Before you call this routine, call OwnBlitter(); after you have * called it as many times as you need, call DisownBlitter(). Remember * that you cannot do any printf's or anything else which requires the * blitter when you own the blitter, so be careful with the debug code. * The machine will lock but will not crash. */ /* * Leo here. This is the bit I mashed to pieces. Using Tom's BlitLab * program (wonderful thing), I figured out what it was I wanted to do. * So sit back, relax, and enjoy the narrative to follow... * * It is assumed that src and dest bitmap are identically sized, * and that the noise bitmap is larger than both of them. * All x,y parameters are in pixels. * * Note that this does NOT do a general arbitrary rectangle to rectangle * logic function. It's just a quick hack to OR random bits from one * bitplane with another, and place the result into a third location. */ oddblit (src, dest, sdx, sdy, noise, nx, ny, xoff, yoff, minterm) short *src, *dest, *noise; int sdx, sdy, nx, ny, xoff, yoff; int minterm; { int noisemod; /* Compute width of bitplanes in words */ sdx = (sdx + 15) >> 4; nx = (nx + 15) >> 4; /* noisemod is in bytes */ noisemod = (nx - sdx) * 2; /* Wait for blitter to finish whatever it may be doing */ WaitBlit (); /* Start tromping the blitter */ blitter -> bsource = src; blitter -> dsource = dest; blitter -> afwm = blitter -> alwm = 0xffff; /* Compute start address into noise plane */ blitter -> asource = noise + yoff * nx + (xoff >> 4); /* Compute desired shift for noise plane */ xoff &= 15; /* Comnpute and write control words */ blitter -> con0 = (xoff << 12) + (touse[minterm] << 8) + minterm; blitter -> con1 = 0; /* No shifts on B source or flags */ /* Write out the modulos */ blitter -> amod = noisemod; blitter -> bmod = 0; /* These are sized precisely */ blitter -> dmod = 0; /* * This last assignment starts up the blitter. */ blitter->bltsize = (sdy << 6) + sdx; } SHAR_EOF fi if test -f 'rnd.asm' then echo shar: "will not over-write existing file 'rnd.asm'" else cat << \SHAR_EOF > 'rnd.asm' *\ * :ts=8 * Yet Another random number generator. By Leo Schwab. * Based on an idea posted on the USENET (Thanks, Sam Dicker!) * For the Manx assembler. * * Calling convention: * short rnd (range); * short range; * * 8606.30 */ public _rnd _rnd lea rndseed,a0 ; Get address of seed move.w 4(sp),d1 ; Get range argument tst.w d1 ble.s setseed ; Go reset seed move.l (a0),d0 ; Get seed ADD.L D0,D0 BHI.S over EORI.L #$1D872B41,D0 over move.l d0,(a0) ; Save new seed andi.l #$ffff,d0 ; Coerce into word divu d1,d0 ; Divide by range swap d0 ; and get remainder (modulus) rts setseed neg.w d1 ; Probably don't need this move.l d1,(a0) rts dseg rndseed dc.l 0 cseg SHAR_EOF fi exit 0 # End of shell archive