home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1990-11-23 | 4.5 KB | 172 lines |
- (* ------------------------------------------------------ *)
- (* BOX.MOD *)
- (* Message und Antwort-Boxen *)
- (* Ausgaberoutinen schreiben direkt auf den Bildschirm *)
- (* *)
- (* (c) 1991 Wolfhard Rinke & TOOLBOX *)
- (* ------------------------------------------------------ *)
- IMPLEMENTATION MODULE Box;
-
- FROM Strings IMPORT Length, CompareStr;
- FROM Terminal IMPORT Read;
- FROM SYSTEM IMPORT BYTE, ADDRESS, SEG, OFS;
-
- TYPE
- CrtChar = RECORD
- ch : CHAR;
- at : BYTE;
- END;
-
- CrtPage = ARRAY [1..25], [1..80] OF CrtChar;
-
- VAR
- Screen : POINTER TO CrtPage;
- (* "Standard": Screen[0B800H:0] : CrtPage; *)
- (* für monochrom : $B000:$0000 *)
-
- CrtAddr : ADDRESS;
-
- (* ------------------------------------------------------ *)
-
- PROCEDURE WriteCharXY(col, row : CARDINAL;
- ch : CHAR;
- num : CARDINAL);
- VAR
- i : CARDINAL;
- BEGIN
- FOR i := 0 TO num-1 DO
- IF (i + row) <= 80 THEN
- Screen^[row, col+i].ch := ch;
- Screen^[row, col+i].at := TextAttr;
- END;
- END;
- END WriteCharXY;
-
- (* ------------------------------------------------------ *)
-
- PROCEDURE ClrScr(x1, y1, x2, y2 : CARDINAL);
- VAR
- row : CARDINAL;
- BEGIN
- FOR row := y1 TO y2 DO
- WriteCharXY(x1, row, 40C, x2-x1);
- END;
- END ClrScr;
-
- (* ------------------------------------------------------ *)
-
- PROCEDURE WriteTextXY(col, row : CARDINAL;
- s : ARRAY OF CHAR);
- VAR
- i : CARDINAL;
- BEGIN
- FOR i := 0 TO Length(s)-1 DO
- WriteCharXY(col+i, row, s[i], 1);
- (* ^ Turbo Pascal !!! *)
- END;
- END WriteTextXY;
-
- (* ------------------------------------------------------ *)
-
- PROCEDURE Frame(x1, y1, x2, y2 : CARDINAL);
- VAR
- i : CARDINAL;
- BEGIN
- ClrScr(x1, y1, x2, y2);
- WriteCharXY(x1, y1, 311C, 1); (* oben *)
- WriteCharXY(x1+1, y1, 315C, x2-x1-2);
- WriteCharXY(x2-1, y1, 273C, 1);
-
- FOR i := y1+1 TO y2-1 DO
- WriteCharXY(x1, i, 272C, 1); (* links *)
- WriteCharXY(x2-1, i, 272C, 1); (* rechts *)
- END;
-
- WriteCharXY(x1, y2, 310C, 1); (* unten *)
- WriteCharXY(x1+1, y2, 315C, x2-x1-2);
- WriteCharXY(x2-1, y2, 274C, 1);
- END Frame;
-
- (* ------------------------------------------------------ *)
-
- PROCEDURE Shadow(x1, y1, x2, y2 : CARDINAL);
- VAR
- i : CARDINAL;
- BEGIN
- FOR i := y1+1 TO y2+1 DO
- WriteCharXY(x2, i, 261C, 1); (* '▒' *)
- END;
- WriteCharXY(x1+1, y2+1, 261C, x2-x1);
- END Shadow;
-
- (* ------------------------------------------------------ *)
-
- PROCEDURE Message(head : ARRAY OF CHAR;
- col, row : CARDINAL;
- s : ARRAY OF CHAR);
- VAR
- i : CARDINAL;
- len : CARDINAL;
- hlen : CARDINAL;
- BEGIN
- len := Length(s) + 4;
-
- (* Für den Rahmen und je ein Blank vorne und hinten *)
-
- Frame(col, row, col+len, row+2);
-
- IF CompareStr(head, '') <> 0 THEN
- (* oder: IF head[0] <> 0C THEN ... *)
-
- hlen := (len-Length(head)) DIV 2;
- WriteTextXY(col+hlen, row, head);
- END;
-
- WriteTextXY(col+2, row+1, s);
-
- (* sollte optional sein: der Schatten... *)
- Shadow(col, row, col+len, row+2);
- END Message;
-
- (* ------------------------------------------------------ *)
-
- PROCEDURE ReadKey() : CHAR;
- VAR
- ch : CHAR;
- BEGIN
- Read(ch);
- RETURN ch;
- END ReadKey;
-
- (* ------------------------------------------------------ *)
-
- PROCEDURE Answer(col, row : CARDINAL;
- s : ARRAY OF CHAR;
- corr : EntrySet;
- VAR ch : CHAR);
- BEGIN
- Message(' Answer ', col, row, s);
-
- REPEAT
- ch := CAP(ReadKey());
- IF ch IN corr THEN
- (* WriteCharXY(col+Length(s), row+1, ch, 1); *)
- ELSE
- (* optional:
- Sound(200);
- Delay(100);
- NoSound;
- *)
- END;
- UNTIL ch IN corr;
- END Answer;
-
- BEGIN
- CrtAddr.SEG := 0B800H; (* $B000 für monochrom *)
- CrtAddr.OFS := 00000H;
- Screen := CrtAddr;
- END Box.
- (* ------------------------------------------------------ *)
- (* Ende von BOX.MOD *)
-
-