#INCLUDE "lectprot.inc" #INCLUDE "streamio.inc" PROC display.as.requested(CHAN OF DISP.REQ req.in, CHAN OF SS screen) VAL num.boxes IS 10: -- arbitrary limit [num.boxes]BOX boxpos: -- box corners [num.boxes]XY cursor: -- local cursor position --{{{ box level screen handling PROCs --{{{ goto.in.box PROC goto.in.box(VAL INT box, VAL XY xy) SEQ --{{{ VAL absx IS boxpos[box][x1] + (xy[x]+1): VAL absy IS boxpos[box][y1] + (xy[y]+1): screen ! st.goto; INT32 absx; INT32 absy --}}} cursor[box] := xy : --}}} --{{{ clear.box PROC clear.box(VAL INT box) VAL blanks IS " * * ": XY oldcursor: SEQ oldcursor := cursor[box] --{{{ VAL x1 IS boxpos[box][x1]: VAL x2 IS boxpos[box][x2]: VAL y1 IS boxpos[box][y1]: VAL y2 IS boxpos[box][y2]: IF (y2 > y1) AND (x2 > x1) SEQ y = y1+1 FOR (y2 - y1) -1 SEQ screen ! st.goto; INT32(x1+1); INT32 y screen ! st.out.string; INT32((x2-x1) - 1) :: blanks TRUE SKIP --}}} goto.in.box(box, oldcursor) : --}}} --{{{ draw.box PROC draw.box(VAL INT num, x1, x2, y1, y2, VAL []BYTE boxname) BYTE corner: SEQ --{{{ remember position boxpos[num] := [x1, x2, y1, y2] --}}} corner := '0' + (BYTE num) --{{{ top edge screen ! st.goto; INT32 x1; INT32 y1 screen ! st.out.byte; corner IF x2 > x1 --{{{ print name in middle of line of dashes VAL max.dashes IS (x2-x1) - 1: INT name.len, name.start: INT remaining.dashes: SEQ --{{{ compute name.start name.len := SIZE boxname remaining.dashes := max.dashes - name.len IF remaining.dashes < 0 SEQ name.len := max.dashes name.start := 0 TRUE name.start := remaining.dashes / 2 --}}} SEQ x = 0 FOR name.start screen ! st.out.byte; '-' screen ! st.out.string; INT32 name.len :: boxname SEQ x = 0 FOR (max.dashes - (name.start + name.len)) screen ! st.out.byte; '-' --}}} --{{{ otherwise do nothing TRUE SKIP --}}} screen ! st.out.byte; corner --}}} --{{{ sides IF y2 > y1 SEQ y = y1+1 FOR (y2 - y1) - 1 SEQ screen ! st.goto; INT32 x1; INT32 y screen ! st.out.byte; '|' screen ! st.goto; INT32 x2; INT32 y screen ! st.out.byte; '|' TRUE SKIP --}}} --{{{ bottom edge screen ! st.goto; INT32 x1; INT32 y2 screen ! st.out.byte; corner IF x2 > x1 SEQ x = x1+1 FOR (x2-x1) - 1 screen ! st.out.byte; '-' TRUE SKIP screen ! st.out.byte; corner --}}} cursor[num] := [0,0] clear.box(num) : --}}} --}}} --{{{ more variables BOOL going: -- continuation flag INT current.box: -- identity of box most recently used VAL max.text IS 256: -- string buffer size --}}} SEQ --{{{ receive commands and act on them current.box := -1 going := TRUE WHILE going BYTE box: -- identity of box to be used SEQ req.in ? CASE --{{{ select a variant finish going := FALSE BYTE x1, x2, y1, y2: -- corner co-ordinates BYTE len: -- string length [max.text]BYTE text: -- string buffer define.box; box; x1; x2; y1; y2; len::text draw.box (INT box, INT x1, INT x2, INT y1, INT y2, [text FOR INT len]) BYTE x,y: go.inside.box; box; x; y goto.in.box (INT box, [INT x, INT y]) BYTE len: -- string length [max.text]BYTE text: -- string buffer text.in.box; box; len::text --{{{ INT j: VAL INT box IS INT box: VAL BOX thisbox IS boxpos[box]: VAL INT len IS INT len: SEQ --{{{ check cursor position IF (INT box) = current.box SKIP TRUE --{{{ move real cursor SEQ VAL absx IS thisbox[x1] + (cursor[box][x]+1): VAL absy IS thisbox[y1] + (cursor[box][y]+1): screen ! st.goto; INT32 absx; INT32 absy --}}} --}}} j := 0 WHILE j < len SEQ IF (cursor[box][x] = (thisbox[x2] - (thisbox[x1] + 1))) OR (text[j] = '*c') --{{{ end of line INT new.y: SEQ new.y := cursor[box][y] + 1 IF new.y = (thisbox[y2] - (thisbox[y1] + 1)) --{{{ bottom of box SEQ clear.box(box) new.y := 0 --}}} TRUE SKIP goto.in.box(box, [0, new.y]) --}}} TRUE SKIP IF text[j] = (BYTE 7) screen ! st.beep text[j] < ' ' SKIP TRUE SEQ cursor[box][x] := cursor[box][x] + 1 screen ! st.out.byte; text[j] j := j + 1 --}}} --}}} current.box := INT box --}}} screen ! st.goto; 0; 22 VAL str IS "End of simulation": screen ! st.out.string; INT32 (SIZE str)::str screen ! st.endstream :