-- 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... ~~~~~~~~~~