EyeHack:
CEDAR
PROGRAM
IMPORTS BasicTime, DefaultRemoteNames, Graphics, GraphicsOps, NewerBottom, Process, Random, Rope
= {
ROPE: TYPE = Rope.ROPE;
loaded: BOOL ← FALSE;
images: ARRAY ImageIndex OF Image;
ImageIndex: TYPE = NAT [0 .. ImageCount);
ImageCount: NAT = 4;
Image:
TYPE =
RECORD [
ir: Graphics.ImageRef ← NIL,
yFudge: INTEGER ← 0];
imageBox: IntBox ← [-50, -32, 50, 100-32];
IntBox: TYPE = RECORD [xmin, ymin, xmax, ymax: INT];
imageRadius: REAL ← 31;
screenBitmap: GraphicsOps.BitmapRef ← GraphicsOps.ScreenBitmap[];
quitProb: REAL ← 0.01;
idleMin: INT ← 360;
idleMax: INT ← 3600;
posMin: INT ← 300;
posMax: INT ← 1000;
posMsecs: INT;
Hack:
PROC = {
cx, cy: INTEGER;
circle: Graphics.Path;
first: BOOL ← TRUE;
myC: Graphics.Context ← Graphics.NewContext[];
EnsureLoaded[];
cx ← Random.Choose[1 - imageBox.xmin, screenBitmap.width-1 - imageBox.xmax];
cy ← Random.Choose[1 - imageBox.ymin, screenBitmap.height-1 - imageBox.ymax];
circle ← NewerBottom.Circle[cx, cy, imageRadius];
Graphics.ClipArea[myC, circle];
DO
i: ImageIndex ← Random.Choose[0, ImageCount-1];
Graphics.SetCP[myC, cx + imageBox.xmin, cy + imageBox.ymin + images[i].yFudge];
Graphics.DrawImage[myC, images[i].ir];
IF first THEN NewerBottom.DoXFormer[[clipPath: circle, clipByPath: TRUE], FALSE];
first ← FALSE;
posMsecs ← Random.Choose[posMin, posMax];
Process.Pause[Process.MsecToTicks[posMsecs]];
IF Random.Choose[1, 1000]/1000.0 <= quitProb THEN EXIT;
ENDLOOP;
NewerBottom.Vanillify[];
};
idleSecs: INT;
enabled: BOOL ← TRUE;
BackHack:
PROC = {
DO
now: BasicTime.Unpacked ← BasicTime.Unpack[BasicTime.Now[]];
IF now.month # April OR now.day # 1 THEN EXIT;
idleSecs ← Random.Choose[idleMin, idleMax];
Process.Pause[Process.SecondsToTicks[idleSecs]];
IF NOT enabled THEN EXIT;
Hack[];
ENDLOOP;
};
prefix:
ROPE ← Rope.Cat[
DefaultRemoteNames.Get[].systemHost,
"<PostCedar5.2>MazeWar>Eyeball"];
postfix: ROPE ← ".AIS";
EnsureLoaded:
PROC = {
Load:
PROC [index: ImageIndex, side:
ROPE, yFudge:
INTEGER] = {
images[index] ← [
ir: GraphicsOps.NewAisImage[prefix.Cat[side, postfix]],
yFudge: yFudge];
};
IF loaded THEN RETURN;
Load[0, "Front", 0];
Load[1, "Left", 0];
Load[2, "Right", -1];
Load[3, "Back", 0];
loaded ← TRUE;
};
Forkit: PROC = TRUSTED {Process.Detach[FORK BackHack[]]};
Forkit[];
}.