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