[comp.sys.amiga] One Can Only Wait So Long....

ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) (06/24/87)

[ REPLACE YOUR MAILER ]

	According to popular belief, Craig Norborg, moderator of
comp.{sources,binaries}.amiga, is having trouble with his mailer, which is
preventing the distribution of the newsgroup.

	I've been sitting back and waiting patiently, confident that
comp.*.amiga would unblock soon.  Well, my patience has run out, and I'm
sure yours has, too.

	So, attached here is a copy of the source to "Viacom."  I'm proud of
this enough that I want it to get out all over the place.  I hope this
doesn't anger the net.gods, and isn't considered part of the denominator in
the signal/noise ratio.

	Note that this is no slight on Craig.  I'm sure he's ready to kick
his USENET node by now, if he hasn't already.

	I hope this doesn't get mangled like 'ehb' did...

					Schwab

-------- Indicated where cut. --------
#! /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