home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
EFFO
/
forum8.lzh
/
PROGRAMME
/
MODULA
/
WINDOW
/
area.mod
< prev
next >
Wrap
Text File
|
1989-01-19
|
39KB
|
1,168 lines
(*
-------------------------------------------------------------------------------
@@@@@@@@@@@@@@@@@@@*) IMPLEMENTATION MODULE Area; (*@@@@@@@@@@@@@@@@@@@@@@@
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
| Kurzbeschreibung | minimales Fenstersystem fuer Textbildschirme |
| | |
---------------------+---------------------------------------------------------
| Programm - Version | 2.2 | Text - Version | V#093 |
---------------------+--------+-------------------------+----------------------
| Modulholder | WS | Urversion | WS | August 88 |
---------------------+---------------------------------------------------------
| System - Version | OS-9, Miele-Modula-2 3.5 |
---------------------+---------------------------------------------------------
| Copyright | Freigegeben fuer nichtkommerzielle Nutzung |
| | durch Teilnehmer am EFFO |
---------------------+---------------------------------------------------------
| Hardware | GEPARD 68010, 1 MByte RAM, 80Zeichen-Textkarte |
---------------------+---------------------------------------------------------
| besondere Importe | |
---------------------+---------------------------------------------------------
| Autoren | WS | Werner Stehling, Seilerwis 3, |
| | | CH-8606 Greifensee, Tel. 01/256 42 21 |
---------------------+---------------------------------------------------------
| U P D A T E S | |
---------------------- |
| Datum Version Autor Bemerkungen |
| -------- ------- ----- ----------- |
| 10. 8.88 1.1 WS dynamische Fensterverwaltung unter GDOS |
| 17. 8.88 1.1 WS Prozeduren zur Zahlenausgabe |
| 12.12.88 2.0 WS Umstellung auf OS-9 / Miele-Modula 2 |
| 15.12.88 2.0 WS Aufteilung in area und areaIO |
| 20.12.88 2.1 WS Area-Record mit dynamischer Laenge |
| 27. 1.89 2.1 WS GetAreaPar mit VAR bereich |
| 3. 2.89 2.1 WS Write (CR) geflickt |
| 7. 2.89 2.2 WS SetTemp und EndTemp neu |
| 9. 2.89 2.2 WS ResetAktiv definiert zum Beschleunigen |
| |
-------------------------------------------------------------------------------
| Modul-Beschreibung | siehe Definition Modul |
---------------------- |
-------------------------------------------------------------------------------
*)
FROM Screen IMPORT Send, Gotoxy, Controls;
FROM SYSTEM IMPORT WORD, ADDRESS, SIZE, ADR;
FROM Storage IMPORT ALLOCATE, DEALLOCATE;
FROM BasicIO IMPORT TerminalMode, SetTerminal, In;
FROM FileIO IMPORT StdIn, StdOut, FReadCh, FWriteCh;
FROM Strings IMPORT Length;
CONST kreuz = \160; (* Character zum Rahmen zeichnen *)
tlinks = \166;
eckelo = \170;
eckero = \171;
eckelu = \172;
eckeru = \173;
trecht = \175;
waagre = \184;
senkre = \185;
tunten = \186;
toben = \187;
TYPE RahmTyp = [kreuz..toben];
Dump = POINTER TO dump;
dump = RECORD
nextdump : Dump; (* verketttete Liste *)
dumplen : CARDINAL; (* Groesse von indump *)
xmin, ymin : CARDINAL; (* linke obere Ecke *)
breite, hoehe: CARDINAL;
aktiv : Area ; (* gerade aktive Area *)
indump : Screen (* Fensterinhalt *)
END;
VAR schirm : ARRAY [0..maxx],[0..maxy] OF CHAR;
fenster1, fenstere, workarea : Area;
ersatz : ARRAY RahmTyp,RahmTyp,BOOLEAN OF RahmTyp;
ax0, ay0, adx, ady, axc, ayc, fxc, fyc : CARDINAL;
firstdump : Dump;
(*--------------------------------------------------------------------------*)
PROCEDURE SaveScreen (x0, y0, dx, dy : CARDINAL);
(*--------------------------------------------------------------------------*)
(* Rettet den absoluten Bildschirm von (x0,y0) bis (x0+dx,y0+dy) auf den *)
(* Stack. *)
VAR work : Dump;
i, k, l : CARDINAL;
BEGIN
work := NIL;
l := 18 + dx * dy; (* Platzbedarf in Byte *)
ALLOCATE (work, l);
IF work <> NIL THEN
WITH work^ DO
nextdump := firstdump;
firstdump := work;
dumplen := l;
xmin := x0;
ymin := y0;
breite := dx;
hoehe := dy;
aktiv := workarea;
l := 0;
FOR k := y0 TO y0+dy-1 DO
FOR i := x0 TO x0+dx-1 DO
indump [l] := schirm[i, k];
INC (l)
END
END
END
END
END SaveScreen;
(*--------------------------------------------------------------------------*)
PROCEDURE SetTemp (bereich : Area);
(*--------------------------------------------------------------------------*)
(* Rettet den absoluten Bildschirmbereich auf den Stack, bevor der neue *)
(* Bereich angezeigt wird. Restaurieren durch EndTemp. *)
BEGIN
IF bereich = NIL THEN
SaveScreen (0, 0, maxx, maxy)
ELSE
WITH bereich^ DO
SaveScreen (xmin-1, ymin-1, breite+2, hoehe+2)
END
END;
SetAktiv (bereich)
END SetTemp;
(*--------------------------------------------------------------------------*)
PROCEDURE EndTemp;
(*--------------------------------------------------------------------------*)
(* Holt den zuletzt geretteten Bildschirm vom Stack *)
VAR work : Dump;
i, k, l : CARDINAL;
BEGIN
IF workarea <> NIL THEN
WITH workarea^ DO (* save cursor *)
xcurs := axc;
ycurs := ayc
END
ELSE
fxc := axc;
fyc := ayc
END;
IF firstdump <> NIL THEN
work := firstdump;
WITH work^ DO
l := 0;
FOR k := ymin TO ymin+hoehe-1 DO
Gotoxy (xmin, k);
FOR i := xmin TO xmin+breite-1 DO
FWriteCh (StdOut, indump [l]);
schirm[i, k] := indump[l];
INC (l)
END
END;
workarea := aktiv
END;
IF workarea <> NIL THEN
WITH workarea^ DO
ax0 := xmin;
ay0 := ymin;
adx := breite;
ady := hoehe;
GotoXY (xcurs, ycurs)
END
ELSE
ax0 := 0;
ay0 := 0;
adx := maxx+1;
ady := maxy+1;
GotoXY (fxc, fyc)
END;
firstdump := work^.nextdump;
DEALLOCATE (work, work^.dumplen)
END
END EndTemp;
(*--------------------------------------------------------------------------*)
PROCEDURE FindArea (bereich : Area) : BOOLEAN;
(*--------------------------------------------------------------------------*)
(* Return TRUE, wenn bereich definiert ist *)
VAR work : Area;
BEGIN
IF bereich <> NIL THEN
work := fenster1;
WHILE (work <> NIL) AND (work <> bereich) DO
work := work^.nextarea
END;
RETURN work = bereich
ELSE
RETURN FALSE
END
END FindArea;
(*--------------------------------------------------------------------------*)
PROCEDURE Adjust (bereich : Area);
(*--------------------------------------------------------------------------*)
(* Fenster immer voll auf dem Schirm *)
BEGIN
IF FindArea (bereich) THEN
WITH bereich^ DO
IF breite < 1 THEN
breite := 1
END;
IF hoehe < 1 THEN
hoehe := 1
END;
IF breite > maxx-1 THEN
breite := maxx - 1
END;
IF hoehe > maxy-1 THEN
hoehe := maxy - 1
END;
IF xmin < 1 THEN
xmin := 1
END;
IF ymin < 1 THEN
ymin := 1
END;
IF xmin+breite > maxx THEN
xmin := maxx - breite
END;
IF ymin+hoehe > maxy THEN
ymin := maxy - hoehe
END;
END
END
END Adjust;
(*--------------------------------------------------------------------------*)
PROCEDURE MakeArea (x0, y0, dx, dy : CARDINAL) : Area;
(*--------------------------------------------------------------------------*)
(* neuen Bereich auf dem Schirm einrichten *)
(* x0 und y0 sind die Position des ersten Characters oben links *)
(* dx und dy sind die wahre Breite und Hoehe; der Rahmen zaehlt zusaetzlich *)
VAR i : Area;
l : CARDINAL;
BEGIN
i := NIL;
l := 18 + dx * dy; (* Platzbedarf in Byte *)
ALLOCATE (i, l);
IF i <> NIL THEN
IF fenster1 = NIL THEN
fenster1 := i (* frische Liste *)
END;
IF fenstere <> NIL THEN
fenstere^.nextarea := i
END;
fenstere := i; (* neues Ende der Liste *)
WITH i^ DO
arealen := l;
xmin := x0;
ymin := y0;
breite := dx;
hoehe := dy;
xcurs := 0;
ycurs := 0;
nextarea := NIL;
FOR l := 0 TO dx*dy-1 DO
inarea [l] := ' '
END;
END;
Adjust (i);
END;
RETURN i
END MakeArea;
(*--------------------------------------------------------------------------*)
PROCEDURE GetAreaPar (bereich : Area; VAR x0, y0, dx, dy : CARDINAL);
(*--------------------------------------------------------------------------*)
BEGIN
IF bereich = NIL THEN
x0 := ax0;
y0 := ay0;
dx := adx;
dy := ady
ELSE
WITH bereich^ DO
x0 := xmin;
y0 := ymin;
dx := breite;
dy := hoehe
END
END
END GetAreaPar;
(*--------------------------------------------------------------------------*)
PROCEDURE PositArea (VAR bereich : Area; x0, y0 : CARDINAL);
(*--------------------------------------------------------------------------*)
(* Fenster nach x0, y0 verschieben *)
BEGIN
IF FindArea (bereich) THEN
WITH bereich^ DO
xmin := x0;
ymin := y0
END;
Adjust (bereich);
IF bereich = workarea THEN
SetAktiv (bereich) (* neu zeichnen *)
END;
END;
END PositArea;
(*--------------------------------------------------------------------------*)
PROCEDURE DimArea (VAR bereich : Area; dx, dy : CARDINAL);
(*--------------------------------------------------------------------------*)
(* Fenstergroesse neu festlegen *)
VAR i, k, l : CARDINAL;
neu : Area;
BEGIN
IF FindArea (bereich) THEN
neu := MakeArea (bereich^.xmin, bereich^.ymin, dx, dy);
IF neu <> NIL THEN
WITH bereich^ DO
k := breite * hoehe;
l := xcurs + ycurs * breite
END;
WITH neu^ DO
xcurs := l MOD breite;
ycurs := l DIV breite;
IF ycurs > hoehe THEN
xcurs := breite;
ycurs := hoehe
END;
i := breite * hoehe;
IF i < k THEN k := i END;
FOR l := 0 TO k - 1 DO
inarea[l] := bereich^.inarea[l]
END;
IF bereich = workarea THEN
axc := xcurs;
ayc := ycurs;
SetAktiv (neu) (* neu zeichnen *)
END;
END;
ReturnArea (bereich); (* alte area loeschen *)
bereich := neu; (* neuer pointer *)
END;
END;
END DimArea;
(*--------------------------------------------------------------------------*)
PROCEDURE ReturnArea (bereich : Area);
(*--------------------------------------------------------------------------*)
(* Area zurueckgeben *)
VAR hilf, vorher : Area;
BEGIN
hilf := fenster1;
vorher := NIL;
WHILE (hilf <> NIL) AND (hilf <> bereich) DO
vorher := hilf;
hilf := hilf^.nextarea
END;
IF hilf = bereich THEN
IF hilf = fenster1 THEN
fenster1 := hilf^.nextarea (* neues erstes Fenster *)
END;
IF vorher <> NIL THEN
vorher^.nextarea := hilf^.nextarea (* raus aus der Liste *)
END;
IF hilf = fenstere THEN
fenstere := vorher (* neues letztes Fenster *)
END;
IF hilf = workarea THEN
workarea := NIL (* kein Fenster mehr offen *)
END;
DEALLOCATE (bereich, bereich^.arealen)
END;
END ReturnArea;
(*--------------------------------------------------------------------------*)
PROCEDURE ReturnAll;
(*--------------------------------------------------------------------------*)
(* Alle Areas zurueckgeben *)
BEGIN
WHILE fenster1 <> NIL DO
ReturnArea (fenster1)
END
END ReturnAll;
(*----------------------------------------------------------------------------*)
PROCEDURE InitModule;
(*----------------------------------------------------------------------------*)
VAR i, k : CARDINAL;
BEGIN
(* Wenn dieses ARRAY auch grausam aussieht: im Betrieb ist diese Methode ein
ganzes Stueck schneller, als eine Serie IF- oder CASE-Anweisungen. Der
erste Parameter ist der neu zu schreibende Character, der Zweite ist der
bereits an dieser Stelle stehende Rahmen-Character und der BOOLEAN-
Parameter gibt an, ob es sich um eine linke oder obere (FALSE) oder eine
rechte oder untere (TRUE) Rahmenseite handelt.
*)
ersatz[kreuz ,kreuz ,FALSE]:=kreuz ; ersatz[kreuz ,tlinks,FALSE]:=kreuz ;
ersatz[kreuz ,eckelo,FALSE]:=kreuz ; ersatz[kreuz ,eckero,FALSE]:=kreuz ;
ersatz[kreuz ,eckelu,FALSE]:=kreuz ; ersatz[kreuz ,eckeru,FALSE]:=kreuz ;
ersatz[kreuz ,trecht,FALSE]:=kreuz ; ersatz[kreuz ,waagre,FALSE]:=kreuz ;
ersatz[kreuz ,senkre,FALSE]:=kreuz ; ersatz[kreuz ,tunten,FALSE]:=kreuz ;
ersatz[kreuz ,toben ,FALSE]:=kreuz ;
ersatz[kreuz ,kreuz , TRUE]:=kreuz ; ersatz[kreuz ,tlinks, TRUE]:=kreuz ;
ersatz[kreuz ,eckelo, TRUE]:=kreuz ; ersatz[kreuz ,eckero, TRUE]:=kreuz ;
ersatz[kreuz ,eckelu, TRUE]:=kreuz ; ersatz[kreuz ,eckeru, TRUE]:=kreuz ;
ersatz[kreuz ,trecht, TRUE]:=kreuz ; ersatz[kreuz ,waagre, TRUE]:=kreuz ;
ersatz[kreuz ,senkre, TRUE]:=kreuz ; ersatz[kreuz ,tunten, TRUE]:=kreuz ;
ersatz[kreuz ,toben , TRUE]:=kreuz ;
ersatz[tlinks,kreuz ,FALSE]:=tlinks ; ersatz[tlinks,tlinks,FALSE]:=tlinks ;
ersatz[tlinks,eckelo,FALSE]:=tlinks ; ersatz[tlinks,eckero,FALSE]:=tlinks ;
ersatz[tlinks,eckelu,FALSE]:=tlinks ; ersatz[tlinks,eckeru,FALSE]:=tlinks ;
ersatz[tlinks,trecht,FALSE]:=tlinks ; ersatz[tlinks,waagre,FALSE]:=tlinks ;
ersatz[tlinks,senkre,FALSE]:=tlinks ; ersatz[tlinks,tunten,FALSE]:=tlinks ;
ersatz[tlinks,toben ,FALSE]:=tlinks ;
ersatz[tlinks,kreuz , TRUE]:=kreuz ; ersatz[tlinks,tlinks, TRUE]:=tlinks ;
ersatz[tlinks,eckelo, TRUE]:=kreuz ; ersatz[tlinks,eckero, TRUE]:=tlinks ;
ersatz[tlinks,eckelu, TRUE]:=kreuz ; ersatz[tlinks,eckeru, TRUE]:=tlinks ;
ersatz[tlinks,trecht, TRUE]:=kreuz ; ersatz[tlinks,waagre, TRUE]:=kreuz ;
ersatz[tlinks,senkre, TRUE]:=tlinks ; ersatz[tlinks,tunten, TRUE]:=kreuz ;
ersatz[tlinks,toben , TRUE]:=kreuz ;
ersatz[eckelo,kreuz ,FALSE]:=kreuz ; ersatz[eckelo,tlinks,FALSE]:=kreuz ;
ersatz[eckelo,eckelo,FALSE]:=eckelo ; ersatz[eckelo,eckero,FALSE]:=tunten ;
ersatz[eckelo,eckelu,FALSE]:=trecht ; ersatz[eckelo,eckeru,FALSE]:=kreuz ;
ersatz[eckelo,trecht,FALSE]:=trecht ; ersatz[eckelo,waagre,FALSE]:=tunten ;
ersatz[eckelo,senkre,FALSE]:=trecht ; ersatz[eckelo,tunten,FALSE]:=tunten ;
ersatz[eckelo,toben ,FALSE]:=kreuz ;
ersatz[eckelo,kreuz , TRUE]:=kreuz ; ersatz[eckelo,tlinks, TRUE]:=kreuz ;
ersatz[eckelo,eckelo, TRUE]:=eckelo ; ersatz[eckelo,eckero, TRUE]:=tunten ;
ersatz[eckelo,eckelu, TRUE]:=trecht ; ersatz[eckelo,eckeru, TRUE]:=kreuz ;
ersatz[eckelo,trecht, TRUE]:=trecht ; ersatz[eckelo,waagre, TRUE]:=tunten ;
ersatz[eckelo,senkre, TRUE]:=trecht ; ersatz[eckelo,tunten, TRUE]:=tunten ;
ersatz[eckelo,toben , TRUE]:=kreuz ;
ersatz[eckero,kreuz ,FALSE]:=kreuz ; ersatz[eckero,tlinks,FALSE]:=tlinks ;
ersatz[eckero,eckelo,FALSE]:=tunten ; ersatz[eckero,eckero,FALSE]:=eckero ;
ersatz[eckero,eckelu,FALSE]:=kreuz ; ersatz[eckero,eckeru,FALSE]:=tlinks ;
ersatz[eckero,trecht,FALSE]:=kreuz ; ersatz[eckero,waagre,FALSE]:=tunten ;
ersatz[eckero,senkre,FALSE]:=tlinks ; ersatz[eckero,tunten,FALSE]:=tunten ;
ersatz[eckero,toben ,FALSE]:=kreuz ;
ersatz[eckero,kreuz , TRUE]:=kreuz ; ersatz[eckero,tlinks, TRUE]:=tlinks ;
ersatz[eckero,eckelo, TRUE]:=tunten ; ersatz[eckero,eckero, TRUE]:=eckero ;
ersatz[eckero,eckelu, TRUE]:=kreuz ; ersatz[eckero,eckeru, TRUE]:=tlinks ;
ersatz[eckero,trecht, TRUE]:=kreuz ; ersatz[eckero,waagre, TRUE]:=tunten ;
ersatz[eckero,senkre, TRUE]:=tlinks ; ersatz[eckero,tunten, TRUE]:=tunten ;
ersatz[eckero,toben , TRUE]:=kreuz ;
ersatz[eckelu,kreuz ,FALSE]:=kreuz ; ersatz[eckelu,tlinks,FALSE]:=kreuz ;
ersatz[eckelu,eckelo,FALSE]:=trecht ; ersatz[eckelu,eckero,FALSE]:=kreuz ;
ersatz[eckelu,eckelu,FALSE]:=eckelu ; ersatz[eckelu,eckeru,FALSE]:=toben ;
ersatz[eckelu,trecht,FALSE]:=trecht ; ersatz[eckelu,waagre,FALSE]:=toben ;
ersatz[eckelu,senkre,FALSE]:=trecht ; ersatz[eckelu,tunten,FALSE]:=kreuz ;
ersatz[eckelu,toben ,FALSE]:=toben ;
ersatz[eckelu,kreuz , TRUE]:=kreuz ; ersatz[eckelu,tlinks, TRUE]:=kreuz ;
ersatz[eckelu,eckelo, TRUE]:=trecht ; ersatz[eckelu,eckero, TRUE]:=kreuz ;
ersatz[eckelu,eckelu, TRUE]:=eckelu ; ersatz[eckelu,eckeru, TRUE]:=toben ;
ersatz[eckelu,trecht, TRUE]:=trecht ; ersatz[eckelu,waagre, TRUE]:=toben ;
ersatz[eckelu,senkre, TRUE]:=trecht ; ersatz[eckelu,tunten, TRUE]:=kreuz ;
ersatz[eckelu,toben , TRUE]:=toben ;
ersatz[eckeru,kreuz ,FALSE]:=kreuz ; ersatz[eckeru,tlinks,FALSE]:=tlinks ;
ersatz[eckeru,eckelo,FALSE]:=kreuz ; ersatz[eckeru,eckero,FALSE]:=tlinks ;
ersatz[eckeru,eckelu,FALSE]:=toben ; ersatz[eckeru,eckeru,FALSE]:=eckeru ;
ersatz[eckeru,trecht,FALSE]:=kreuz ; ersatz[eckeru,waagre,FALSE]:=toben ;
ersatz[eckeru,senkre,FALSE]:=tlinks ; ersatz[eckeru,tunten,FALSE]:=kreuz ;
ersatz[eckeru,toben ,FALSE]:=toben ;
ersatz[eckeru,kreuz , TRUE]:=kreuz ; ersatz[eckeru,tlinks, TRUE]:=tlinks ;
ersatz[eckeru,eckelo, TRUE]:=kreuz ; ersatz[eckeru,eckero, TRUE]:=tlinks ;
ersatz[eckeru,eckelu, TRUE]:=toben ; ersatz[eckeru,eckeru, TRUE]:=eckeru ;
ersatz[eckeru,trecht, TRUE]:=kreuz ; ersatz[eckeru,waagre, TRUE]:=toben ;
ersatz[eckeru,senkre, TRUE]:=tlinks ; ersatz[eckeru,tunten, TRUE]:=kreuz ;
ersatz[eckeru,toben , TRUE]:=toben ;
ersatz[trecht,kreuz ,FALSE]:=kreuz ; ersatz[trecht,tlinks,FALSE]:=kreuz ;
ersatz[trecht,eckelo,FALSE]:=trecht ; ersatz[trecht,eckero,FALSE]:=kreuz ;
ersatz[trecht,eckelu,FALSE]:=trecht ; ersatz[trecht,eckeru,FALSE]:=kreuz ;
ersatz[trecht,trecht,FALSE]:=trecht ; ersatz[trecht,waagre,FALSE]:=kreuz ;
ersatz[trecht,senkre,FALSE]:=trecht ; ersatz[trecht,tunten,FALSE]:=kreuz ;
ersatz[trecht,toben ,FALSE]:=kreuz ;
ersatz[trecht,kreuz , TRUE]:=trecht ; ersatz[trecht,tlinks, TRUE]:=trecht ;
ersatz[trecht,eckelo, TRUE]:=trecht ; ersatz[trecht,eckero, TRUE]:=trecht ;
ersatz[trecht,eckelu, TRUE]:=trecht ; ersatz[trecht,eckeru, TRUE]:=trecht ;
ersatz[trecht,trecht, TRUE]:=trecht ; ersatz[trecht,waagre, TRUE]:=trecht ;
ersatz[trecht,senkre, TRUE]:=trecht ; ersatz[trecht,tunten, TRUE]:=trecht ;
ersatz[trecht,toben , TRUE]:=trecht ;
ersatz[waagre,kreuz ,FALSE]:=toben ; ersatz[waagre,tlinks,FALSE]:=toben ;
ersatz[waagre,eckelo,FALSE]:=waagre ; ersatz[waagre,eckero,FALSE]:=waagre ;
ersatz[waagre,eckelu,FALSE]:=toben ; ersatz[waagre,eckeru,FALSE]:=toben ;
ersatz[waagre,trecht,FALSE]:=toben ; ersatz[waagre,waagre,FALSE]:=waagre ;
ersatz[waagre,senkre,FALSE]:=toben ; ersatz[waagre,tunten,FALSE]:=waagre ;
ersatz[waagre,toben ,FALSE]:=toben ;
ersatz[waagre,kreuz , TRUE]:=tunten ; ersatz[waagre,tlinks, TRUE]:=tunten ;
ersatz[waagre,eckelo, TRUE]:=tunten ; ersatz[waagre,eckero, TRUE]:=tunten ;
ersatz[waagre,eckelu, TRUE]:=waagre ; ersatz[waagre,eckeru, TRUE]:=waagre ;
ersatz[waagre,trecht, TRUE]:=tunten ; ersatz[waagre,waagre, TRUE]:=waagre ;
ersatz[waagre,senkre, TRUE]:=tunten ; ersatz[waagre,tunten, TRUE]:=tunten ;
ersatz[waagre,toben , TRUE]:=waagre ;
ersatz[senkre,kreuz ,FALSE]:=tlinks ; ersatz[senkre,tlinks,FALSE]:=tlinks ;
ersatz[senkre,eckelo,FALSE]:=senkre ; ersatz[senkre,eckero,FALSE]:=tlinks ;
ersatz[senkre,eckelu,FALSE]:=senkre ; ersatz[senkre,eckeru,FALSE]:=tlinks ;
ersatz[senkre,trecht,FALSE]:=senkre ; ersatz[senkre,waagre,FALSE]:=tlinks ;
ersatz[senkre,senkre,FALSE]:=senkre ; ersatz[senkre,tunten,FALSE]:=tlinks ;
ersatz[senkre,toben ,FALSE]:=tlinks ;
ersatz[senkre,kreuz , TRUE]:=trecht ; ersatz[senkre,tlinks, TRUE]:=senkre ;
ersatz[senkre,eckelo, TRUE]:=trecht ; ersatz[senkre,eckero, TRUE]:=senkre ;
ersatz[senkre,eckelu, TRUE]:=trecht ; ersatz[senkre,eckeru, TRUE]:=senkre ;
ersatz[senkre,trecht, TRUE]:=trecht ; ersatz[senkre,waagre, TRUE]:=trecht ;
ersatz[senkre,senkre, TRUE]:=senkre ; ersatz[senkre,tunten, TRUE]:=trecht ;
ersatz[senkre,toben , TRUE]:=trecht ;
ersatz[tunten,kreuz ,FALSE]:=kreuz ; ersatz[tunten,tlinks,FALSE]:=kreuz ;
ersatz[tunten,eckelo,FALSE]:=tunten ; ersatz[tunten,eckero,FALSE]:=tunten ;
ersatz[tunten,eckelu,FALSE]:=kreuz ; ersatz[tunten,eckeru,FALSE]:=kreuz ;
ersatz[tunten,trecht,FALSE]:=kreuz ; ersatz[tunten,waagre,FALSE]:=tunten ;
ersatz[tunten,senkre,FALSE]:=kreuz ; ersatz[tunten,tunten,FALSE]:=tunten ;
ersatz[tunten,toben ,FALSE]:=kreuz ;
ersatz[tunten,kreuz , TRUE]:=tunten ; ersatz[tunten,tlinks, TRUE]:=tunten ;
ersatz[tunten,eckelo, TRUE]:=tunten ; ersatz[tunten,eckero, TRUE]:=tunten ;
ersatz[tunten,eckelu, TRUE]:=tunten ; ersatz[tunten,eckeru, TRUE]:=tunten ;
ersatz[tunten,trecht, TRUE]:=tunten ; ersatz[tunten,waagre, TRUE]:=tunten ;
ersatz[tunten,senkre, TRUE]:=tunten ; ersatz[tunten,tunten, TRUE]:=tunten ;
ersatz[tunten,toben , TRUE]:=tunten ;
ersatz[toben ,kreuz ,FALSE]:=toben ; ersatz[toben ,tlinks,FALSE]:=toben ;
ersatz[toben ,eckelo,FALSE]:=toben ; ersatz[toben ,eckero,FALSE]:=toben ;
ersatz[toben ,eckelu,FALSE]:=toben ; ersatz[toben ,eckeru,FALSE]:=toben ;
ersatz[toben ,trecht,FALSE]:=toben ; ersatz[toben ,waagre,FALSE]:=toben ;
ersatz[toben ,senkre,FALSE]:=toben ; ersatz[toben ,tunten,FALSE]:=toben ;
ersatz[toben ,toben ,FALSE]:=toben ;
ersatz[toben ,kreuz , TRUE]:=kreuz ; ersatz[toben ,tlinks, TRUE]:=kreuz ;
ersatz[toben ,eckelo, TRUE]:=kreuz ; ersatz[toben ,eckero, TRUE]:=kreuz ;
ersatz[toben ,eckelu, TRUE]:=toben ; ersatz[toben ,eckeru, TRUE]:=toben ;
ersatz[toben ,trecht, TRUE]:=kreuz ; ersatz[toben ,waagre, TRUE]:=toben ;
ersatz[toben ,senkre, TRUE]:=kreuz ; ersatz[toben ,tunten, TRUE]:=kreuz ;
ersatz[toben ,toben , TRUE]:=toben ;
workarea := NIL;
fenster1 := NIL;
fenstere := NIL;
firstdump:= NIL;
FOR k := 0 TO maxy DO
FOR i := 0 TO maxx DO
schirm[i,k] := ' '
END;
END;
Send (ClrScreen);
fxc := 0; (* full screen cursor *)
fyc := 0;
ax0 := 0;
ay0 := 0;
adx := maxx+1;
ady := maxy+1;
GotoXY (fxc, fyc)
END InitModule;
(*--------------------------------------------------------------------------*)
PROCEDURE GotoXY (x0, y0 : CARDINAL);
(*--------------------------------------------------------------------------*)
BEGIN
axc := x0 MOD adx;
ayc := y0 MOD ady;
Gotoxy (ax0+axc, ay0+ayc)
END GotoXY;
(*--------------------------------------------------------------------------*)
PROCEDURE GetXY (VAR x0, y0 : CARDINAL);
(*--------------------------------------------------------------------------*)
BEGIN
x0 := axc;
y0 := ayc
END GetXY;
(*--------------------------------------------------------------------------*)
PROCEDURE Rahmen;
(*--------------------------------------------------------------------------*)
VAR ch, ck : CHAR;
i, y : CARDINAL;
m : ADDRESS;
k : BOOLEAN;
x : ARRAY [FALSE..TRUE] OF CARDINAL;
(*----------------------------------------------------------------------*)
PROCEDURE Rahmenchar (ch : CHAR) : BOOLEAN;
(*----------------------------------------------------------------------*)
(* SET funktioniert nicht *)
BEGIN
CASE ch OF
kreuz,
tlinks,
eckelo,
eckero,
eckelu,
eckeru,
trecht,
waagre,
senkre,
tunten,
toben: RETURN TRUE
ELSE
RETURN FALSE
END
END Rahmenchar;
(*----------------------------------------------------------------------*)
BEGIN
IF workarea <> NIL THEN
Gotoxy (ax0-1, ay0-1);
ck := schirm[ax0-1,ay0-1];
ch := eckelo;
IF Rahmenchar (ck) THEN (* Ecke links oben *)
ch := ersatz [ch, ck, FALSE];
END;
schirm[ax0-1,ay0-1] := ch;
FWriteCh (StdOut, ch);
y := ay0-1;
FOR i := ax0 TO ax0 + adx - 1 DO (* Oberkante *)
ck := schirm[i,y];
ch := waagre;
IF Rahmenchar (ck) THEN
ch := ersatz [ch, ck, FALSE];
END;
schirm[i,y] := ch;
FWriteCh (StdOut, ch)
END;
ck := schirm[ax0+adx,ay0-1];
ch := eckero;
IF Rahmenchar (ck) THEN (* Ecke rechts oben *)
ch := ersatz [ch, ck, TRUE];
END;
schirm[ax0+adx,ay0-1] := ch;
FWriteCh (StdOut, ch);
x[FALSE] := ax0 - 1;
x[TRUE ] := ax0 + adx ;
FOR i := ay0 TO ay0+ady - 1 DO (* linke und rechte Kante *)
FOR k := FALSE TO TRUE DO
Gotoxy (x[k], i);
ck := schirm[x[k],i];
ch := senkre;
IF Rahmenchar (ck) THEN
ch := ersatz [ch, ck, k];
END;
schirm[x[k],i] := ch;
FWriteCh (StdOut, ch)
END;
END;
Gotoxy (ax0-1, ay0+ady);
ck := schirm[ax0-1,ay0+ady];
ch := eckelu;
IF Rahmenchar (ck) THEN (* Ecke links unten *)
ch := ersatz [ch, ck, FALSE];
END;
schirm[ax0-1,ay0+ady] := ch;
FWriteCh (StdOut, ch);
y := ay0+ady;
FOR i := ax0 TO ax0 + adx - 1 DO (* Unterkante *)
ck := schirm[i,y];
ch := waagre;
IF Rahmenchar (ck) THEN
ch := ersatz [ch, ck, TRUE];
END;
schirm[i,y] := ch;
FWriteCh (StdOut, ch)
END;
ck := schirm[ax0+adx,ay0+ady];
ch := eckeru;
IF Rahmenchar (ck) THEN (* Ecke rechts unten *)
ch := ersatz [ch, ck, TRUE];
END;
schirm[ax0+adx,ay0+ady] := ch;
FWriteCh (StdOut, ch)
END
END Rahmen;
(*--------------------------------------------------------------------------*)
PROCEDURE ScrollUp;
(*--------------------------------------------------------------------------*)
VAR i, k, l, p : CARDINAL;
BEGIN
WITH workarea^ DO
p := ax0+adx-1;
l := 0;
FOR k := ay0 TO ay0+ady-2 DO
Gotoxy (ax0, k);
FOR i := ax0 TO p DO
inarea [l] := inarea [l+adx];
schirm [i,k] := inarea [l];
FWriteCh (StdOut, inarea[l]);
INC (l)
END;
END;
p := ay0+ady-1;
Gotoxy (ax0, p);
FOR i := ax0 TO ax0+adx-1 DO
inarea [l] := ' ';
schirm [i,p] := inarea [l];
FWriteCh (StdOut, inarea[l]);
INC (l)
END
END
END ScrollUp;
(*--------------------------------------------------------------------------*)
PROCEDURE WriteLn;
(*--------------------------------------------------------------------------*)
VAR ch : CHAR;
i, k : CARDINAL;
BEGIN
IF workarea = NIL THEN
ch := CRKey;
FWriteCh (StdOut, ch);
axc := 0;
IF ayc < ady-1 THEN
INC (ayc)
ELSE
FOR i := 0 TO adx-1 DO
FOR k := 0 TO ady-2 DO
schirm[i,k] := schirm[i,k+1]
END;
schirm[i,ady-1] := ' '
END
END
ELSE
WITH workarea^ DO
IF ayc = ady - 1 THEN
ScrollUp
ELSE
INC (ayc)
END;
axc := 0;
Gotoxy (ax0, ay0+ayc)
END
END;
END WriteLn;
(*--------------------------------------------------------------------------*)
PROCEDURE Write (ch : CHAR);
(*--------------------------------------------------------------------------*)
BEGIN
IF ch = CRKey THEN
WriteLn
ELSIF ch <> 0c THEN
IF axc >= adx THEN
WriteLn
END;
FWriteCh (StdOut, ch);
schirm [ax0+axc, ay0+ayc] := ch;
IF workarea <> NIL THEN
workarea^.inarea[axc+ayc*adx] := ch;
END;
INC (axc)
END
END Write;
(*--------------------------------------------------------------------------*)
PROCEDURE ShowArea;
(*--------------------------------------------------------------------------*)
VAR i, k : CARDINAL;
BEGIN
IF workarea = NIL THEN
FOR k := 0 TO maxy DO
Gotoxy (0, k);
FOR i := 0 TO maxx DO
FWriteCh (StdOut, schirm[i,k])
END;
END;
GotoXY (fxc, fyc)
ELSE
WITH workarea^ DO
GotoXY (0, 0);
FOR i := 0 TO adx*ady-1 DO
Write (inarea[i])
END;
axc := xcurs;
ayc := ycurs;
Gotoxy (ax0+axc, ay0+ayc)
END;
END;
END ShowArea;
(*--------------------------------------------------------------------------*)
PROCEDURE ResetAktiv (bereich : Area);
(*--------------------------------------------------------------------------*)
(* der weitere Output geht wieder in Area bereich *)
BEGIN
IF workarea <> NIL THEN
WITH workarea^ DO (* save cursor *)
xcurs := axc;
ycurs := ayc
END;
ELSE
fxc := axc;
fyc := ayc
END;
workarea := fenster1;
WHILE (workarea <> NIL) AND (workarea <> bereich) DO
workarea := workarea^.nextarea
END;
IF workarea <> NIL THEN
WITH workarea^ DO
ax0 := xmin;
ay0 := ymin;
adx := breite;
ady := hoehe;
axc := xcurs;
ayc := ycurs;
Gotoxy (ax0+axc, ay0+ayc)
END;
ELSE
ax0 := 0;
ay0 := 0;
adx := maxx+1;
ady := maxy+1;
GotoXY (fxc, fyc)
END
END ResetAktiv;
(*--------------------------------------------------------------------------*)
PROCEDURE SetAktiv (bereich : Area);
(*--------------------------------------------------------------------------*)
(* der weitere Output geht in Area bereich *)
BEGIN
IF workarea <> NIL THEN
WITH workarea^ DO (* save cursor *)
xcurs := axc;
ycurs := ayc
END;
ELSE
fxc := axc;
fyc := ayc
END;
workarea := fenster1;
WHILE (workarea <> NIL) AND (workarea <> bereich) DO
workarea := workarea^.nextarea
END;
IF workarea <> NIL THEN
WITH workarea^ DO
ax0 := xmin;
ay0 := ymin;
adx := breite;
ady := hoehe;
Rahmen;
END;
ELSE
ax0 := 0;
ay0 := 0;
adx := maxx+1;
ady := maxy+1
END;
ShowArea;
END SetAktiv;
(*--------------------------------------------------------------------------*)
PROCEDURE GetAktiv (VAR bereich : Area);
(*--------------------------------------------------------------------------*)
BEGIN
bereich := workarea
END GetAktiv;
(*--------------------------------------------------------------------------*)
PROCEDURE ClearScreen;
(*--------------------------------------------------------------------------*)
BEGIN
Send (ClrScreen);
END ClearScreen;
(*--------------------------------------------------------------------------*)
PROCEDURE ClearArea;
(*--------------------------------------------------------------------------*)
VAR i, k : CARDINAL;
BEGIN
IF workarea = NIL THEN
FOR k := 0 TO maxy DO
FOR i := 0 TO maxx DO
schirm[i,k] := ' '
END;
END;
Send (ClrScreen);
fxc := 0;
fyc := 0;
ELSE
GotoXY (0, 0);
WITH workarea^ DO
FOR i := 0 TO adx*ady-1 DO
Write (' ')
END;
xcurs := 0;
ycurs := 0;
END;
END;
GotoXY (0, 0)
END ClearArea;
(*--------------------------------------------------------------------------*)
PROCEDURE ClearToEOL;
(*--------------------------------------------------------------------------*)
VAR sav, i : CARDINAL;
BEGIN
sav := axc;
FOR i := axc TO adx-1 DO
Write (' ')
END;
GotoXY (sav, ayc)
END ClearToEOL;
(*--------------------------------------------------------------------------*)
PROCEDURE ClearLine;
(*--------------------------------------------------------------------------*)
BEGIN
GotoXY (0, ayc);
ClearToEOL
END ClearLine;
(*--------------------------------------------------------------------------*)
PROCEDURE WriteString (VAR s : ARRAY OF CHAR);
(*--------------------------------------------------------------------------*)
VAR i : CARDINAL;
BEGIN
IF s[0] <> 0c THEN
FOR i := 0 TO Length (s)-1 DO
Write (s[i])
END
END
END WriteString;
(*--------------------------------------------------------------------------*)
PROCEDURE CursorDown;
(*--------------------------------------------------------------------------*)
BEGIN
IF workarea <> NIL THEN
WITH workarea^ DO
IF ayc = ady-1 THEN
ScrollUp
ELSE
INC (ayc);
END;
END
ELSIF ayc < ady-1 THEN
INC (ayc)
END;
GotoXY (axc, ayc)
END CursorDown;
(*--------------------------------------------------------------------------*)
PROCEDURE CursorUp;
(*--------------------------------------------------------------------------*)
BEGIN
IF ayc > 0 THEN
DEC (ayc)
END;
GotoXY (axc, ayc)
END CursorUp;
(*--------------------------------------------------------------------------*)
PROCEDURE CursorLeft;
(*--------------------------------------------------------------------------*)
BEGIN
IF axc > 0 THEN
DEC (axc);
GotoXY (axc, ayc)
ELSE
axc := adx - 1;
CursorUp
END
END CursorLeft;
(*--------------------------------------------------------------------------*)
PROCEDURE CursorRight;
(*--------------------------------------------------------------------------*)
BEGIN
IF axc < adx-1 THEN
INC (axc);
GotoXY (axc, ayc)
ELSE
axc := 0;
CursorDown
END
END CursorRight;
(*--------------------------------------------------------------------------*)
PROCEDURE DeleteOne;
(*--------------------------------------------------------------------------*)
VAR i, k, l : CARDINAL;
BEGIN
IF workarea <> NIL THEN
WITH workarea^ DO
xcurs := axc;
ycurs := ayc;
k := axc+ayc*adx;
l := (ayc+1)*adx-1;
i := k;
WHILE i < l DO
inarea [i] := inarea [i+1];
Write (inarea[i]);
INC (i)
END;
inarea [l] := ' ';
Write (inarea[l]);
GotoXY (xcurs, ycurs)
END
ELSE
i := axc;
l := ayc;
WHILE axc < adx-1 DO
Write (schirm[axc+1, ayc])
END;
Write (' ');
GotoXY (i, l)
END
END DeleteOne;
(*--------------------------------------------------------------------------*)
PROCEDURE InsertChar (num : CARDINAL);
(*--------------------------------------------------------------------------*)
VAR i, k, l, xcu, ycu : CARDINAL;
BEGIN
IF workarea <> NIL THEN
WITH workarea^ DO
xcurs := axc;
ycurs := ayc;
k := axc+ayc*adx+num;
l := (ayc+1)*adx-1;
i := l;
WHILE i >= k DO
inarea [i] := inarea [i-num];
DEC (i)
END;
i := k-num;
WHILE i < k DO
inarea [i] := ' ';
INC (i)
END;
i := k-num;
WHILE i <= l DO
Write (inarea[i]);
INC (i)
END;
GotoXY (xcurs, ycurs)
END
ELSE
xcu := axc;
ycu := ayc;
k := axc+num;
l := adx-1;
i := l;
WHILE i >= k DO
schirm [i, ycu] := schirm [i-num, ycu];
DEC (i)
END;
i := k-num;
WHILE i < k DO
schirm [i, ycu] := ' ';
INC (i)
END;
i := k-num;
WHILE i <= l DO
Write (schirm[i, ycu]);
INC (i)
END;
GotoXY (xcu, ycu)
END
END InsertChar;
(*--------------------------------------------------------------------------*)
PROCEDURE BusyRead (VAR ch : CHAR);
(*--------------------------------------------------------------------------*)
BEGIN
FReadCh (StdIn, ch)
END BusyRead;
(*--------------------------------------------------------------------------*)
PROCEDURE Read (VAR ch : CHAR);
(*--------------------------------------------------------------------------*)
BEGIN
FReadCh (StdIn, ch);
CASE ch OF
CRKey : InsertChar (adx-axc); WriteLn |
DelKey : DeleteOne |
BSKey : IF (axc > 0) OR (ayc > 0) THEN
CursorLeft; DeleteOne END |
HTab : GotoXY (axc + 4, ayc) |
INSKey : InsertChar (1) |
LeftKey : CursorLeft |
RightKey : CursorRight |
DownKey : CursorDown |
UpKey : CursorUp |
HomeKey : ClearArea
ELSE
Write (ch)
END
END Read;
(*--------------------------------------------------------------------------*)
BEGIN
SetTerminal (In, CharBlank); (* einzelner Characterinput ohne Echo ! *)
InitModule;
END Area.