-- AltoPoly.mesa
-- Last Edited by Sandman on 23-Apr-82 14:28:08
-- Last Edited by Daniels on 11-May-82 17:22:47
-- Last Edited by Sweet on 14-May-82 14:56:11
DIRECTORY
AltoDisplay,
DisplayDefs,
Inline USING [BITXOR, LongDiv, LongMult],
MiscDefs,
Process,
SystemDefs,
Window;
AltoPoly: MONITOR
IMPORTS
DisplayDefs,Inline, MiscDefs, Process, SystemDefs =
BEGIN OPEN Inline;
DisplayWidth: CARDINAL = 38;
DisplayHeight: CARDINAL = 808;
DCBchainHead: POINTER TO DCBptr = LOOPHOLE[420B];
DCBptr: TYPE = POINTER TO DCB;
DCB: TYPE = AltoDisplay.DCB;
bitmap: POINTER;
dcb: DCBptr;
bmWords, bmLines: CARDINAL;
CreateDisplay: PROCEDURE =
BEGIN
wordsPerLine: CARDINAL ← DisplayWidth;
bmLines ← DisplayHeight;
bmWords ← wordsPerLine * bmLines;
dcb ← SystemDefs.AllocateResidentSegment[bmWords+SIZE[DCB]];
bitmap ← dcb+SIZE[DCB];
MiscDefs.Zero[bitmap, bmWords];
dcb↑ ← [NIL, high, black, 0, wordsPerLine, bitmap, bmLines/2];
DCBchainHead↑ ← dcb;
END;
VectorSize: CARDINAL = 55;
i1: CARDINAL ← 0;
i2: CARDINAL ← VectorSize/2;
vector: ARRAY [0..VectorSize) OF WORD ← [
031575B, 055455B, 147160B, 176745B, 173126B,
117426B, 033612B, 130620B, 054013B, 167672B,
070252B, 033100B, 015700B, 113523B, 170465B,
024344B, 175535B, 137325B, 126211B, 010207B,
173547B, 016071B, 056622B, 014433B, 113225B,
047553B, 103025B, 110174B, 000125B, 173304B,
076700B, 104042B, 135030B, 126234B, 175154B,
140123B, 167542B, 000405B, 035464B, 166537B,
050260B, 167655B, 123615B, 175164B, 172206B,
140365B, 074606B, 075656B, 176163B, 030027B,
022102B, 040051B, 154630B, 017144B, 073372B];
Word: PUBLIC PROCEDURE RETURNS [ret: WORD] =
BEGIN
ret ← vector[i1] ← vector[i1] + vector[i2];
IF (i1 ← i1+1) >= VectorSize THEN i1 ← 0;
IF (i2 ← i2+1) >= VectorSize THEN i2 ← 0;
RETURN
END;
seed: CARDINAL;
Random: PROCEDURE [low, high: CARDINAL ← 0] RETURNS [CARDINAL] =
BEGIN
seed ← Word[];
RETURN[IF high = 0 THEN seed ELSE ((seed MOD (high-low+1)) + low)];
END;
movie: BOOLEAN ← FALSE;
moviePause: CARDINAL ← 100;
DoIt: PROCEDURE = {
nPoints: [3..6] = Random[high: 6, low: 3];
start, stop, middle, oldMiddle: ARRAY [0..6) OF Window.Place;
dims: Window.Dims = [w: 608, h: 808];
first: BOOLEAN ← TRUE;
DrawPolygon: PROC [
points: POINTER TO ARRAY [0..6) OF Window.Place, op: DisplayOp ← set] = {
FOR i: CARDINAL IN [0..nPoints) DO
DisplaySolidLine[start: points[i], stop: points[(i+1) MOD nPoints],
op: op];
ENDLOOP};
DrawDashed: PROC = {
FOR i: CARDINAL IN [0..nPoints) DO
DisplayDashedLine[start: start[i], stop: stop[i]];
ENDLOOP};
EraseOldMiddle: PROC = {
DrawPolygon[@oldMiddle, xor]};
-- DrawPolygon[@start]; DrawPolygon[@stop]; DrawDashed[]};
FOR i: CARDINAL IN [0..nPoints) DO
start[i] ← [x: Random[high: dims.w-1], y: Random[high: dims.h-1]];
stop[i] ← [x: Random[high: dims.w-1], y: Random[high: dims.h-1]];
ENDLOOP;
MiscDefs.Zero[bitmap, bmWords];
DrawPolygon[@start];
Pause[750];
DrawPolygon[@stop];
Pause[750];
DrawDashed[];
Pause[1500];
IF ~movie THEN MiscDefs.Zero[bitmap, bmWords];
oldMiddle ← start;
FOR i: CARDINAL IN [0..interval] DO
FOR j: CARDINAL IN [0..nPoints) DO
middle[j] ← PointOnLine[
start: start[j], stop: stop[j], i: i, n: interval];
ENDLOOP;
DrawPolygon[@middle, IF movie THEN xor ELSE set];
IF first THEN first ← FALSE
ELSE IF movie THEN {EraseOldMiddle[]; Pause[moviePause]};
oldMiddle ← middle;
ENDLOOP;
IF movie THEN EraseOldMiddle[];
Pause[2500]};
Pause: ENTRY PROCEDURE [msec: CARDINAL] = {
cond: CONDITION ← [timeout: Process.MsecToTicks[msec]];
WAIT cond};
interval: CARDINAL ← 40;
running, deactivating: BOOLEAN ← FALSE;
wait: CONDITION ← [timeout: Process.SecondsToTicks[1]];
Line: TYPE = POINTER TO PACKED ARRAY [0..608] OF [0..1];
LineArray: TYPE = ARRAY [0..808) OF Line;
lines: POINTER TO ARRAY [0..808) OF Line;
InitLineArray: PROC = {
wordsPerScanLine: CARDINAL = 38;
lp: POINTER ← bitmap;
lines ← SystemDefs.AllocateResidentSegment[SIZE[LineArray]];
FOR i: CARDINAL IN [0..808) DO lines[i] ← lp + i*wordsPerScanLine; ENDLOOP};
Vector: TYPE = RECORD [value: CARDINAL, neg: BOOLEAN];
Vectorfy: PROC [start, stop: INTEGER] RETURNS [Vector] = INLINE {
IF start < stop THEN RETURN[[value: stop - start, neg: FALSE]]
ELSE RETURN[[value: start - stop, neg: TRUE]]};
DisplayOp: TYPE = {set, xor};
DisplaySolidLine: PROC [start, stop: Window.Place, op: DisplayOp] =
BEGIN
twodMajor, twodMajorminus2dMinor, xDir, yDir, e: INTEGER;
deltaY, deltaX: Vector;
deltaX ← Vectorfy[start: start.x, stop: stop.x];
deltaY ← Vectorfy[start: start.y, stop: stop.y];
IF deltaY.neg THEN yDir ← -1 ELSE yDir ← 1;
IF deltaX.neg THEN xDir ← -1 ELSE xDir ← 1;
IF deltaY.value > deltaX.value THEN
BEGIN
twodMajor ← 2*deltaX.value;
twodMajorminus2dMinor ← twodMajor - 2*deltaY.value;
e ← 2*deltaX.value - deltaY.value;
UNTIL start.y = stop.y DO
IF op = set THEN lines[start.y][start.x] ← 1
ELSE lines[start.y][start.x] ←
Inline.BITXOR[lines[start.y][start.x], 1];
IF e > 0 THEN {
start.x ← start.x + xDir; e ← e + twodMajorminus2dMinor}
ELSE e ← e + twodMajor;
start.y ← start.y + yDir;
ENDLOOP;
END
ELSE -- shallow
BEGIN
twodMajor ← 2*deltaY.value;
twodMajorminus2dMinor ← twodMajor - 2*deltaX.value;
e ← 2*deltaY.value - deltaX.value;
UNTIL start.x = stop.x DO
IF op = set THEN lines[start.y][start.x] ← 1
ELSE lines[start.y][start.x] ←
Inline.BITXOR[lines[start.y][start.x], 1];
IF e > 0 THEN {
start.y ← start.y + yDir; e ← e + twodMajorminus2dMinor}
ELSE e ← e + twodMajor;
start.x ← start.x + xDir;
ENDLOOP;
END
END;
DisplayDashedLine: PROC [start, stop: Window.Place] =
BEGIN
twodMajor, twodMajorminus2dMinor, xDir, yDir, e: INTEGER;
deltaY, deltaX: Vector;
count: CARDINAL ← 0;
value: [0..1] ← 1;
deltaX ← Vectorfy[start: start.x, stop: stop.x];
deltaY ← Vectorfy[start: start.y, stop: stop.y];
IF deltaY.neg THEN yDir ← -1 ELSE yDir ← 1;
IF deltaX.neg THEN xDir ← -1 ELSE xDir ← 1;
IF deltaY.value > deltaX.value THEN
BEGIN
twodMajor ← 2*deltaX.value;
twodMajorminus2dMinor ← twodMajor - 2*deltaY.value;
e ← 2*deltaX.value - deltaY.value;
UNTIL start.y = stop.y DO
lines[start.y][start.x] ← value;
IF e > 0 THEN {
start.x ← start.x + xDir; e ← e + twodMajorminus2dMinor}
ELSE e ← e + twodMajor;
start.y ← start.y + yDir;
IF count = 5 THEN {
value ← Inline.BITXOR[value, 1]; count ← 0}
ELSE count ← count + 1;
ENDLOOP;
END
ELSE -- shallow
BEGIN
twodMajor ← 2*deltaY.value;
twodMajorminus2dMinor ← twodMajor - 2*deltaX.value;
e ← 2*deltaY.value - deltaX.value;
UNTIL start.x = stop.x DO
lines[start.y][start.x] ← value;
IF e > 0 THEN {
start.y ← start.y + yDir; e ← e + twodMajorminus2dMinor}
ELSE e ← e + twodMajor;
start.x ← start.x + xDir;
IF count = 5 THEN {
value ← Inline.BITXOR[value, 1]; count ← 0}
ELSE count ← count + 1;
ENDLOOP;
END
END;
PointOnLine: PROC [
start, stop: Window.Place, i, n: INTEGER] RETURNS [place: Window.Place] =
BEGIN
vec: Vector ← Vectorfy[start: start.x, stop: stop.x];
delta: CARDINAL ← LongDiv[LongMult[vec.value, i], n];
place.x ← IF vec.neg THEN start.x - delta ELSE start.x + delta;
vec ← Vectorfy[start: start.y, stop: stop.y];
delta ← LongDiv[LongMult[vec.value, i], n];
place.y ← IF vec.neg THEN start.y - delta ELSE start.y + delta;
END;
DisplayDefs.DestroyDisplay[];
CreateDisplay[];
InitLineArray[];
AltoDisplay.Cursor↑ ← ALL[0];
DO
DoIt[];
ENDLOOP;
END...
~~~~~~~~~~