DIRECTORY ViewerPrivate USING [], Interminal USING [SetCursorPattern]; HourGlassImpl: CEDAR PROGRAM IMPORTS Interminal EXPORTS ViewerPrivate = TRUSTED BEGIN 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 PROC [ticks: CARDINAL] = TRUSTED { 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; }; TickHourglass: PUBLIC PROC = TRUSTED { incr: INTEGER; n, m: CARDINAL; topSlope: CARDINAL = 3; bottomSlope: CARDINAL = 2; IF (tick_tick+1) > totalTicks THEN { -- 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; } 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 { 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; }; sandUsed _ sandUsed+1; ENDLOOP; Interminal.SetCursorPattern[LOOPHOLE[theHGBits]]; -- update displayed cursor }; END. HourGlassImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. edited by McGregor, October 25, 1982 10:17 am Last Edited by: Maxwell, January 3, 1983 12:51 pm Doug Wyatt, April 14, 1985 11:47:58 pm PST See HourGlass.mesa for instructions on how to use these procedures. Here's how to modify the cursor: change the initialHourglass array below to anything you like for an initial cursor. Count the number of bits (of sand) contained in the top and change the constant grains to this number. sandArray will also need to be changed in InitializeHourglass. The first seven numbers tell how many grains there are to start in the top rows of the hourglass (not counting the sides). The last seven numbers tell how many empty places (slots for sand grains) there are in the bottom rows of the hourglass. The algorithm that moves the grains will carefully skip over any grains you initially put in the bottom. Other fun things to play with are the constants that control how steep (slope) the sand piles up in the bottom, or drains from the top. Happy hacking, /Scott. take a grain out of the top non-empty row of sand, favoring the middle. put a grain in one of the top non-empty rows of sand, favoring the middle, and using the slope as a determinant of the sand stacking angle. Ê¥– "Mesa" style˜codešœ™Kšœ Ïmœ1™K˜K˜K˜K˜K˜=Kšœžœ˜ Kšœ˜K˜—š  œžœžœžœ˜&Kšœžœ˜Kšœžœ˜Kšœ žœ˜Kšœ žœ˜K˜šžœžœÏc˜3Kšžœ žœžœ˜?K˜K˜K˜=Kšžœ˜Kšœ˜K˜—Kšžœžœ žœ"ž˜?˜KšœG™Gšžœž œžœž˜Kšžœ)žœžœ˜5š žœžœžœžœž˜%Kšžœžœžœ˜Kšžœ˜—Kšžœ˜—K˜K˜ K˜ šžœž˜K˜ Kšœžœžœžœ˜*Kšžœ˜—K˜K˜KšœJ™JKšœ@™@šžœžœžœ ž˜8K˜K˜Kšžœ˜—šžœ˜šžœžœ ž˜Kšžœ,žœžœ˜8š žœžœžœž œžœ ž˜1Kšžœžœžœ˜Kšžœ˜—Kšžœ˜—K˜K˜ K˜ šžœž˜K˜ Kšœžœžœžœ˜*Kšžœ˜—K˜Kšœ˜K˜—K˜K˜Kšžœ˜K˜—Kšœžœ¡˜LK˜Kšœ˜K˜—K˜Kšžœ˜—…— @ÿ