home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turbo Toolbox
/
Turbo_Toolbox.iso
/
sonderh1
/
gsxlib2.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1979-12-31
|
13KB
|
319 lines
{---------------------------------------------------------------------------}
{ gsxlib2.pas - Pascal GSX Bibliothek: }
{ GDPs, Eingabe-Funktionen }
{---------------------------------------------------------------------------}
{ Inhalt:
Bar, Circle_Segment, Circle, Graph_Chars, Get_Color, Get_Cell_Array,
Set_Input_Mode, Locate, Valuate, Choice, Input_String }
{**-----------------------------------------------------------------------**}
{** Hier folgen die Generalized-Drawing-Primitives. Diese Zeichenmakros **}
{** sind von 1 (= Bar) bis 5 (= GraphChar) durchnummeriert. **}
{** Dadurch kann man aus dem Wert von 'GDPs' unmittelbar entnehmen, bis **}
{** zu welchem GDP diese vom Treiber unterstuetzt werden. **}
{** (siehe Begleitartikel: GSX, die unbek. Groesse, Teil 1, Heft 1/87. **}
{**-----------------------------------------------------------------------**}
{ Zeichnen eines durch Eckkoordinaten bestimmten Rechtecks. Benutzt werden
die aktuellen 'Fill'-Attribute. }
PROCEDURE Bar (xlb, ylb, { linke, untere Ecke }
xrt, yrt: INTEGER); { rechte, obere Ecke }
BEGIN
contrl[1] := 11; contrl[2] := 2; contrl[6] := 1;
ptsin[1] := xlb; ptsin[2] := ylb;
ptsin[3] := xrt; ptsin[4] := yrt;
VDI_Call(contrl, intin, intout, ptsin, ptsout);
END;
{---------------------------------------------------------------------------}
{ Ein Kreissegment als Kreisbogen (Arc) oder Tortenstueck (PieSlice) zeich-
nen. 'xc', 'yc' = Kreismittelpunkt, 'xs', 'ys' gibt den Startpunkt des
Kreisbogens an, 'angle' den Winkel. Ist 'angle' positiv, wird das Kreis-
segment im Uhrzeigersinn gezeichnet, andernfalls gegen selbigen. }
PROCEDURE Circle_Segment (SegmentType: Circle_Types;
xc, yc, xs, ys, angle: REAL);
VAR xe, ye: INTEGER;
a, b, t, r: REAL;
BEGIN
{ die fehlenden, konsisdenten Parameter fuer GSX berechnen: }
t := ys-yc;
r := Sqrt(Sqr(xs-xc)+Sqr(t));
t := t/r;
a := ArcTan(t/Sqrt(1-t*t))*180.0/pi;
IF a < 0 THEN a := 360.0-a;
b := a-angle;
IF b < 0 THEN b := 360.0-b;
t := (180.0-b)*pi/180.0;
xe := -Round(r*cos(t)-xc);
ye := Round(r*sin(t)+yc);
contrl[1] := 11; contrl[2] := 4; contrl[6] := SegmentType;
ptsin[1] := Round(xc); ptsin[2]:= Round(yc);
IF angle < 0.0 THEN
BEGIN
intin[1] := Round(b*10); intin[2] := Round(a*10);
ptsin[3] := xe; ptsin[4] := ye;
ptsin[5] := Round(xs); ptsin[6] := Round(ys);
END
ELSE
BEGIN
intin[1] := Round(a*10); intin[2] := Round(b*10);
ptsin[3] := Round(xs); ptsin[4] := Round(ys);
ptsin[5] := xe; ptsin[6] := ye;
END;
ptsin[7] := Round(r);
ptsin[8] := 0;
VDI_Call(contrl, intin, intout, ptsin, ptsout);
END;
{---------------------------------------------------------------------------}
{ Einen Kreis, der durch die Koordinaten xc,yc (Mittelpunkt) und xu,yu (auf
dem Kreis liegend) bestimmt ist, zeichnen. Es werden die aktuellen 'Fill'-
Attribute benutzt. Die Parameter sind vom Typ REAL, da Turbo-Pascal Pro-
bleme mit den Zwischenergebnissen bei der Berechnung des Radius (ptsin[5])
hat. }
PROCEDURE Circle (xc, yc, xu, yu: REAL);
BEGIN
contrl[1] := 11; contrl[2] := 3; contrl[6] := 4;
ptsin[1] := Round(xc); ptsin[2] := Round(yc);
ptsin[3] := Round(xu); ptsin[4] := Round(yu);
ptsin[5] := Round(Sqrt(Sqr(xu-xc)+Sqr(yu-yc))); ptsin[6] := 0;
VDI_Call(contrl, intin, intout, ptsin, ptsout);
END;
{---------------------------------------------------------------------------}
{ Zeichenkette mit Grafikzeichen aus dem Sonderzeichensatz mancher Drucker
(Diablo, Epson) ab der Position x,y drucken. }
PROCEDURE Graph_Chars (x, y: INTEGER; VAR s: VDI_STRING);
BEGIN
contrl[1] := 11; contrl[2] := 1; contrl[4] := Length(s);
ptsin[1] := x; ptsin[2] := y;
FOR x := 1 TO Length(s) DO
intin[x] := Ord(s[x]);
VDI_Call(contrl, intin, intout, ptsin, ptsout);
END;
{---------------------------------------------------------------------------}
{ Ende der GDPs }
{---------------------------------------------------------------------------}
{ Die Prozedur gibt zurueck, wie die Farbe 'Color_Index' aus Rot, Gruen
und Blau zusammengesetzt ist (s.a. Set_Color). Wenn im Parameter 'Rea-
lized' TRUE uebergeben wird, wird die vom Geraet tatsaechlich reali-
sierte Farbmischung zurueckgegeben, sonst die bei der Einstellung mit
'Set_Color' verlangte. Die Farbwerte werden in Promille (0-1000) zu-
rueck gegeben. }
PROCEDURE Get_Color (Color: Color_Index; Realized: BOOLEAN;
VAR Red, Green, Blue: INTEGER);
BEGIN
contrl[1] := 26; contrl[2] := 0;
intin[1] := Color; intin[2] := Ord(Realized);
VDI_Call(contrl, intin, intout, ptsin, ptsout);
VDI_Error := (contrl[3] <> 0) OR (intout[1] <> Color);
Red := intout[2];
Green := intout[3];
Blue := intout[4]
END;
{---------------------------------------------------------------------------}
{ Fol. Prozedur holt in Umkehrung von 'Cell_Array' die Farbmusterdefintion
einer Flaeche. Falls ein Pixel nicht eindeutig einer Farbe zugeordnet
werden kann, wird 'Invalid' gleich TRUE gesetzt. Falls im 'ColorIndex-
Array nach dem Prozedur-Aufruf fuer einen Pixel der Farbindex -1 steht,
konnte dieser nicht bestimmt werden. Weiteres siehe Begleittext. }
PROCEDURE Get_Cell_Array (xlb, ylb, { linke, untere Ecke }
xrt, yrt: INTEGER; { rechte, obere Ecke }
VAR Rows,
Columns: INTEGER;
VAR ColorIndexArray: VDI_intout;
VAR Invalid: BOOLEAN);
BEGIN
contrl[1] := 27; contrl[2] := 2;
contrl[4] := Rows*Columns; contrl[6] := Columns; contrl[7] := Rows;
ptsin[1] := xlb; ptsin[2] := ylb;
ptsin[3] := xrt; ptsin[4] := yrt;
VDI_Call(contrl, intin, ColorIndexArray, ptsin, ptsout);
Columns := contrl[8]; Rows := contrl[9];
Invalid := (contrl[10] = 1);
END;
{---------------------------------------------------------------------------}
{ GSX-Eingabefunktionen }
{---------------------------------------------------------------------------}
{ Eingabe-Modus fuer das logisches Geraet 'Device' setzen.
'Mode = Request' bewirkt, dass auf ein Eingabeereignis gewartet wird,
bevor zum Anwenderprogramm zurueckgekehrt wird. Bei 'Mode = Sample'
wird der aktuelle Status bzw. die aktuelle Position des Eingabe-Geraetes
o h n e Warten zurueckgegeben. }
FUNCTION Set_Input_Mode (Device: Input_Devices;
Mode: Input_Modes): Input_Modes;
BEGIN
contrl[1] := 33; contrl[2] := 0;
intin[1] := Device; intin[2] := Mode;
VDI_Call(contrl, intin, intout, ptsin, ptsout);
Set_Input_Mode := intout[1];
END;
{---------------------------------------------------------------------------}
{ Position des spez. Positionierungs-Gerates in Geraete-Koordinaten zurueck-
geben.
Request-Mode:
Auf dem Bildschirm erscheint ein Graphik-Cursor an der Position (x,y),
der abhaengig vom 'Locator_Device' mit den Cursortasten, Maus oder Joy-
stick manoevriert werden kann, bis ein Tastendruck folgt.
Die gedrueckte Taste wird als CHARacter in 'terminator' zurueckgegeben.
In x und y stehen die neuen Cursor-Koordinaten.
Sample-Mode:
Sinngemaess wie Request, der Cursor wird jedoch nicht dargestellt und
auch kein Abschluss der Eingabe durch Tastendruck erwartet.
Wenn die Koordinaten geaendert wurden, werden die neuen zurueckgegeben.
Findet ein Tastendruck statt, wird das entspr. Zeichen zurueckgegeben.
Geschieht nichts, wird auch nichts zurueckgegeben.
Fuer beide Modis gilt: 'terminator' = Char(0), wenn keine abschliessen-
de Taste gedrueckt wurde. Wenn das abschliessende Zeichen nicht von der
Tastatur sondern z.B. von einer Maus kommt, geben die Maustasten in auf-
steigender Reihenfolge char(32), char(33), char(34)... zurueck. }
PROCEDURE Locate (Locator: Locator_Devices; InputMode: Input_Modes;
VAR x, y: INTEGER; VAR terminator: CHAR);
BEGIN
contrl[1] := 28; contrl[2] := 1;
intin[1] := Locator;
ptsin[1] := x; ptsin[2] := y;
VDI_Call(contrl, intin, intout, ptsin, ptsout);
VDI_Error := FALSE;
terminator := Char(0);
IF InputMode = Request THEN
BEGIN
IF (contrl[5] = 0) THEN
VDI_Error := TRUE
ELSE
terminator := Char(intout[1]);
x := ptsout[1];
y := ptsout[2];
END
ELSE
BEGIN
IF (contrl[5] = 1) THEN
terminator := Char(intout[1]);
IF (contrl[3] = 1) THEN
BEGIN
x := ptsout[1];
y := ptsout[2];
END;
END;
END;
{---------------------------------------------------------------------------}
{ Denn Wert der Variable 'Value' mit z.B einem Paddle oder den Cursor-up-
und Cursor-down-Tasten aendern. Auch hier die Unterscheidung zwischen den
beiden Input-Modis wie bei 'Locate'.
Typische Implementation der Cursor-Tasten:
Cursor-up addiert 10 zu 'Value', Cursor-down subtrahiert entsprechend.
Wird eine der beiden Tasten zusammen mit SHIFT gedrueckt, wird entspr.
1 addiert bzw. subtrahiert. }
PROCEDURE Valuate (InputMode: Input_Modes;
VAR Value: INTEGER; VAR terminator: CHAR);
BEGIN
contrl[1] := 29; contrl[2] := 0; intin[2] := Value;
VDI_Call(contrl, intin, intout, ptsin, ptsout);
terminator := Char(0);
IF InputMode = Request THEN
BEGIN
Value := intout[1];
terminator := Char(intout[2]);
END
ELSE
BEGIN
IF (contrl[5] = 1) THEN
Value := intout[1];
IF (contrl[5] = 2) THEN
terminator := Char(intout[2]);
END;
END;
{---------------------------------------------------------------------------}
{ Auswahl vom selektierten 'Wahl'-Geraet. 'Device' = 1 entspricht den
Funktions-Tasten, 'Device' > 1 ist geraeteabhaengig. Die Funktions-
Tasten sind von 1 an aufsteigend durchnummeriert, wobei die Anzahl
geraeteabhaengig ist. Im Request-Modus wird solange gewartet, bis
eine gueltige Funktions-Taste gedrueckt wurde; ihre Nummer wird zu-
rueckgegeben. Im Sample-Modus wird ebenfalls die Nummer einer Funk-
tions-Taste zurueckgegeben, falls eine gedrueckt wurde. Wurde eine
Nicht-Funktions-Taste gedrueckt, so wird ihr n e g a t i v e r Wert
als Terminator zurueckgegeben. Wurde keine Taste gedrueckt, wird der
Wert 0 geliefert. }
FUNCTION Choice (Device: INTEGER; InputMode: Input_Modes): INTEGER;
BEGIN
contrl[1] := 30; contrl[2] := 0; intin[1] := Device;
VDI_Call(contrl, intin, intout, ptsin, ptsout);
IF InputMode = Request THEN
Choice := intout[1]
ELSE
CASE contrl[5] OF
0: Choice := 0;
1: Choice := intout[1];
2: Choice := -intout[2];
END;
END;
{---------------------------------------------------------------------------}
{ Zeichenkette vom spez. Geraet einlesen, falls dieses dafuer geeignet.
'Device' = 1 ist die Tastatur der Konsole. Andere Werte fuer 'Device'
sind geraeteabhaengig.
Request-Modus:
Es werden solange Zeichen eingelesen, bis RETURN/ENTER eingegeben oder
'maxlen' erreicht wird. Wenn 'Echo' = TRUE, so wird der Text in den
aktuellen Text-Attributen ab der Position (x,y) auf dem Bildschirm
dargestellt.
Sample-Modus:
Es werden die im Puffer 'anstehenden' Zeichen eingelesen, bis eine
der folgenden Bedingungen eintritt:
- es ist kein weiteres Zeichen verfuegbar
- RETURN/ENTER wurde angetroffen
- 'maxlen' wurde erreicht
Es wird sofort zum Programm zurueckgekehrt, wenn keine Eingabe vorliegt.
PROCEDURE Input_String (Device, maxlen: INTEGER;
InputMode: Input_Modes;
Echo: BOOLEAN; x, y: INTEGER;
VAR st: VDI_STRING);
BEGIN
contrl[1] := 31; intin[1] := Device; intin[2] := maxlen;
IF InputMode = Sample THEN
contrl[2] := 0
ELSE
BEGIN
contrl[2] := Ord(Echo); intin[3] := contrl[2];
ptsin[1] := x; ptsin[2] := y;
END;
VDI_Call(contrl, intin, intout, ptsin, ptsout);
st[0] := contrl[5];
FOR x := 1 TO contrl[5] DO
st[x] := Char(intout[x]);
END;
{---------------------------------------------------------------------------}
{ Ende von gsxlib2.pas }