<> <> <> DIRECTORY HourGlass, Interminal USING [SetCursorPattern]; HourGlassImpl: CEDAR PROGRAM IMPORTS Interminal EXPORTS HourGlass = TRUSTED BEGIN <> <> <> <> <> <> <> <> <> <<(slope) the sand piles up in the bottom, or drains from the top. Happy hacking, /Scott.>> X: BOOL = TRUE; O: BOOL = FALSE; theHGBits: PACKED ARRAY [0..16*16) OF BOOL; theHG: POINTER TO PACKED ARRAY [0..16*16) OF BOOL _ @theHGBits; initialHourglass: PACKED ARRAY [0..16*16) OF BOOL = [ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, O, X, X, X, X, X, X, X, X, X, X, X, X, X, X, O, O, O, X, X, X, X, X, X, X, X, X, X, X, X, O, O, O, O, O, X, X, X, X, X, X, X, X, X, X, O, O, O, O, O, O, O, X, X, X, X, X, X, X, X, O, O, O, O, O, O, O, O, O, X, X, X, X, X, X, O, O, O, O, O, O, O, O, O, O, O, X, X, X, X, O, O, O, O, O, O, O, O, O, O, O, O, X, O, O, X, O, O, O, O, O, O, O, O, O, O, O, X, O, O, O, O, X, O, O, O, O, O, O, O, O, O, X, O, O, O, O, O, O, X, O, O, O, O, O, O, O, X, O, O, O, O, O, O, O, O, X, O, O, O, O, O, X, O, O, O, O, O, O, O, O, O, O, X, O, O, O, X, O, O, O, O, O, O, O, O, O, O, O, O, X, O, X, O, O, O, O, O, O, O, O, O, O, O, O, O, O, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X ]; grains: CARDINAL = 56; initGrains: CARDINAL = 3; invertSand: BOOL _ TRUE; sand: BOOL _ TRUE; sandArray: ARRAY [1..15) OF CARDINAL; sandUsed, tick, totalTicks, savedTicks: CARDINAL; InitializeHourglass: PUBLIC PROCEDURE [ticks: CARDINAL] = TRUSTED BEGIN savedTicks _ ticks; sandUsed _ tick _ 0; totalTicks _ ticks; theHG^ _ initialHourglass; sandArray _ [14, 12, 10, 8, 6, 4, 2, 2, 3, 6, 7, 10, 11, 14]; sand _ TRUE; END; TickHourglass: PUBLIC PROCEDURE = TRUSTED BEGIN incr: INTEGER; n, m: CARDINAL; topSlope: CARDINAL = 3; bottomSlope: CARDINAL = 2; IF (tick_tick+1) > totalTicks THEN BEGIN -- wrap around IF invertSand THEN sand _ ~sand ELSE theHG^ _ initialHourglass; sandUsed _ tick _ 0; totalTicks _ savedTicks; sandArray _ [14, 12, 10, 8, 6, 4, 2, 2, 3, 6, 7, 10, 11, 14]; RETURN; END ELSE THROUGH [sandUsed..MIN[tick*grains/totalTicks, grains]) DO <> FOR n DECREASING IN [2..8) DO IF sandArray[n] >= sandArray[n-1]+topSlope THEN EXIT; REPEAT FINISHED => FOR n IN [1..8) DO IF sandArray[n]#0 THEN EXIT; ENDLOOP; ENDLOOP; sandArray[n] _ sandArray[n]-1; m _ (n*16)+7; incr _ 1; UNTIL theHG[m]=sand DO m _ m+incr; incr _ -incr + (IF incr<0 THEN 1 ELSE -1); ENDLOOP; theHG[m] _ ~sand; <> <> IF sandUsed < initGrains THEN theHG[SELECT sandUsed FROM 0 => (9*16)+7, 1 => (11*16)+7, ENDCASE => (13*16)+7] _ sand ELSE BEGIN FOR n IN [8..14) DO IF sandArray[n] >= sandArray[n+1]+bottomSlope THEN EXIT; REPEAT FINISHED => FOR n DECREASING IN [8..15) DO IF sandArray[n]#0 THEN EXIT; ENDLOOP; ENDLOOP; sandArray[n] _ sandArray[n]-1; m _ (n*16)+7; incr _ 1; WHILE theHG[m]=sand DO m _ m+incr; incr _ -incr + (IF incr<0 THEN 1 ELSE -1); ENDLOOP; theHG[m] _ sand; END; sandUsed _ sandUsed+1; ENDLOOP; Interminal.SetCursorPattern[LOOPHOLE[theHGBits]]; -- update displayed cursor END; END.