unit IIUWGRAPH: class; { this predefined class enables basic graphic operations } { the early versions of library IIUWGRAPH have been elaborated by Piotr Carlsson, Miroslawa Milkowska, Janina Jankowska, Michal Jankowski at Institute of Informatics, University of Warsaw 1987, and added to Loglan system by Danuta Szczepanska 1987, the recent versions were done at LITA, Pau, by Pawel Susicki (1991) for Unix Sebastien Bernard (1992) for ATARI fait à Pau, le {TIME \@ "d MMMM, yyyy"|6 August, 1993} A.S.} { the predefined class IIUWGRAPH is included in all versions of interpreter of Loglan, with the exception of the present version of interpreter for VAX/VMS. Each interpreter is equipped with one version of graphic library which corresponds to one of the following possibilities: - EGA card, (use egaint if you have a VGA card) - Hercules mono card, - IBM CGA card several variants are offered CGA colour, CGA mono 320 x 200 CGA mono 640 x 200 all above versions were tested in DOS 3.3 environment - an emulation of Hercules in a Xwindow for UNIX environment, - an emulation of IIUWGRAPH in ATARI STE environment. NEW (october 1993) MM. Becourt et Larrieu did a multiwindow graphic co-process for the int Loglan interpreter in Unix & Xwindows environment. See the separate document on it. M. Larrieu did an experimental version of vgaint Loglan executor for the machines 386/486. } hidden MaxX, MaxY, current_X, current_Y, is_graphic_On, current_Colour, current_Background_Colour, current_Style, current_Palette, current_Pattern ; { Hercules EGA/VGA CGA Unix } const MaxX = 719 ; { 639 319 } MaxY = 347 ; { 349 199 } { the screen's coordinates are (0,0) ----------------------> (MaxX,0) ¦ ¦ ¦ V (0, MaxY) (MaxX,MaxY) } var currentDriver : integer, { see NOCARD below } current_X, current_Y: integer { it is the current position } is_graphic_On: Boolean, { evidently tells whether we are in graphics mode } current_Colour : integer, { } current_Background_Colour : integer, current_Style : integer, { } current_Palette : integer, current_Pattern unit GRON : procedure (i: integer); { procedure sets the monitor in graphic mode and clears the buffer of screen. The parameter is meaningless, the only exception is made for the IBM CGA card in this case if you have chosen the mode 320x200 pixels the the value 1 of the parameter means colours, the value 0 means a mono screen is connected to the card } unit GROFF : procedure; { the procedure sets the monitor in the text mode filling it with spaces. DO NOT FORGET to set the monitor in the text mode before you terminate your program } unit NOCARD : function : integer; { the value given by this function determines the type of the currently used monitor and it is equal to 1 for Hercules mono card, 2 for IBM CGA color 3 for IBM CGA mono 320 x 200 4 for IBM CGA mono 640 x 200 5 for EGA/VGA card ?? 6 for ATARI STE ?? 7 for Unix versions equipped with XWindows You can not call the function nocard before GRON sets the graphic mode } unit CLS : procedure; { the screen will be cleared and filled with colour 0 } unit HPAGE : procedure(nr, : integer, clear : boolean); { the procedure is applicable to the cards EGA/VGA and Hercules only! it selects a page of video memory with the number = nr, clears its contents if clear is set <>0, and sets the mode mode = 0 the content of the page is shown as text, mode = 1 the content of the page is shown graphically, mode = -1 a worktime buffer is associated with the page. Mode -1 does not change the number not the way it is shown. Mode 0 links the buffer with the selected page. For card Hercules only call HPAGE(0, 1, 1) is equivalent to call GRON(99) and call HPAGE(0, 0, 1) is equivalent to call GROFF. Example of an animating loop var nr: integer; begin call GRON(0); nr := 1; (* draw first image *) call DRAW(...) ... while more do call HPAGE(1-nr, 1,0); (* displaying *) call HPAGE(nr, -1,1); (* buffering *) (* draw modified image *) call DRAW( ...) ... nr := 1-nr od end example unit VIDEO : procedure( A: array of integer); { this procedure can not be applied for the EGA/VGA card } { the worktime buffer will be associated with the array A. A call of VIDEO does not change the contents of the buffer. All subsequent calls of the procedures modifying the screen will concern the array A. The screen does not change. A ready image can be moved to the screen with the help of GETMAP/PUTMAP procedures or it can be stored on disk. The array should have 16 kBytes for IBM CGA card or 32 kBytes for Hercules card.} { PROCEDURES CONTROLLING THE COLOURS } unit COLOR : procedure(co : integer); { sets current color to co for monochrome displays, 0 means black, non-0 - white for color displays, 0 means background see PALLET } unit STYLE : procedure(styl : integer); { sets style of lines and fill shades to a combination of current color and background color (for mono - white and black, respectively) according to 5 predefined patterns: 0 .... 1 **** 2 ***. 3 **.. 4 *.*. 5 *... where '*' means current color, '.' background colour When drawing the segments the subsequent pixels will have colour determined by cyclic application of style pattern. The first and the last pixels of a segment will have always current colour. When filling contours the given style will be applied to horizontal lines with even coordinate. The style for odd lines is determined automatically. The same applies for perpendicular lines. There are other possibilities of mixing colours, cf procedure PATERN. } unit PATERN : procedure (par, par1, par2, par3 : integer); { sets style of lines and fill shades to an explicitly specified combination of colours. When drawing lines the only parameter of importance will be par. When filling the parameters par and par2 concern the horiwontal (resp. perpendicular) lines with the coordinate x (resp: y) even. lines combination of colors : "iv" for even scan lines, "io" for odd. Color encoding is decimal, allowing 4 pixels. Lines are drawn always according to "iv". Examples: call patern(1100,0011) is equivalent to call color(1), call style(3) call patern(1212,2121) produces a shade that cannot be otherwise achieved ( a dotted line consisting of pixels in colors 1 and 2 ) unit BORDER : procedure (background_Colour: integer); [ IBM color mode only ] sets actual background color to i ( i = 0,1,...,15 ) unit PALLET : procedure (nr : integer); { the codes of colors are as follows 0 black 1 blue dark 2 green dark 3 turquoise dark 4 red dark 5 violet 6 brown 7 grey light 8 grey dark 9 blue 10 green 11 turquoise 12 red light 13 rose 14 yellow 15 white the procedure does not applies for Hercules card} unit INTENS : procedure (i : integer); { changes current intensity, 1 means more intensity, 0 less; default intensity is 1 Applies to IBM CGA only } { PROCEDURES CONTROLLING POSITION } unit MOVE : procedure (x,y :integer); { procedure MOVE sets the current position on the screen on the pixel with coordinates x - column, y - line } { precondition of MOVE: 0{SYMBOL 163 \f "Symbol"}x{SYMBOL 163 \f "Symbol"}MaxX & 0{SYMBOL 163 \f "Symbol"}y{SYMBOL 163 \f "Symbol"}MaxY } unit INXPOS : function: integer; { function INXPOS returns the x coordinate of the current position } unit INYPOS : function : integer; { function INYPOS returns the y coordinate of the current position } unit PUSHXY : procedure; { pushes current position, color & style onto the stack. The stack is kept internally, max depth is 16 } unit POPXY: procedure; { restores position, color & style from internal stack } { Example unit DIAGONAL : procedure; var ix, iy : integer; begin call PUSHXY; ix := INXPOS; iy := INYPOS; call DRAW(ix+10, iy+10); call POPXY end DIAGONAL; } unit TRACK : procedure (x,y : integer); { displays a small (8*8) arrow-shaped cursor which can be moved around with cursor keys; a single keystroke moves it by 5 pixels, in NUM mode step size is 1 pixel; "home" key returns the cursor to the initial (x,y); "end" removes cursor from screen, and returns - the new current position can be read with "INXPOS" and "INYPOS" above. ATTENTION: if you have a mouse then read on the predefined class Mouse, which permits to control the mouse } { PROCEDURES SERVING POINTS } unit POINT : procedure(x,y: integer); { moves current position to pixel (x,y) and sets it to current color } unit INPIX : function (x,y : integer) : integer; { moves to pixel (x,y) and returns its color setting; } unit DRAW : procedure( x,y : integer); { draws a line from current screen position to (x,y); sets current position to (x,y); line is drawn in current color, with both terminal pixels always turned white ( non-background) for non-black ( non-background ) line color. Bresenham's algorithm is used, pixels belonging to the segment change their state depending on current colour and style. } unit CIRB : procedure (xi, yi, ri : integer, alfa, beta : real, cbord, fill, p, q : integer); { draws a circle (or ellipse, depending on aspect value, see below), optionally filling its interior; does not preserve position; (xi,yi) - are center coordinates ri - radius in pixels (horizontally) alfa, beta - starting & ending angles; if alfa=beta a full circle is drawn; values should be given in radians; cbord - border color, fill - if fill <>0, interior is filled in current style&color p,q - aspect ratio; if p/q=1, a perfect circle is drawn, if p/q<1, the horizontal axis is longer, if p/q>1 - the vertical axis is longer; } unit HFILL : procedure(x: integer); { fills current row (horizontally) from current position (INXPOS, INYPOS) up to (x,INYPOS) with bit pattern depending on current color, style and/or pattern and position on the screen in such a way that adjacent "hfill"ed" rows will produce a shade simulating color; ATTENTION hfill does not change current position; It is advised to use hfill when filling contours since it works faster then DRAW. Procedure hfill is capable to similate additional colours. } unit VFILL : procedure(y: integer); { fills current column ( vertically ) from current position (INXPOS, INYPOS) up to (INXPOS, y) in a similiar way that "hfill" does; rectangular area "vfill'ed" is not distinguishable on the screen from same shape "hfill'ed", except that it will take much longer to fill. ATTENTION hfill does not change current position; { Procedures operating on bitmaps } unit GETMAP : function (x,y : integer) : arrayof integer; {saves rectangular area between current position as top left corner and (ix,iy) as bottom right corner, including border lines; position remains unchanged. array of integer should have 4+(rows{SYMBOL 215 \f "Symbol"}{SYMBOL 233 \f "Symbol"}columns/8{SYMBOL 249 \f "Symbol"} {SYMBOL 215 \f "Symbol"}coeff) bytes. The coefficient coeff is 1 for Hercules, 2 for CGA, 4 for EGA card. ATTENTION: in DOS environment the size of the array may necessitate the use of loglan with the option H+, see also memavail } unit PUTMAP : procedure ( a: array of integer); {sets rectangular area of screen pixels to that saved by "getmap" in "iarray"; same size is restored, with top left corner in current position; position remains unchanged. } unit ORMAP : procedure ( a : arrayof integer); {same as putmap, but saved bitmap is or'ed into screen rather than just set. } unit XORMAP : procedure ( a: arrayof integer); {same as putmap, but saved bitmap is xor'ed into screen rather than just set. } unit INKEY : function : integer; {returns next character from keyboard buffer; 0 is returned if buffer is empty; special keys are returned as negative numbers; ALT-NUM method may be used for entering character codes above 127 (this makes entering special keys 128-132 impossible); if a character is returned, it is also removed from the buffer, so MS-DOS will not see it (CTRL-C!); typeahead is allowed, echo is suppressed. } unit HASCII : procedure {'xor's the character in a 8*8 box with top left corner in the current position; moves current position by (8,0); character code 0 sets complete box to black ( background ), with no change in position. BIOS ROM font for IBM color card is used. If the font table is not at F000:FA6E, the character will probably be unrecognizable, and most certainly wrong. For codes >127, table pointed to by interrupt vector 31 is used. } unit HFONT {sets 8*8 horizontal font table address to iseg:ioffs.} unit HFONT8 {includes a copy of IBM ROM 8*8 font and returns address suitable for passing to "hfont"; Use of "hfont8" makes program larger but quarantees BIOS ROM independence.} unit INHLINE : procedure (a: arrayof char; output n : integer); { reads a line of at most "n" characters from the keyboard, storing them in the "a" array; characters are echoed at current position with "hascii" as they are typed in; a blinking cursor prompts for the next character; BACKSPACE works as expected, RETURN completes the reading; typing "n"-th character also completes the line; "l" is blank filled up to "n" bytes; on return "n" is the total number of characters read. } unit OUTHLINE : procedure (a : arrayof char; n : integer); { calls "hascii" "n" times with subsequent bytes from "a" array as arguments; before each character is written, "hascii(0)" is called. } end IIUWGRAPH; à Pau, le {DATE|06/08/93} {PAGE|4} Predefined class IIUWGRAPH {PAGE|3}