[comp.sources.amiga] v89i129: jitter - evolving bugs

page%swap@Sun.COM (Bob Page) (05/12/89)

Submitted-by: myrias!ami-cg!cg@uunet.uu.net (Chris Gray)
Posting-number: Volume 89, Issue 129
Archive-name: fun/jitter.1

This is 'jitter', an implementation of the evolving bugs described in
the May 1989 Computer Recreations column in "Scientific American".

[source is in Draco.  uuencoded executable included.  ..bob]

# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
#	READ_ME
#	jitter.d
#	jitter.uu
#	jitter.w
# This is archive 1 of a 1-part kit.
# This archive created: Thu May 11 18:26:59 1989
echo "extracting READ_ME"
sed 's/^X//' << \SHAR_EOF > READ_ME
XEnclosed are the Draco source and the binary for 'jitter', an implementation
Xof the evolving bugs described in the May 1989 Computer Recreations column
Xin "Scientific American". The implementation is pretty much as is described
Xin the article. Some details:
X
X    - runs from CLI only (sorry)
X
X    - tested only on my Amiga 2000 with 2620 CPU board and 5 Meg of RAM,
X      bug should work on any Amiga (works quite a bit faster if you use
X      SetCPU's FASTROM option)
X
X    - changes its priority to -5, so it won't hog your system (it's 100%
X      CPU bound)
X
X    - code is not commented, and isn't the best in the world, but it
X      shouldn't be hard to figure out
X
X    - uses a 640 x 400 x 3 (8 colour) screen
X
X    - colours:
X	black: background
X	grey: borders, text, and food (bacteria)
X	red: bug with power < 250
X	brown: bug with power < 500
X	yellow: bug with power < 750
X	green: bug with power < 1000
X	light blue: bug with power < 1250
X	bright blue: other bugs
X
X    - exit by clicking on the close box (there are no menus or other gadgets)
X
X    - right-hand-side of screen:
X
X	number of time steps done
X
X	numbers of births and deaths, and current number of bugs
X
X	average genotype of all bugs:
X
X	    l - likelihood of a shallow left turn
X	    L - likelihood of a sharp left turn
X	    b - likelihood of a backwards move
X	    R - likelihood of a sharp right turn
X	    r - likelihood of a shallow right turn
X	    s - likelihood of going straight
X
X	    values range from 1 - 9, and are powers of 2 + 1 of the actual
X	    likelihood figure
X
X	age of selected bug
X
X	power of selected bug
X
X	genotype of selected bug
X
X	graph of bug population over time, updated every 100 time steps
X
X    - click on a bug with the left mouse button to make it the selected bug.
X      It's state will be continuously displayed, and the bug will be drawn
X      as a larger, hollow, square instead of just a square
X
X    - click outside of the main display window, or activate any other window,
X      to deselect the selected bug
X
X    - the right-hand side of the display is directly on the screen RastPort,
X      so you can grab the screen by the drag bar up there and move it, or
X      use the foreground/background screen gadgets
X
X    - magic values used in this version (I know, it should have a bunch of
X      gadgets so you can change them!)
X
X	initial population: 16
X	maximum power: 1500
X	minimum power for reproduction: 1000 (light blue)
X	minimum age for reproduction: 500
X	maximum age before death by old age: 50000
X	    (if you lower this to, say, 5000, then you get a very cyclic
X	    population behavior, and they will sometimes die out)
X	new bacteria rain (food) per time step: 3
X	power imbued by eating one food: 12
X
X    - no "garden of Eden" implemented (pretty easy to add, but we wanted
X      to have input to the program first)
X
X    - this version is written using the V1.2 Draco compiler. It is available
X      on CompuServe and on Fish Disk #201. Incase you don't have it or
X      don't want to set it up, I've included the object file - its only
X      7K bytes.
X
X    - to rebuild: (assuming you have Draco V1.2, and all of the include
X      files needed under DRINC:, and all of the libraries needed and the
X      startup code under DRLIB:), then
X
X	draco jitter
X	blink with jitter.w
X
X    - authors: Chris Gray (Amiga specific stuff and a couple of Draco hints)
X      and Don Reble (all the rest).
X
X    - possible enhancements:
X	- add gadgets to control the key magic values
X	- allow editing of individual bugs
X	- add a whole food chain - combine this stuff with the "Sharks and
X	  Fish" idea from a few years back. You would have sharks which feed
X	  on the fish, which feed on the plants, which grow better where
X	  there are dead sharks or fish. Each (except likely the plants)
X	  would have their own gene-set.
X
XHave fun, and don't go blind watching the little devils!
SHAR_EOF
echo "extracting jitter.d"
sed 's/^X//' << \SHAR_EOF > jitter.d
X#drinc:exec/miscellaneous.g
X#drinc:exec/memory.g
X#drinc:exec/ports.g
X#drinc:exec/tasks.g
X#drinc:devices/inputEvent.g
X#drinc:graphics/gfx.g
X#drinc:graphics/view.g
X#drinc:graphics/rastport.g
X#drinc:intuition/miscellaneous.g
X#drinc:intuition/screen.g
X#drinc:intuition/window.g
X#drinc:intuition/intuiMessage.g
X#drinc:libraries/dos.g
X
Xuint
X    SCREEN_WIDTH = 640,
X    SCREEN_HEIGHT = 400,
X    SCREEN_DEPTH = 3,
X    SCREEN_COLOURS = 1 << SCREEN_DEPTH,
X    GADGETS_WIDTH = 80,
X
X    VIEW_WIDTH = SCREEN_WIDTH - 4 - 2 - GADGETS_WIDTH,
X    VIEW_HEIGHT = SCREEN_HEIGHT - 11,
X
X    MAX_X = VIEW_WIDTH / 4,
X    MAX_Y = VIEW_HEIGHT / 4 - 1,
X    WRAP_Y = 4 * MAX_Y,
X
X    ROW_SEP = 8 + 8 + 1 + 2,
X    STEP_ROW = 2,
X    POP_ROW = STEP_ROW + ROW_SEP,
X    BIRTH_ROW = POP_ROW + ROW_SEP,
X    DEATH_ROW = BIRTH_ROW + ROW_SEP,
X    PROB_ROW = DEATH_ROW + ROW_SEP,
X    AGE_ROW = PROB_ROW + ROW_SEP + ROW_SEP,
X    POWER_ROW = AGE_ROW + ROW_SEP,
X    BUG_PROB_ROW = POWER_ROW + ROW_SEP,
X
X    GRAPH_ZERO = SCREEN_WIDTH - GADGETS_WIDTH,
X    GRAPH_MAX = GRAPH_ZERO + 70,
X    GRAPH_TOP = BUG_PROB_ROW + ROW_SEP + 10,
X    GRAPH_BOTTOM = SCREEN_HEIGHT - 2,
X
X    CHAR_WIDTH = 8,
X
X    GRAPH_FREQ = 100;
X
Xuint
X    INIT_POP = 16,
X    MAX_POWER = 1500,
X    REP_POWER = 1000,
X    REP_AGE = 500,
X    OLD_AGE = 50000,
X    RAIN_QUAN = 3,
X    BACT_POWER = 12,
X    MAX_PROB = 256;
X
X*Screen_t Screen;
X*Window_t Window;
X*RastPort_t RastPort, ScreenRastPort;
X
X[SCREEN_COLOURS] uint COLOUR_TABLE = (
X    0x000,
X    0x777,
X    0xf00,
X    0xa72,
X    0xfc0,
X    0x6c0,
X    0x0cc,
X    0x55f
X);
X
Xtype
X    Direction_t = struct {
X	int d_x, d_y;
X    },
X
X    Bug_t = struct {
X	*Bug_t b_next;
X	Direction_t b_loc;
X	uint b_dir;
X	uint b_age;
X	uint b_power;
X	uint b_pSum;
X	[6] uint b_probs;
X    };
X
X[6] Direction_t DIR_DELTAS = (
X    ( 0, -1),
X    (+1, -1),
X    (+1,  0),
X    ( 0, +1),
X    (-1, +1),
X    (-1,  0)
X);
X
X*Bug_t Bugs, Favorite;
Xuint RandSeed;
X
X[9] [10] char Titles = (
X    "  Time   ",
X    "  Bugs   ",
X    " Births  ",
X    " Deaths  ",
X    "   lLbRrs",
X    "         ",
X    "   Age   ",
X    "  Power  ",
X    "   lLbRrs"
X);
X
Xulong Steps, Population, Births, Deaths;
X[6] uint ProbSums;
X
Xproc randNum(uint modulo)uint:
X    RandSeed := RandSeed * 2113 + 13367;
X    RandSeed := (RandSeed >> 8) + (RandSeed << 8);
X    RandSeed % modulo
Xcorp;
X
Xproc drawStat(register ulong stat; uint row)void:
X    uint LENGTH = 9;
X    [LENGTH] char buffer;
X    register int idx;
X
X    if stat > 999999999 then stat := 999999999; fi;
X    idx := LENGTH - 1;
X    while
X	buffer[idx] := stat % 10 + '0';
X	stat := stat / 10;
X	idx := idx - 1;
X	stat ~= 0
X    do
X    od;
X    while idx >= 0 do
X	buffer[idx] := ' ';
X	idx := idx - 1;
X    od;
X    Move(ScreenRastPort, VIEW_WIDTH + 2 + 2 + CHAR_WIDTH / 2, row + 26);
X    Text(ScreenRastPort, &buffer[0], LENGTH);
Xcorp;
X
Xproc drawProbs([6]uint probs; uint row)void:
X    register uint pidx, val, power;
X    register ulong stat;
X	
X    stat := 0;
X    for pidx from 5 downto 0 do
X	val := probs[pidx];
X	power := 0;
X	while val > 0 do
X	    val := val / 2;
X	    power := power + 1;
X	od;
X	if power > 9 then power := 9; fi;
X	stat := stat * 10 + power;
X    od;
X    drawStat(stat, row);
Xcorp;
X
Xproc drawProbAvgs()void:
X    [6] uint aves;
X    register uint pidx;
X
X    for pidx from 5 downto 0 do
X	aves[pidx] :=
X	    if Population = 0 then
X		0
X	    else
X		ProbSums[pidx] / Population
X	    fi;
X    od;
X    drawProbs(aves, PROB_ROW);
Xcorp;
X
Xproc drawStats()void:
X    drawStat(Steps, STEP_ROW);
X    drawStat(Population, POP_ROW);
X    drawStat(Births, BIRTH_ROW);
X    drawStat(Deaths, DEATH_ROW);
X    drawProbAvgs();
Xcorp;
X
Xproc drawBug(register *Bug_t bug; bool show)void:
X    register int px, py;
X
X    px := 4 * bug*.b_loc.d_x;
X    py := 4 * bug*.b_loc.d_y + 2 * bug*.b_loc.d_x;
X    if py >= WRAP_Y then py := py - WRAP_Y fi;
X    SetAPen(RastPort,
X	if show then
X	    bug*.b_power / (MAX_POWER / (SCREEN_COLOURS - 2) + 1) + 2
X	else
X	    0
X	fi);
X    if bug = Favorite then
X	Move(RastPort, px + 2, py + 10);
X	Draw(RastPort, px + 2, py + 13);
X	Draw(RastPort, px + 5, py + 13);
X	Draw(RastPort, px + 5, py + 10);
X	Draw(RastPort, px + 2, py + 10);
X    else
X	RectFill(RastPort, px + 2, py + 10, px + 4, py + 12);
X    fi;
Xcorp;
X
Xproc drawRain(register int px, py)void:
X    px := 4 * px;
X    py := 4 * py + px / 2;
X    if py >= WRAP_Y then py := py - WRAP_Y fi;
X    SetAPen(RastPort, 1);
X    ignore WritePixel(RastPort, px + 2, py + 12);
Xcorp;
X
Xproc testRain(register int px, py)bool:
X    px := 4 * px;
X    py := 4 * py + px / 2;
X    if py >= WRAP_Y then py := py - WRAP_Y fi;
X    ReadPixel(RastPort, px + 2, py + 12) = 1
Xcorp;
X
Xproc makeInitialBugs()void:
X    register uint bugnum, pidx;
X    register *Bug_t newbug;
X
X    Bugs := nil;
X    for bugnum from INIT_POP-1 downto 0 do
X	newbug := AllocMem(sizeof(Bug_t), 0);
X	newbug*.b_next := Bugs;
X	Bugs := newbug;
X	newbug*.b_loc.d_x := randNum(MAX_X);
X	newbug*.b_loc.d_y := randNum(MAX_Y);
X	newbug*.b_dir := randNum(6);
X	newbug*.b_age := 0;
X	newbug*.b_power := MAX_POWER / 2;
X	newbug*.b_pSum := 0;
X	for pidx from 5 downto 0 do
X	    newbug*.b_probs[pidx] := 1 << randNum(7);
X	    newbug*.b_pSum := newbug*.b_pSum + newbug*.b_probs[pidx];
X	    ProbSums[pidx] := ProbSums[pidx] + newbug*.b_probs[pidx];
X	od;
X	drawBug(newbug, true);
X    od;
X    Population := INIT_POP;
X    Births := INIT_POP;
Xcorp;
X
Xproc initStuff()void:
X    DateStamp_t ds;
X    register uint idx;
X
X    SetAPen(ScreenRastPort, 1);
X    Move(ScreenRastPort, SCREEN_WIDTH - 2, 11);
X    Draw(ScreenRastPort, SCREEN_WIDTH - 2, SCREEN_HEIGHT - 2);
X    Move(ScreenRastPort, SCREEN_WIDTH - 1, 11);
X    Draw(ScreenRastPort, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 2);
X    Move(ScreenRastPort, SCREEN_WIDTH - GADGETS_WIDTH, SCREEN_HEIGHT - 1);
X    Draw(ScreenRastPort, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
X    for idx from 9 downto 1 do
X	Move(ScreenRastPort, VIEW_WIDTH + 5, 11 + ROW_SEP * idx);
X	Draw(ScreenRastPort, SCREEN_WIDTH - 2, 11 + ROW_SEP * idx);
X	Move(ScreenRastPort, VIEW_WIDTH + 8, ROW_SEP * idx);
X	Text(ScreenRastPort, &Titles[idx - 1][0], 9);
X    od;
X    DateStamp(&ds);
X    RandSeed := ds.ds_Tick;
X    Steps := 0;
X    Deaths := 0;
X    makeInitialBugs();
X    Favorite := nil;
X    drawStats();
Xcorp;
X
Xproc rainBact()void:
X    register uint count;
X
X    for count from RAIN_QUAN - 1 downto 0 do
X	drawRain(randNum(MAX_X), randNum(MAX_Y));
X    od;
Xcorp;
X	
Xproc mutate(register *Bug_t bug)void:
X    bool double;
X    register uint pidx;
X
X    pidx := randNum(6);
X    if bug*.b_probs[pidx] = 1 then
X	double := true;
X    elif bug*.b_probs[pidx] >= MAX_PROB then
X	double := false;
X    else
X	double := randNum(2) = 0;
X    fi;
X    bug*.b_pSum := bug*.b_pSum - bug*.b_probs[pidx];
X    if double then
X	ProbSums[pidx] := ProbSums[pidx] + bug*.b_probs[pidx];
X	bug*.b_probs[pidx] := bug*.b_probs[pidx] * 2;
X    else
X	bug*.b_probs[pidx] := bug*.b_probs[pidx] / 2;
X	ProbSums[pidx] := ProbSums[pidx] - bug*.b_probs[pidx];
X    fi;
X    bug*.b_pSum := bug*.b_pSum + bug*.b_probs[pidx];
X    if bug = Favorite then
X	drawProbs(Favorite*.b_probs, BUG_PROB_ROW);
X    fi;
Xcorp;
X
Xproc reproduce(register *Bug_t bug)void:
X    register *Bug_t newbug;
X    register uint pidx;
X
X    newbug := AllocMem(sizeof(Bug_t), 0);
X    if newbug ~= nil then
X	bug*.b_age := 0;
X	newbug* := bug*;
X	newbug*.b_power := newbug*.b_power / 2;
X	bug*.b_power := bug*.b_power - newbug*.b_power;
X	newbug*.b_next := bug*.b_next;
X	bug*.b_next := newbug;
X	for pidx from 5 downto 0 do
X	    ProbSums[pidx] := ProbSums[pidx] + bug*.b_probs[pidx];
X	od;
X	mutate(bug);
X	mutate(newbug);
X	drawProbAvgs();
X	Population := Population + 1;
X	Births := Births + 1;
X	drawStat(Population, POP_ROW);
X	drawStat(Births, BIRTH_ROW);
X    fi;
Xcorp;
X
Xproc moveBug(register *Bug_t bug)void:
X    register int rnd, idx;
X
X    bug*.b_age := bug*.b_age + 1;
X    bug*.b_power := bug*.b_power - 1;
X    rnd := randNum(bug*.b_pSum);
X    idx := 0;
X    while rnd >= 0 do
X	rnd := rnd - bug*.b_probs[idx];
X	idx := idx + 1;
X    od;
X    bug*.b_dir := (bug*.b_dir + idx - 1) % 6;
X    bug*.b_loc.d_x := bug*.b_loc.d_x + DIR_DELTAS[bug*.b_dir].d_x;
X    bug*.b_loc.d_y := bug*.b_loc.d_y + DIR_DELTAS[bug*.b_dir].d_y;
X    if bug*.b_loc.d_x >= MAX_X then
X	bug*.b_loc.d_x := 0;
X	bug*.b_loc.d_y := bug*.b_loc.d_y + MAX_X / 2;
X    elif bug*.b_loc.d_x < 0 then
X	bug*.b_loc.d_x := MAX_X - 1;
X	bug*.b_loc.d_y := bug*.b_loc.d_y - MAX_X / 2;
X    fi;
X    while bug*.b_loc.d_y >= MAX_Y do
X	bug*.b_loc.d_y := bug*.b_loc.d_y - MAX_Y;
X    od;
X    while bug*.b_loc.d_y < 0 do
X	bug*.b_loc.d_y := bug*.b_loc.d_y + MAX_Y;
X    od;
X    if testRain(bug*.b_loc.d_x, bug*.b_loc.d_y) then
X	bug*.b_power := bug*.b_power + BACT_POWER;
X	if bug*.b_power > MAX_POWER then
X	    bug*.b_power := MAX_POWER;
X	fi;
X    fi;
Xcorp;
X
Xproc killBug(register *Bug_t bug)void:
X    register uint pidx;
X	
X    Deaths := Deaths + 1;
X    Population := Population - 1;
X    for pidx from 5 downto 0 do
X	ProbSums[pidx] := ProbSums[pidx] - bug*.b_probs[pidx];
X    od;
X    drawBug(bug, false);
X    if Favorite = bug then Favorite := nil; fi;
X    FreeMem(bug, sizeof(Bug_t));
X    drawStat(Deaths, DEATH_ROW);
X    drawStat(Population, POP_ROW);
Xcorp;
X
Xproc doBug(register ***Bug_t bugptr)void:
X    register *Bug_t bug;
X
X    bug := bugptr**;
X    if bug*.b_age >= REP_AGE and bug*.b_power >= REP_POWER then
X	reproduce(bug);
X    fi;
X    if bug*.b_power = 0 or bug*.b_age > OLD_AGE then
X	bugptr** := bug*.b_next;
X	killBug(bug);
X    else
X	drawBug(bug, false);
X	moveBug(bug);
X	drawBug(bug, true);
X	bugptr* := &bug*.b_next;
X    fi;
Xcorp;
X
Xproc stepGraph()void:
X
X    ScrollRaster(ScreenRastPort, 0, -1,
X		 GRAPH_ZERO, GRAPH_TOP, GRAPH_MAX, GRAPH_BOTTOM);
X    ignore WritePixel(ScreenRastPort, GRAPH_ZERO + Population, GRAPH_TOP);
Xcorp;
X
Xproc timeStep()void:
X    **Bug_t bugptr;
X
X    Steps := Steps + 1;
X    if Steps % GRAPH_FREQ = 0 then
X	stepGraph();
X    fi;
X    drawStat(Steps, STEP_ROW);
X    rainBact();
X    bugptr := &Bugs;
X    while bugptr* ~= nil do
X	doBug(&bugptr);
X    od;
X    if Favorite ~= nil then
X	drawStat(Favorite*.b_age, AGE_ROW);
X	drawStat(Favorite*.b_power, POWER_ROW);
X    fi;
Xcorp;
X
Xproc pickFavorite(register int px, py)void:
X    register int dx, dy, mdist, dist;
X    register *Bug_t bug, nearbug;
X
X    py := py - px / 2;
X    if py < 0 then py := py + WRAP_Y; fi;
X    px := px / 4;
X    py := py / 4;
X    bug := Bugs;
X    if bug ~= nil then
X	mdist := 0x7fff;
X	while bug ~= nil do
X	    dx := | (bug*.b_loc.d_x - px);
X	    dy := | (bug*.b_loc.d_y - py);
X	    if dx > MAX_X / 2 then dx := MAX_X - dx; fi;
X	    if dy > MAX_Y / 2 then dy := MAX_Y - dy; fi;
X	    dist := dx + dy;
X	    if dist < mdist then
X		mdist := dist;
X		nearbug := bug;
X	    fi;
X	    bug := bug*.b_next;
X	od;
X	if Favorite ~= nil then
X	    drawBug(Favorite, false);
X	    drawBug(nearbug, false);
X	    bug := Favorite;
X	    Favorite := nearbug;
X	    drawBug(bug, true);
X	    drawBug(Favorite, true);
X	else
X	    drawBug(nearbug, false);
X	    Favorite := nearbug;
X	    drawBug(Favorite, true);
X	fi;
X	drawProbs(Favorite*.b_probs, BUG_PROB_ROW);
X    fi;
Xcorp;
X
Xproc cancelFavorite()void:
X    *Bug_t bug;
X
X    if Favorite ~= nil then
X	drawBug(Favorite, false);
X	bug := Favorite;
X	Favorite := nil;
X	drawBug(bug, true);
X    fi;
Xcorp;
X
Xproc handleMessage(register *IntuiMessage_t im)bool:
X    ulong class;
X    uint which;
X    int mouseX, mouseY;
X    bool quit;
X
X    quit := false;
X    class := im*.im_Class;
X    which := im*.im_Code;
X    mouseX := im*.im_MouseX;
X    mouseY := im*.im_MouseY;
X    ReplyMsg(&im*.im_ExecMessage);
X    case class
X    incase CLOSEWINDOW:
X	quit := true;
X    incase INACTIVEWINDOW:
X	cancelFavorite();
X    incase MOUSEBUTTONS:
X	if which = IECODE_UP_PREFIX | IECODE_LBUTTON then
X	    pickFavorite(mouseX, mouseY);
X	fi;
X    esac;
X    quit
Xcorp;
X
Xproc doStuff()void:
X    register *IntuiMessage_t im;
X    register *Bug_t oldbug;
X    register bool quit;
X
X    initStuff();
X    quit := false;
X    while not quit and Population ~= 0 do
X	timeStep();
X	im := pretend(GetMsg(Window*.w_UserPort), *IntuiMessage_t);
X	if im ~= nil then
X	    quit := handleMessage(im);
X	fi;
X    od;
X    while not quit do
X	ignore Wait(1 << Window*.w_UserPort*.mp_SigBit);
X	while
X	    im := pretend(GetMsg(Window*.w_UserPort), *IntuiMessage_t);
X	    im ~= nil
X	do
X	    quit := handleMessage(im);
X	od;
X    od;
X    while Bugs ~= nil do
X	oldbug := Bugs;
X	Bugs := Bugs*.b_next;
X	FreeMem(oldbug, sizeof(Bug_t));
X    od;
Xcorp;
X
Xproc main()void:
X    NewWindow_t nw;
X
X    if OpenExecLibrary(0) ~= nil then
X	ignore SetTaskPri(FindTask(nil), -5);
X	if OpenGraphicsLibrary(0) ~= nil then
X	    if OpenIntuitionLibrary(0) ~= nil then
X		if OpenDosLibrary(0) ~= nil then
X		    Screen := OpenScreen(&NewScreen_t(
X			0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH,
X			0, 1, LACE | HIRES, CUSTOMSCREEN, nil, nil, nil, nil));
X		    if Screen ~= nil then
X			ScreenRastPort := &Screen*.sc_RastPort;
X			LoadRGB4(&Screen*.sc_ViewPort, &COLOUR_TABLE[0],
X				 SCREEN_COLOURS);
X			nw := NewWindow_t(
X			    0, 0, SCREEN_WIDTH - GADGETS_WIDTH, SCREEN_HEIGHT,
X			    FREEPEN, FREEPEN,
X			    CLOSEWINDOW | MOUSEBUTTONS | INACTIVEWINDOW,
X			    WINDOWCLOSE | SIMPLE_REFRESH | ACTIVATE |
X				NOCAREREFRESH,
X			    nil, nil, nil, nil, nil, 0, 0, 0, 0,
X			    CUSTOMSCREEN);
X			nw.nw_Title := "Jitter by Don & Chris";
X			nw.nw_Screen := Screen;
X			Window := OpenWindow(&nw);
X			if Window ~= nil then
X			    RastPort := Window*.w_RPort;
X			    doStuff();
X			    CloseWindow(Window);
X			fi;
X			CloseScreen(Screen);
X		    fi;
X		    CloseDosLibrary();
X		fi;
X		CloseIntuitionLibrary();
X	    fi;
X	    CloseGraphicsLibrary();
X	fi;
X	CloseExecLibrary();
X    fi;
Xcorp;
SHAR_EOF
echo "extracting jitter.uu"
sed 's/^X//' << \SHAR_EOF > jitter.uu
X
Xbegin 644 jitter
XM```#\P`````````'``````````8````"````#@````$````!`````0````$`7
XM``4D```#Z0````).^0```````````^P````!````!@````(````````#\@``+
XM`^L````.```#\@```^L````!```#\`````)?1$]30F%S90`````````````#8
XM\@```^L````!```#\`````1?26YT=6ET:6]N0F%S90````````````````/RJ
XM```#ZP````$```/P`````E]'9GA"87-E``````````````/R```#ZP````$`'
XM``/P`````E]3>7-"87-E``````````````/R```#Z0``!20CP````!(CR```X
XM`!9.^0``#H0`````````````3E8``$CG`P`^.0```!C._`A!WGPT-S/'````F
XM&.!//#D````8X4[>1C/'````&`*'``#__X[N``A(1R`'3-\`P$Y>(%]4CT[01
XM3E;_]DCG#P`N+@`*#(<[FLG_8P8N/#N:R?\\/``((`=R"DZY```01"H!>##:(
XMA!V%8/<@!W(*3KD``!!T+@!31DJ'9MI*1FT*';P`(&#W4T9@\B\Y````#"\\D
XM```",CHN``AX&MI$`H4``/__+P5.N0``$H`O.0````Q(;O_W<`DO`$ZY```2'
XM.$S?`/!.7B!?7(].T$Y6``!(YS\$0H1^!38'*FX`"N-+/#4P`$)%2D9C!N).$
XM4D5@]@Q%``EC!#H\``D@!'(*3KD``!`P)@!"@C0%UH(H`U'/_\@O!#\N``A.7
XMN0```&1,WR#\3EX@7UR/3M!.<4Y6__1(YP\`?@4\!^-.*CD````>9@1"A&`F:
XM.@?C32!\````*CHP4``H.0```!X"A0``__\B!"`%3KD``!!$*``]A&#T4<__W
XMQ$AN__1P3C\`3KD```#X3-\`\$Y>3G5.<2\Y````&G`"/P!.N0```&0O.0``X
XM`!YP%3\`3KD```!D+SD````B<"@_`$ZY````9"\Y````)G`[/P!.N0```&1.*
XMN0```5A.=4Y6``!(YP\$*FX`"CHM``3E13X%.BT`!N5%."T`!.-$VD0\!0Q&-
XM`8!M!`1&`8`O.0````A*+@`(9Q!"A3HM``PX/`#[BL1416`"0D4"A0``__\O1
XM!4ZY```30+OY````%&8``)HO.0````@Z!U1%2,4O!3H&>`K:1$C%+P5.N0``:
XM$H`O.0````@Z!U1%2,4O!3H&>`W:1$C%+P5.N0``$J0O.0````@Z!UI%2,4O*
XM!3H&>`W:1$C%+P5.N0``$J0O.0````@Z!UI%2,4O!3H&>`K:1$C%+P5.N0``?
XM$J0O.0````@Z!U1%2,4O!3H&>`K:1$C%+P5.N0``$J1@,"\Y````"#H'5$5(!
XMQ2\%.@9X"MI$2,4O!3H'6$5(Q2\%.@9X#-I$2,4O!4ZY```2R$S?(/!.7B!?C
XM7(].T$Y6``!(YP\`/BX`"CPN``CE1SH&Y44X!VP"4D3B1-I$/`4,1@&`;00$Y
XM1@&`+SD````(<`$O`$ZY```30"\Y````"#H'5$5(Q2\%.@9X#-I$2,4O!4ZYF
XM```3'$S?`/!.7B!?6(].T$YQ3E8``$CG#P`^+@`*/"X`".5'.@;E13@';`)28
XM1.)$VD0\!0Q&`8!M!`1&`8`O.0````@Z!U1%2,4O!3H&>`S:1$C%+P5.N0``-
XM$O@,```!9P1"!6`">@$@!4S?`/!.7B!?6(].T$CG'P1"N0```!!^#W`<+P!"]
XMITZY```3W"I`*KD````0(\T````0/SP`BDZY````'#M```1P8#\`3KD````<3
XM.T``!G`&/P!.N0```!P[0``(0FT`"CM\`NX`#$)M``Y\!3H&XTUX`7`'/P!.S
XMN0```!SAK#N$4!`Z+0`..`;C3-IU0!`[10`..@;C33@&XTP@?````"HX,$``;
XM-@;C2]AU,!`@?````"HQA%``4<[_M"\-<`$?`$ZY```"`%'/_U!P$"/`````[
XM'G`0(\`````B3-\@^$YU3E;_]$CG!P0O.0````QP`2\`3KD``!-`+SD````,<
XM+SP```)^<`LO`$ZY```2@"\Y````#"\\```"?B\\```!CDZY```2I"\Y````L
XM#"\\```"?W`++P!.N0``$H`O.0````PO/````G\O/````8Y.N0``$J0O.0``Z
XM``PO/````C`O/````8].N0``$H`O.0````PO/````G\O/````8].N0``$J1^3
XM"2\Y````#"\\```"+SP'>A/,Q7H+W$4"A@``__\O!DZY```2@"\Y````#"\\3
XM```"?CP'>A/,Q7H+W$4"A@``__\O!DZY```2I"\Y````#"\\```",CP'>A/,N
XMQ0*&``#__R\&3KD``!*`+SD````,0?H`;"I(/`=31@*&``#__R`&(CP````*6
XM3KD``!`(+`!(=6@`<`DO`$ZY```2.%-'9@#_8$AN__1.N0``$2@L+O_\,\8`_
XM```80KD````:0KD````F3KD```0$0KD````43KD```&X3-\@X$Y>3G4@(%1I#
XM;64@("``("!"=6=S("`@`"!":7)T:',@(``@1&5A=&AS("``("`@;$QB4G)S9
XM`"`@("`@("`@(``@("!!9V4@("``("!0;W=E<B`@`"`@(&Q,8E)R<P`O!WX"A
XM/SP`BDZY````'#\`<&`_`$ZY````'#\`3KD```,X4<__X"X?3G5.<4Y6__Y(1
XMYP\,*FX`"'`&/P!.N0```!P^`#P`XTX,=0`!8!!F"!U\``'__V`J/`?C3@QU<
XM`0!@$&4&0B[__V`8<`(_`$ZY````'$I`9P1"!F`"?`$=1O__/"T`#CH'XTV<7
XM=5`0.T8`#DHN__]G.#P'XTXZ!^--('P````J.C!0`#@'XTS:=4`0('P````JQ
XM,85@`#P'XTXZ!^--.C50$.--.X5@$&`V/`?C3CH'XTTZ-5`0XDT[A6`0/`?CY
XM3CH'XTT@?````"HZ,%``.`?C3)IU0!`@?````"HQA6``/"T`#CH'XTW<=5`0!
XM.T8`#KOY````%&84*'D````42&P`$#\\`)I.N0```/A,WS#P3EX@7UB/3M!.G
XM<4Y6``!(YP\\*FX`"'`<+P!"ITZY```3W"A`(`!G``"80FT`"B9,)$UP&Q;:G
XM4<C__#PL``SB3CE&``P\+0`,G&P`##M&``PHE2J,?@4\!^-..@?C32!\````0
XM*CHP4``X!^-,VG5`$"!\````*C&%8`!1S__:+PU.N0``!N`O#$ZY```&X$ZY>
XM```!6%*Y````'E*Y````(B\Y````'G`5/P!.N0```&0O.0```")P*#\`3KD`,
XM``!D3-\\\$Y>(%]8CT[03G%.5@``2.</#"IN``A2;0`*4VT`##\M``Y.N0``.
XM`!P^`$)&2D=M$#H'.`;C3)IU0!`^!5)&8.PZ+0`(VD9314C%>`:+Q$A%.T4`R
XM"#HM``1!^@"^*$@X+0`(Y4S:=$``.T4`!#HM``9!^@"F*$@X+0`(Y4S:=$`"X
XM.T4`!@QM`(H`!&T20FT`!#HM``9X1=I$.T4`!F`8.BT`!&P2.WP`B0`$.BT`9
XM!GA%FD0[10`&#&T`8``&;0XZ+0`&>&":1#M%``9@ZCHM``9L#CHM``9X8-I$^
XM.T4`!F#L/RT`!#\M``9.N0```Z!*`&<:.BT`#'@,VD0[10`,#&T%W``,8P8[4
XM?`7<``Q,WS#P3EX@7UB/3M```/__``'__P`!```````!__\``?__``!.<4Y6#
XM``!(YP\,*FX`"%*Y````)E.Y````'GX%/`?C3CH'XTT@?````"HZ,%``.`?C/
XM3)IU0!`@?````"HQA6``4<__VB\-0B=.N0```@`H>0```!2[S&8&0KD````4E
XM+PUP'"\`3KD``!/X+SD````F<#L_`$ZY````9"\Y````'G`5/P!.N0```&1,M
XMWS#P3EX@7UB/3M!.5@``2.<!'"IN``@F52A3#&P!]``*91`,;`/H``QE""\,X
XM3KD```?T/BP`#&<(#&S#4``*8PXF52:4+PQ.N0``">!@("\,0B=.N0```@`OI
XM#$ZY```(N"\,<`$?`$ZY```"`"J,3-\X@$Y>(%]8CT[0+P<O.0````Q"IW#_R
XM+P`O/````C`O/````+<O/````G8O/````8Y.N0``$UPO.0````PN.0```![>8
XMO````C`O!R\\````MTZY```3'"X?3G5.5O_\2.<!!%*Y````&B`Y````&G)D-
XM3KD``!!$+@%F!DZY```*Y"\Y````&G`"/P!.N0```&1.N0``!K1+^0```!`M+
XM3?_\*F[__"`59PQ(;O_\3KD```IT8.P@.0```!1G,"IY````%$*'/BT`"B\'T
XM<'0_`$ZY````9"IY````%$*'/BT`#"\'/SP`ATZY````9$S?((!.7DYU3G%.O
XM5O_\2.<_'#XN``H\+@`(-@8T!VP"4D+B0I9"/`-L!`9&`8`V!VP"5D/D0SX#@
XM-@9L`E9#Y$,\`RIY````$"`-9P``UCU\?____B`-9TPV+0`$ED=L`D1#.@,V&
XM+0`&ED9L`D1#.`,,10!%;P@V/`"*ED4Z`PQ$`#!O!G9@ED0X`S8%UD0]0__\0
XMMF[__FP(/6[__/_^*$TJ56"P(#D````49T(O.0```!1")TZY```"`"\,0B=.R
XMN0```@`J>0```!0CS````!0O#7`!'P!.N0```@`O.0```!1P`1\`3KD```(`?
XM8"`O#$(G3KD```(`(\P````4+SD````4<`$?`$ZY```"`"9Y````%$AK`!`_Z
XM/`":3KD```#X3-\X_$Y>(%]8CT[03E;__"`Y````%&<J+SD````40B=.N0``M
XM`@`M>0```!3__$*Y````%"\N__QP`1\`3KD```(`3EY.=4YQ3E;_]$CG`00J:
XM;@`(0B[_]2UM`!3__#UM`!C_^CUM`"#_^#UM`"+_]B\-3KD``!1X+B[__&``&
XM`#`=?``!__5@``!03KD```ST8```1@QN`.C_^F8./R[_^#\N__9.N0``"]!@R
XM```L(`=!^@`(3OD``!"D```-D@`#````"```#7P```(````-:``(``````UR"
XM'B[_]2`'3-\@@$Y>(%]8CT[03G%(YP\<3KD```380@<<!V8P*CD````>9RA.^
XMN0``"S0F>0````0O*P!63KD``!1@*D`@`&<*+PU.N0``#3`>`&#,'`=F/GH!-
XM)GD````$)FL`5A@K``_IK2\%3KD``!1()GD````$+RL`5DZY```48"I`(`!G(
XM#"\-3KD```TP'@!@WF"^(#D````09R`H>0```!`F>0```!`CTP```!`O#'`<C
XM+P!.N0``$_A@V$S?./!.=4Y6_]!(YP`,0J=.N0``$Y1G``#TF\TO#4ZY```4N
XM%"\`</LO`$ZY```4+$*G3KD``!'L9P``S$*G3KD``!%`9P``ND*G3KD``!#D*
XM9P``J$'Z`00O"$ZY```1O"/``````&<``(PJ>0````!+[0!4(\T````,*GD`^
XM````2&T`+$'Z`/0O"'`(+P!.N0``$EQ+[O_00?H`D"A(<"\:W%'(__Q!^@!LV
XM+4C_ZBUY`````/_N2&[_T$ZY```1U"/`````!&<@*GD````$(^T`,@````A./
XMN0``#=0O.0````1.N0``$:0O.0````!.N0``$8Q.N0``$1!.N0``$71.N0``)
XM$B!.N0``$\1,WS``3EY.=4II='1E<B!B>2!$;VX@)B!#:')I<P```````C`!:
XMD/__``@""``"$$@```````````````````````````````````````\`````)
XM`H`!D``#``&`!``/````````````````````````!W</``IR#\`&P`#,!5\OG
XM`B\#-`#$P28`2$/&P4A#0D/4@TA!PL!(04)!U($@`B8?)!].=0``+P(D`,#![
XM2$+$P4A"0D+0@B0?3G5*@&8$0H%.=4J!9@1"@$YU+P(O`T*"=A_C@..2M(%E7
XM!)2!4H!1R__R(@(F'R0?3G5*068$0H!.=8#!:```&B\"2$!"@C0`A,$P`DA`4
XM-`"$P3`")!].=0*```#__TYU``!(IS@`0D(V*``$4D,R`M)#XD$X`>=$L+!`&
XM_F<88@0V`6`"-`$X`E)$MD1FX"!03)\`'$[0('!``DR?`!Q.T```(E\@'R\)%
XM0_H`&"\.+'D````$3J[]V"Q?(\``````3G5D;W,N;&EB<F%R>0`B>0`````OP
XM#BQY````!$ZN_F(L7TYU```O#B(O``@L>0````!.KO]`+%\B7UB/3M$B7R`?I
XM+PE#^@`8+PXL>0````1.KOW8+%\CP`````!.=6EN='5I=&EO;BYL:6)R87)Y[
XM````(GD`````+PXL>0````1.KOYB+%].=0``+PX@;P`(+'D`````3J[_OBQ?H
XM(E]8CT[1+PX@;P`(+'D`````3J[_N"Q?(E]8CT[1+PX@;P`(+'D`````3J[_Y
XM.BQ?(E]8CT[1+PX@;P`(+'D`````3J[_-"Q?(E]8CT[1(E\@'R\)0_H`&"\.0
XM+'D````$3J[]V"Q?(\``````3G5G<F%P:&EC<RYL:6)R87)Y`````")Y````Z
XM`"\.+'D````$3J[^8BQ?3G4``"\.(F\`$"!O``P@+P`(+'D`````3J[_Q"Q?/
XM(E_>_``,3M$``"\.(&\`$")O``P@+P`(+'D`````3J[_0"Q?(E_>_``,3M$`'
XM`"\.(F\`$"`O``PB+P`(+'D`````3J[_$"Q?(E_>_``,3M$``"\.(F\`$"`O`
XM``PB+P`(+'D`````3J[_"BQ?(E_>_``,3M$``$CG,`(B;P`@("\`'"(O`!@DJ
XM+P`4)B\`$"QY`````$ZN_LY,WT`,(E_>_``43M$``"\.(F\`$"`O``PB+P`(L
XM+'D`````3J[^PBQ?(E_>_``,3M$``"\.(F\`$"`O``PB+P`(+'D`````3J[^C
XMO"Q?(E_>_``,3M$``"\.(F\`#"`O``@L>0````!.KOZJ+%\B7U"/3M%(YSP"^
XM(F\`,"`O`"PB+P`H)"\`)"8O`"`H+P`<*B\`&"QY`````$ZN_G1,WT`\(E_>>
XM_``<3M$``")?(!\O"4/Z`!@O#BQY````!$ZN_=@L7R/``````$YU97AE8RYLK
XM:6)R87)Y`````")Y`````"\.+'D````$3J[^8BQ?3G4``"\.("\`#"(O``@L1
XM>0````!.KO\Z+%\B7U"/3M$O#B)O``P@+P`(+'D`````3J[_+BQ?(E]0CT[1!
XM+PXB;P`(+'D`````3J[^VBQ?(E]8CT[1+PXB;P`,("\`""QY`````$ZN_M0LQ
XM7R)?4(].T2\.("\`""QY`````$ZN_L(L7R)?6(].T2\.(&\`""QY`````$ZN:
XM_HPL7R)?6(].T2\.(F\`""QY`````$ZN_H8L7R)?6(].T0```^P```!K````#
XM`0``#U````]<```/2```#T````[T```/:```#RX```[Z```.Z@``#N````YL/
XM```.9@``#F````Y8```.-```#AP```WT```-Y@``#1@```T0```-`@``#/H`_
XM``S6```,Q@``#,````RD```,D@``#(P```QT```,;```#`H```NP```+F```2
XM"Y````MR```+7```"T0```L^```+&```"Q(```KH```*.```"BX```H6```*M
XM!```"EH```GT```*2@``">X```B<```(A@``"(P```B````(7```"$H```?4/
XM```'S```![(```>@```':```!U8```9(```&/```!C8```8P```%Z```!<@`[
XM``6D```%@```!68```5.```%-@``!2````4(```$\@``!.(```3.```$Q@``1
XM!*8```24```$)@``!"````0*```#S@```W8```-F```"7````OX```+>```"1
XMP````J(```*$```"9@```C````'J```!V@```<H```&Z```!>````8(```%HU
XM````V@```+@```!&````/````#0````F`````P````(``!$P```1$@``$/X`E
XM```&`````P``$=P``!'$```1K```$90``!%V```16@````L````$```3?@``_
XM$TP``!,L```3"```$N(``!*T```2D```$FP``!)(```2(@``$@8````)````"
XM!0``%(```!1H```44```%#@``!0<```4!```$^@``!/&```3K@```'@````&@
XM```.V@``#W0```Z0```/>@``#X8```Z^```/.@``#PX```[*```.L@``#U8`6
XM``Z>```/8@``#X````ZJ```/;@``#BX```W:```.#```#DP```WN```.>```Y
XM#?X```X^```-=```#9X```V.```-7```#;P```VT```-K```#:(```T*```-=
XM)@``#.0```Q\```,A@``#)X```RN```,N@``#-````M,```+;```"U8```MF6
XM```+J@``"\(```N(```++```"PP```JR```*F```"L8```J^```*T@``"E0`3
XM``ID```*1```"B@```F8```(T@``")8```BF```(;```"'0```@(```(>@``W
XM!^(```;R```')```!M(```:^```&R@``!D(```4"```%,```!6````6>```%)
XMX@``!A8```8F```&3@``!1H```5(```%>```!<(```3L```&!@``!#````0^@
XM```$3```!'````08```$N@```^8```..```#<````R@```)^```"G````KH`0
XM``+8```"]@```E8```'$```!U````>0```'T```!^@```9(```&J```!+```$
XM`48```"(````G````-0```#H````#@````@````"`````````_`````"4F5P;
XM;'E-<V<``!1X`````D=E=$US9P`````48`````%786ET```42`````-39714*
XM87-K4')I`````!0L`````D9I;F1487-K```4%`````)&<F5E365M````$_@`6
XM```"06QL;V--96T``!/<````!$-L;W-E17AE8TQI8G)A<GD``!/$````!$]PI
XM96Y%>&5C3&EB<F%R>0```!.4`````U-C<F]L;%)A<W1E<@``$UP````"4V5T4
XM05!E;@```!-``````U=R:71E4&EX96P`````$QP````#4F5A9%!I>&5L````W
XM```2^`````)296-T1FEL;```$L@````!1')A=P``$J0````!36]V90``$H``J
XM```"3&]A9%)'0C0``!)<`````51E>'0``!(X````!4-L;W-E1W)A<&AI8W-,G
XM:6)R87)Y```2(`````5/<&5N1W)A<&AI8W-,:6)R87)Y````$>P````#3W!E\
XM;E=I;F1O=P`````1U`````-/<&5N4V-R965N`````!&\`````T-L;W-E5VENT
XM9&]W````$:0````#0VQO<V538W)E96X````1C`````9#;&]S94EN='5I=&EO&
XM;DQI8G)A<GD``````!%T````!4]P96Y);G1U:71I;VY,:6)R87)Y```10```(
XM``-$871E4W1A;7```````!$H````!$-L;W-E1&]S3&EB<F%R>0```!$0````5
XM!$]P96Y$;W-,:6)R87)Y`````!#D`````E]D7V-A<V5L```0I`````-?9%]DN
XM:78S,G4R`````!!T`````U]D7V1I=C,R=0``````$$0````#7V1?;75L,S(R/
XM```````0,`````)?9%]M=6PS,@``$`@````"7W-T87)T`````````````U]D$
XJ7W!A<DQE;@```````!(````#7V1?<&%R4V%V90``````%@````````/R5
X``
Xend
Xsize 7332
SHAR_EOF
echo "extracting jitter.w"
sed 's/^X//' << \SHAR_EOF > jitter.w
Xfrom drlib:drstart0.o+jitter.r
Xlibrary drlib:draco.lib+drlib:dos.lib+drlib:intuition.lib+drlib:graphics.lib+*
Xdrlib:exec.lib
Xsmallcode
Xto jitter
SHAR_EOF
echo "End of archive 1 (of 1)"
# if you want to concatenate archives, remove anything after this line
exit