qb2c:      BASIC with X11 graphics for UNIX and Linux
qb2c:      Quasi - Microsoft's (R) QuickBASIC (C) to ANSI C translator
QB2C home page: http://faust.irb.hr/~stipy/qb2c/qb2c.html
     mirrors:   http://pclei05.irb.hr/~mario/qb2c/qb2c.html
                http://nomadinfo.cern.ch/~stipy/qb2c/qb2c.html
QB2C ftp site : ftp://darkstar.irb.hr/pub/qb2c/qb2c.tgz
Author:  Mario Stipcevic, Rudjer Boskovic Institute, Zagreb, Croatia
         E-mail: stipcevi@rudjer.irb.hr URL: http://faust.irb.hr/~stipy
Version: 3.2k 24-Sep-1998
 
 QB2C is a package which makes possible execution of BASIC programs
under most of the UNIX systems provided that a C compiler is available 
on the system. It essentially consists of the BASIC-to-C translator
(qb2c) which translates BASIC code into C code, graphics included.
The BASIC syntax largely follows Microsoft's (R) QuickBASIC (C) syntax.
Normal BASIC graphics is now output to X11 console, therefore X11 
is also required. Additional possibility to mix BASIC and C code
within the single program file makes QB2C more than just a translator: 
it can serve as a tool for easy C programming, especially of small
programs and compiled substitutes for shell scripts.

 There is some rudimentary X11-windows-based graphics built into
the QB2C including dot, line and marker drawing, filling polygonal
areas, mouse pointer and image manipulation, loading/saving GIF format
on/from screen etc. The extensive source on this topics is given
in this manual.

 Versions from 3.0 on can deal with more than one (up to 16) X-windows
at a time. 

 Versions from 3.5 on are payware, price is 25 US$. See the ANNOUNCEMENT
file for more information.

 Intrinsically qb2c understands only programs written in strict 
QuickBASIC syntax (BASIC keywords in capital, proper spacing...), 
but 'bcpp' syntax preprocessor can translate a variety of BASIC styles 
into QB format thus making the whole thing much more flexible. 
Currently, there is no support (preprocessing) for Visual Basic
command style (such as 'While'...). 

 Scripts 'brun' (to run directly BASIC programs) and 'bcc' (to compile 
BASIC program and produce an executable) are also provided in order to make
life easier. Script 'run' may be used to run directly C programs. In either
case user must supply *only* the bare name (i.e. without the extension .c)
of a file to be run or compiled. User may change these to suit his/her needs 
or system specifics.

 BASIC is an easy-to-learn and user friendly programming language which 
is in principle known to everybody. One of ideas behind this project was
to be able to use scripts made in BASIC as all-around tool for building 
user-made commands and interfaces to existing UNIX commands. It is true 
though that BASIC has a rather limited access to UNIX system, but QB2C 
allows to circumvent this problem by mixing BASIC and C text in a single 
program/file. (See the example at the end of the manual.) 
With time and with addition of some X11-based graphic capabilities, QB2C 
proved to be an excellent tool for writing small, handy programs that
execute on virtually any UNIX system, and as a help in writing C programs. 
Its graphics capabilities also grew to a level where they can be used
to produce nontrivial programs with less effort when compared to
some other programming tools. 

 QB2C itself can run on any system which has ANSI C installed. To
make the executable qb2c available, just compile qb2c.c .


QB2C packet consists of:

qb2c         qb2c translator;
bcpp         BASIC -> C syntax preprocessor. One needs that when the
             input BASIC text is not exactly in QuickBASIC format;
calib        Tool used to 'calibrate' key(board) codes of your UNIX
             system to match QB standard (see the DIFFERENCES section);
libqbX11.a   QuickBasic's X11-based graphics library 
bcc          The BASIC compiler
brun         The script to run BASIC programs in UNIX;
run          The script to run C programs
bhelp        The script to display this short manual

and the following example files:

graphic.bas  demonstrates the normal 1-window BASIC graphics
xtest.bas    demonstrates multi-window graphics and mouse operation
request.bas  demonstrates use of XREQST function to input text from graphics
animate.bas  demonstrates animation using XANIM
button.bas   demonstrates creation and use of simple 3D button

These can simply be run by: brun name , where 'name' is the name of the
desired example with the extension ".bas" STRIPPED OFF. Example:
brun animate

QB2C MAIN FEATURES: 

* Recognizes MAIN, SUBroutines and FUNCTIONs

* Declares variables (int, real, char) inside MAIN and inside every SUB.
  All arguments are passed to user-defined SUBroutines as pointers, so
  that SUBroutines can affect their values, as in QuickBASIC.
  Arguments of a SUB are therefore not declared in the SUB.

* Takes care of SHARED variables. 
  If a variable is SHARED it is not declared inside the respective SUB,
  but as a global variable seen by every other FUNCTION, SUBroutine and main.
  A complete list of shared variables appears in preamble of the translated C 
  program.

* Treats UNIX formatted ASCII (text) files as QB would treat
  DOS formatted ASCII files. The difference between the two is
  that DOS line terminator is newline + CR while UNIX uses only newline 
  character terminate a line of text.

* Translates logical expressions from QB form to C form

* Brakes up multiple lines (:) into single lines in C

* Keeps all original REMarks and places them intelligently. Does add 
  a few of its own remarks (about shared variables in SUBs, and in preamble)

* Writes out C text neatly

* Recognizes and translates over 80 BASIC keywords: 

 ... the following QB commands and keywords:
 o SUB ... END SUB
 o EXIT SUB
 o FUNCTION ... END FUNCTION
 o STATIC  (as a qualifier of SUB or FUNCTION)
 o SHARED
 o CONST
 o DECLARE
 o DIM
 o IF ... THEN ... ELSE ... END IF
 o FOR ... TO ... STEP ... NEXT
 o DO WHILE ... LOOP
 o WHILE ... WEND
 o GOTO
 o GOSUB
 o RETURN
 o Labels
 o CALL
 o OPEN .. FOR mode AS #n  
   where 'mode' is INPUT, OUTPUT, APPEND
 o CLOSE #n
 o EOF
 o EXISTS
 o PRINT #n
 o PRINT
 o LOCATE
 o COLOR
 o CLS
 o LINE INPUT #n
 o INPUT #n
 o INPUT
 o COMMAND$
 o INKEY$()
 o DATE$
 o TIME$
 o TIMER
 o PAUSE
 o RANDOMIZE
 o SHELL
 o REM
 o LET
 o GET (graphics)
 o PUT (graphics)
 o END 
 
 ... basic string processing functions: 
 o SPACE$, MID$, LEFT$, RIGHT$, STR$, CHR$, ASC, VAL, LEN

 ... and mathematical functions:  
 o LOG, SIN, COS, TAN, ATN, SQR, ABS, EXP, SGN, RND, INT, CINT MIN, MAX,
   MOD and power ^

 ... and a limited number of graphics statements + some non-BASIC ones:
 o SCREEN, PALETTE, SET, PSET, PGET, LINE, CIRCLE, PLINE, FAREA, MARKER,
   PMARKER, XWINDOW, XTEXT, XUPDATE, XCLS, XSELWI, SAVEGIF, LOADGIF, GIFINFO,
   GCGET, XPOINTER, XCURSOR, XTITLE, XREQST, XCLIP, XNOCLI, XWARP, GET, PUT,
   XANIM, GETCOL, XGETGE
   (see the graphics section of this manual).

* If a line cannot be translated a WARNING or ERROR are issued, the  
  line and its number dumped at the screen and the translating 
  process stopped.

* There are few syntax or other errors which can be detected  
  during translation. Translation assumes that the input QuickBASIC
  program is itself (almost) debugged. Preprocessor bcpp does some additional
  simple checks like brackets and double quotes balance etc.

+ Reference Manual +

DIFFERENCES
  
o DIFFERENCES 
  In BASIC, for example 5 / 8 equals to 0.625 while in C this is equal 
  to 0 (integer zero) because the binary operator "/" acts as the integer
  division operator when both operands are integer numbers. QB2C translator
  will therefore also produce zero for such expressions unless they are 
  written in one of the following ways:
  5. / 8., 5. / 8, 5 / 8., 5! / 8, 5 / 8!, 5! / 8!, (0.+ 5) / 8 etc. 
  A BETTER way is to tell QB2C to translate properly by specifying options
  "-b -r" in which case the preprocessor bcpp is turned on and it replaces
  every division operator " / " with " / (double)". This is NOT a default.
 
o DATE$ has more possible formats:
  DATE$ or DATE$(0)  ->   12-27-1996   (the default QuickBASIC format)
  DATE$(1)           ->   27.12.1996
  DATE$(2)           ->   27/12/1996
  DATE$(3)           ->   27-Dec-1996
  DATE$(4)           ->   Sun Dec 27 15:14:37 1996

o INKEY$  
  Usage:   a$ = INKEY$
  This implementation of INKEY$ waits until a key is pressed
  and then returns a string associated to a character pressed. Unlike
  the INKEY$ in QuickBASIC it cannot return empty string (""). This
  should not cause any noticeable differences in operation of programs
  since INKEY$ is usually embedded in an outer loop which is exited when
  a key is pressed. 

  According to QB, when a key is pressed, INKEY$ returns a string which 
  corresponds to the key. Most keys return a string of length one (single 
  character). Extended keys are represented with a string of length 2.
  Key codes of ordinary keys are emulated by QB2C exactly as they are in
  QuickBASIC whereas codes of extended keys are (hopefully insignificantly) 
  different. The only difference is that the first code is 1 instead of 0.

  Here is the list of extended keys and their ASCII codes:

  Key   QB2C   QBASIC     Key     QB2C   QBASIC     Key          QB2C  QBASIC  
  F1    1 59   0 59       F9      1 67   0 67       End          1 79  0 79
  F2    1 60   0 60       F10     1 68   0 68       Page Down    1 81  0 81
  F3    1 61   0 61       F11     1 133  0 133      Cursor Up    1 72  0 72
  F4    1 62   0 62       F12     1 134  0 134      Cursor Left  1 75  0 75
  F5    1 63   0 63       Insert  1 82   0 82       Cursor Down  1 80  0 80
  F6    1 64   0 64       Home    1 71   0 71       Cursor Right 1 77  0 77
  F7    1 65   0 65       Page Up 1 73   0 73
  F8    1 66   0 66       Delete  1 83   0 83

  This is not all ! As different implementations of screen codes in UNIX 
  are not unique, it is necessary to 'calibrate' your keyboard in some way.
  If you are going to use INKEY$ function you should definitely do this 
  by running program calib. The program will ask you to press extended keys 
  listed above and will create the file .kbcalib in your $HOME directory. 

o Constants

   Constant numbers may be represented with or without leading and/or 
  trailing zeros, and in exponential notation. For example the
  following are equivalent:
  0.001
  .001
  000.001
  0.001000 
   Exponential notation allows more convenient and compact writing of very 
  large or very small numbers:
  1000000000 is equivalent to: 1E9,  1e9, 1E+9 or 1e+9 .
  .000000001 is equivalent to: 1E-9 or 1e-9 .
 
  Numbers, whether in ordinary or in exponentioal notation *must be written
  without any spaces*. For example, the following is invalid:
  a = 1 000 000
  b = 1E 9
  etc.
  
   When associted to a variable, constant numbers is always automatically 
  converted to the variable type. For example:
  a = 1
  or
  a = 1 
  is equivalent to:
  a = ((float) 1)
  in C.
  
o IF ... THEN
  IF ... THEN ... ELSE
  IF ... GOTO
  

o LOCATE row, column 
o COLOR  [bg[, fg]]
  LOCATE and COLOR appear reduced to their essence. Syntaxes are:
  x, y, bg and fg may be numerical expressions. Useful ranges are:
  1<= x <= 80
  1<= y <= 25
  0<= bg <= 31
  0<= fg <= 7
  For bg or fg out of specified ranges, modulo 32 and modulo 8 respectively
  are taken.
  The numeration of colors is different than in QuickBASIC, but all colors
  are there: 
         0...7       black, red, green, yellow, blue, magenta, cyan, white   
  Colors 0...7 are half-brigh. These are the only valid values for background;
  colors 8..15 are the same as 0...7 but of maximal brightness (i.e. "bold");
  colors 16..23 are the same as 0...7 but blinking;
  colors 24..31 are the same as 8..15 (bold) and blinking.
  
  If COLOR is called without arguments, the default colors are restored.
  In case something terrible happened, you may reset the terminal with
  SHELL "reset"  from within a program, or type 'reset' at the prompt.

o CLS 
  clears the screen (alternatively, SHELL "clear" does the same).
  Syntax :
  CLS [n]
  Valid arguments are 0, 2 or none. 0 or none clears the whole screen 
  and places cursor at home while 2 clears all but the last line.

o TIMER 
  Usage:  a = TIMER
  function counts only seconds: I do not know how to make it
  more precise under UNIX. Suggestions welcome.

BASIC COMMANDS
  
o TIME$
  Usage:  a$ = TIME$
  Returns time in the format hh:mm:ss

o PAUSE sec
  Program execution pauses 'sec' sec. This is precise to a microsecond 
  i.e. 1.000001 is a longer interval than 1. seconds.

o PRINT [string[,][;]] ...
  Print a string, string expression or number.1
  See also: EPRINT

o EPRINT .......
  The same as PRINT command except that is prints to the standard error
  device (stderr). Normally, output of tpe PRINT command can be redirected
  into a file like this:

  $ program > file

  However, the output of EPRINT will still appear on the screen. Thus, EPRINT
  is suitable for printing error messages. If you want to redirect both
  PRINT and EPRINT output use >& :

  $ program >& file

  See also: PRINT

o expression-1 MOD expression-2
  Calculates remainder of division of expression-1 by expression-2.
  Before doing so, both expresions are rounded to nearest integer.
  
  EXAMPLE:
  1 + 2 * 19 MOD 6.7 + .5
  is equivalent to:
  1 + (CINT(2 * 19) MOD CINT(6.7)) + .5
  The result is 4.5.
  
o EXISTS("filename")
  Function EXISTS returns TRUE if file or diretory "filename" exists, 
  FALSE if it doesn't exist. This function normally expands ~.
  String expression can also be passed as an argument.

  EXAMPLE:
   name$ = "myfile.dat"
   IF EXISTS("~/" + name$) THEN
    ...
   END IF
  The block ... will be excuted if a file or a directoy with name 
  "myfile.dat" exists.

GRAPHICS

  Set of graphics commands to work under X11 windows system is included. 
  They are similar in syntax to the original Quick Basic commands, except 
  for some intrinsic differences between DOS and X11 graphics display.
  For example, the 'SCREEN 10' command will open an 820x485 pixel 
  X-window to which subsequent graphics will be sent. Both text 
  and graphics screens live at the same time, so there is no need to
  switch between two modes ('SCREEN 0' is obsolete).

  There is a small demo program 'graphic.bas' included in this package.
  Try to compile it and understand how it works: 
  bcc graphic
  graphic
  

  Below is the short review of syntax.

o SCREEN 10
  Opens an X11 graphic window of the size width=820; height=485 pixels.

  SCREEN (x, y)[, width, height[, title$[, Xfont_name$]]]
  Initializes graphics and opens X11 graphic window with identifier ID = 0 
  at the position (x, y) pixels. The window ID number is used in commands
  like: XSELWI, XCLS etc.
  The optional width and height of the window are specified in pixels.
  If not specified, the default is: width=820, height=485.
  The default background colour is white and foreground black. These
  may be changed (individually for each window) via SET BG or XCLS.
  The default global font is:
  "-misc-fixed-medium-r-normal-*-20-140-*-100-c-100-iso8859-1"
  and it fits exactly 80 rows and 25 columns in the default window size.
  Initial title for the window can be set via title$ parameter. By default
  title will be written in the form: title@hostname. To avoid printing of
  the hostname, start the title with "-". Title of an already open window
  can be redefined via XTITLE command, which behaves the same way.

  SCREEN must be the first graphics command and must be executed exactly
  once. If more than one X-windows are needed they may be opened via 
  XWINDOW command.

  The background color of an already opened window can be changed via 
  XCLS command.


o [win% =] XWINDOW (x, y)[, width, height[, title$]]
  Open an X11 graphic window at the position (x, y) pixels. The window
  identification number is the next unused integer number and will be 
  written to variable win% if specified. The first window (ID = 0) must
  be opened with the SCREEN command. The window ID number is used in
  commands as: XSELWI, XCLS etc.
  The optional width and height of the window are specified in pixels.
  If not specified, the default is: width=820, height=485.
  The default background colour is white and foreground black. These
  may be changed (individually for each window) via SET BG or XCLS.

  The background color of an already opened window can be changed via 
  XCLS command.

  See also SCREEN command.


o PALETTE color_index%, r%, g%, b%
  Sets one color in the palette (2 <= color_index <= 255),
  where r%, g%, and b% are the color intensities (red, green, blue) between
  0 and 255 each.
  Color indexes 0 and 1 are used by the system for the window background
  and foreground colors respectively, when graphics is initialized (SCREEN)
  and should never be changed by user directly. You can alter the background
  of each opened window individually using XCLS and/or SET BG.
  (See LOADGIF for more details when GIF's are manipulated.)

o XTITLE title$[, win%]
  title$ = title
  win%  =  window identifier number
  Title of an already open window can be set via XTITLE command.
  By default title will be written in the form: title@hostname. To avoid
  printing of the hostname, start title with "-". 
  If win% omitted, set the title of the current window.
  If window win% is not existing, command has no effect.

o PSET (x, y)[, color%]
  Draws one point of a given colour index. If the color index is omitted,
  point is drawn in the current line color (see SET LCOL).

o PGET (x, y)[, color%]
  Gets the colour index of a point at the location (x, y).
  NOTE: NOT IMPLEMENTED

o LINE (x1, y1) - (x2, y2)[, color%[, B[F]]
  /* LINE -[STEP] (x, y)  is not yet supported ! */
  Draws a line, 
  where 'color' index is defined via PALETTE. The rest of the
  syntax is as in QuickBasic. The dashing style may be set with
  SET DMOD command (see below).

o PLINE n%, array_%[, color%]
  Connects first n% points given in the array 'array_%' with the straight line
  which attributes may be set with SET command (see below). See the notes
  about the array in PMARKER command. It works also for n% = 1 in which case
  a point is drawn.
  Color may both be specified by SET LCOL command or with the third argument,
  which is equivalent.

o MARKER (x, y)[, color%]
  Plots a marker at the point (x, y). Attributes of the marker may be set 
  with the SET command.

o PMARKER n%, array_%[, color%]
  Plots n% markers using points from the 2-dimensional array 'array_%' 
  which must be of type single short (therefore the '_%' suffix) and 
  must have the second dimension equal to 1, for example: DIM array_%(10,1). 
  Then the first three points are:
  (x1, y1) -> (array_%(0,0), array_%(0,1))
  (x2, y2) -> (array_%(1,0), array_%(1,1))
  (x3, y3) -> (array_%(2,0), array_%(2,1))
  etc.
  Attributes of the marker may be set with the SET command.
 
o CIRCLE (x, y), radius, [,[color][,[start][,[end][,aspect]]]]
  Draws a circle (or ellipse) with the center at the position (x, y)
  and 'radius'. It is possible to give 'start' and 'end' angles in
  radians: they are connected in positive sense. For ellipses, horizontal
  radius is given by 'radius' while 'aspect' is the ratio of vertical to
  horizontal radius. Color of the circle may be also set via SET FACI.
  For filled circles and ellipses use ixarc routine directly from C:
  C ixarc(x, y, rx, ry, angle1, angle2, ifill);
  with all parameters being integers:
   (x, y)  is the center;
   rx      is the horizontal radius;
   ry      is the vertical   radius;
   angle1  start angle in degrees;
   angle1  end   angle in degrees;
   ifill   0=hollow, 1=filled according to SET FASI (style) and 
           SET FACI (color) attributes 

o XTEXT (x%, y%), text$[, angle[, magn]]
  Draws the text 'text$' at the position (x%, y%) with an 'angle' (in 
  degrees) and magnification factor 'magn'. 
  By default angle=0.,  magn=1. .
  By default the text is aligned to left lower (descenders') corner.
  Text alignment may be changed with SET TXAL command.  Text colour 
  and font may be set with SET TXCI and SET TFON commands.
  NOTE: Use of a magnification factor different from default may 
  cause the letters to look very crude. It is better to use a font of
  appropriate size.

o FAREA n%, array_%[, color%]
  Fills polygonal area described by n% points the polygon. Fill area 
  attributes may be set with SET FASI (style) and SET FACI (color).
  Polygonal line describing the area may not be closed: in such a case
  it is assumed that the last point is connected with the first one.

o GCGET (x%, y%), answ%[, typ%[, mode%]] 
  Get pointer (mouse) position in the currently selected (see XSELWI) 
  X-window. The position is written to (x%, y%) after a mouse button 
  is pressed, released or mouse moved within the window. 

  The answ% contains button information:
  answ% = 1      left button pressed
          11     left button released
          2      middle button pressed
          12     middle button released
          3      right button pressed
          13     right button released.
  Input parameters are: 
  typ% (mouse type) = 0 previous type       mode% (request mode) = 0 Request
                      1 Tracking cross      (default = 1)          1 Sample. 
  (default type = 1)  2 Cross-hair
                      3 Rubber circle
                      4 Rubber band
                      5 Rubber rectangle.

  NOTE: User should normally use this mouse-reading function only if
  program uses only one X-window, because GCGET can read only one window
  at the time. If more than one X-window is opened, XPOINTER should be 
  used instead.


o XPOINTER (x%, y%), win%, answ%[, typ%[, mode%]]
  Get pointer (mouse) position. The function waits untill the mouse 
  is moved or a mouse button pressed or released. After one of these
  events has happened, the function returns the following:

  Output parameters:
  (x%, y%) = the position of of the pointer;
  win%     = window on which the pointer is logically positioned;
  answ%    = 1      left button pressed
             11     left button released
             2      middle button pressed
             12     middle button released
             3      right button pressed
             13     right button released.
  Input parameters are: 
  typ% (mouse type) = 1 Tracking cross      mode% (request mode) = 0 Request
  (default = 1)       2 Cross-hair          (default = 1)          1 Sample.
                      3 Rubber circle
                      4 Rubber band
                      5 Rubber rectangle.

  If a key is pressed, XPOINTER returns a window number of the active
  window (active window s recognized by its border color) and answ%
  equals to +char_code (key pressed) or -char_code (key depressed).


o XCURSOR ctype%
  Defines cursor shape for the current window. The cursor for that particular
  window remains unchanged everafter, except if GCGET is called for this
  window. On the other hand, XPOINTER doesn't change windows' pointer.
  Cursor types are listed in <X11/cursorfont.h> file for the particular
  system. Quite standard are the following types:
  XC_X_cursor (SCREEN and XWINDOW default), XC_crosshair, XC_arrow, 
  XC_left_ptr, XC_right_ptr, XC_hand1, XC_hand2, XC_watch,
  XC_based_arrow_down, XC_based_arrow_up, XC_boat, XC_bottom_left_corner,
  XC_bottom_right_corner, XC_bottom_side, XC_bottom_tee, XC_box_spiral,
  XC_center_ptr, XC_circle, XC_cross, XC_cross_reverse,
  XC_diamond_cross, XC_dot, XC_dotbox, XC_double_arrow etc...

o XREQST (x%, y%), text$
  Request input text at the position (x%, y%) in the current window. 

o SAVEGIF filename$
  Saves contents of the graphics window into a GIF87a file

o LOADGIF (x%, y%), filename$[, ipal%], bgcolor%]
  Loads a GIF from a file into the current graphics window, such that
  the upper left corner of a picture is placed at the pixel position x%, y%
  It works well for GIF87a and non-extended GIF89a file formats.
  If ipal% = 0 (default) then the picture is loaded using its own color
  palette, whether if ipal% = 1 the unique standard 6x6x6 palette is used.
  This language supports only 256 colors at the time.
  In the case ipal% = 0, palette ocupies colors from 16 up to max 255.
  In the case ipal% = 1, palette ocupies colors from 32 up to max 255.
  Therefore safe user-defined colors are from 2 - 15 (or 31) (see the SCREEN
  command).
   GIF's background can be specified by index 0 <= bgcolor% <= 255 in the
  palette which will be present after the GIF is loaded. Default is -1 
  which means GIF's own background. Specify bgcolor% = 0 to set GIF's
  backgroun to the current window background.


o GIFINFO filename$, width[, height[, ncolor]]
  Obtain width, height and number of colors used in the GIF file 'filename$'
  Variable types of width, height and ncolor may be any.


o GET (x%, y%), w%, h%, array?
  Copy a rectangular area of the current window into an one-dimensional
  array of color pixels.
  Point (x%, y%) specifies the top-left corner of the rectangle, and w%, h%
  are width and height of the rectangle in pixels. 
  User must make sure that the array has enough space to receive the image.
  Each pixel is represented with one byte of information. Number of bytes
  required to store image is w% * h%. The byte representing one pixel contains
  a value between 0 and 255 which is a code color of that pixel, corresponding
  to the current palette. Pixels are stored in the natural order i.e. pixel
  at the coordinate (x, y) of the rectangular is placed at the (x + w% * y)-th
  byte of the array.

  It is recommended to use byte-type array (suffix "?") if some kind of
  picture manipulation is intended by the user, since in this case 
  one element of the array corresponds to exactly one pixel of image.

  NOTE: See the PUT and GETCOL commands and the example program getput.bas.


o GETCOL icol%, r%, g%, b%
  Retreive information about the color icol% in the current palette.
  Returns red (r%), green (g%) and blue (b%) components of the color icol%.

  Related information:  PALETTE, GET, PUT


o PUT (x%, y%), array?, w%, h%[, (xs%, ys%)[, sw%, sh%]]
  Put contents of an color array onto the current window.
  Contents of the array is interpreted as a square image of the width
  w% and height h%. Pixels are retrieved in the natural order i.e. pixel
  at the coordinate (x%, y%) of the rectangular is placed at the 
  (x% + w% * y%)-th byte of the array. A subimage of this is copied on the 
  window. Subimage starts at the upper left corner (xs%, ys%) relative
  to the image stored in the array and has the width sw%, height sh%.
  The image is drawn on the window according to the current draw mode
  (SET DRMD).
  Parameters:
   (x%, y%) - point in the destination window where to put the image
   array?   - name of the byte-type array of pixels (one byte per pixel)
   w%, h%   - dimensions of the image stored in the array
   (xs%, ys%) - upper left corner of subimage to be copied, default = (0, 0)
   sw%, sh%   - window dimensions, default = w% - xs%, h% - ys%

  Related topics: PUT, GET, PALETTE, GETCOL, SET DRMD

  NOTE: See the GET and GETCOL command for the additional information.
  NOTE: In order to produce correct image, color palette must not be
        changed between GET and PUT commands, since array? only contains
        color codes of pixels.
  NOTE: Using multiple PUT commands it is possible to achieve animation.
        However, simpler and faster way is to use XANIM command.
 
o XANIM (x%, y%), array?, w%, h%[, (xs%, ys%)[, sw%, sh%]] 
  Animate series of images stored in arrays. Similar to PUT command.
  XANIM is similar to PUT command, but unlike the PUT command it remembers
  the last image drawn. With each call XANIM performs two actions: 1) draw
  the old picture (if one exists), and 2) draw a new picture (specified in
  the array). If the drawing mode is set to 2 (SET DRMD 2) this performs
  animation. Other drawing modes can be also useful to achieve visual effects.
  For parameters description, please refer to the command PUT. 

  Animation is achieved by a series of calls to XANIM with different arrays.
  You are allowed to change all of parameters in every call.

  At the end of animation, XANIM *must* be called once more with 0 or NULL 
  as the array name, in order to free the memory which is not used anymore
  and to reset the animation for a fresh new start. Values of the other 
  parameters then have no effect. For example: XANIM (0, 0), 0, 0, 0 .

  Before doing that, drawing mode may be changed to obtain a desired effect.
  Set DRMD to the following value:

   SET DRMD          effect
    0          leave the last image as it is (usually xor with the background)
    1          overwrite the area with the last image
    2          erase the last image, leaving background
    3          invert the last image and overwrite the area with it

  Related topics: PUT, GET, PALETTE, GETCOL, SET DRMD

  NOTE: see the example program animate.bas


o SET LCOL cindex%              (or SET PLCI cindex%)
  Sets line color to the 'cindex%' defined by PALETTE; 

o SET LWID n%
  sets line width in pixels;

o SET DMOD d1[, d2[, d3[, ... ]]...]
  Sets dashing style for lines. If there is only one argument, the dashing
  style is as follows:
  0  =  full line
  1  =  dashed line (6,6)
  2  =  dashed-dotted line (6,3,1,3)
  3  =  dotted line (1,6)
  4  =  dense dotted line (1,3) 

  (Note that a reasonable description always has an even number of arguments.)
  Other dashing styles may be obtained supplying more than one argument
  (max. 10 arguments). For example SET DMOD 6, 3, 1, 3 will produce a
  dashed-dotted line of 6 drawn pixels followed by 3 blank pixels, 1 drawn
  pixel and 3 blank pixels.


o SET DRMD mode%
  Set the drawing mode for drawing src to dest as follows.
  Set the drawing mode:     mode% = 0  Keep the previous mode
                            mode% = 1  Copy src       (i.e. overwrite dest)
                            mode% = 2  src XOR dest
                            mode% = 3  NOT src        (i.e. invert)
                            mode% = 4  src AND dest
                            mode% = 5  NOT (src XOR dest)
 
o SET PMTS type%, width%
  sets marker type and width in pixels. This settings will be used in 
  subsequent calls to MARKER and PMARKER;
  type%: 0 or 20 = filled circle
         1 or 21 = filled box
         2 or 22 = filled triangle pointing up
         3 or 23 = filled triangle pointing down
         4 or 24 = hollow circle
         5 or 25 = hollow box
         6 or 26 = hollow triangle pointing up
         7 or 27 = hollow triangle pointing down

o SET PMCI cindex%
  sets marker color index as defined by PALETTE; 

o SET TXCI cindex%
  sets XTEXT color index as defined by PALETTE;

o SET TFON font$
  sets font used by XTEXT. These X fonts can be seen with the command
  xfontsel. The default set by the SCREEN command is: 
  "-misc-fixed-medium-r-normal-*-20-140-*-100-c-100-iso8859-1". 
  A nicer font is, for example, Adobes' Helvetica:
  "-adobe-helvetica-medium-r-normal-*-14-0-100-100-p-*-iso8859-1".
  The number '14' there is the pixelsize and should be scaled if
  font of a different size is needed.

o SET TXAL h%, v%
  set XTEXT alignment
  h% = 0 left (default)             v% = 0 down (default)
       1 left                            1 down
       2 middle                          2 middle 
       3 right                           3 up

o SET FASI style%, hatch%
  Sets fill area style. Description:
  style% = 0   interior is not filled
  style% = 1   interior is filled with solid of a given (SET FACI) color
  style% = 3   interior is hatched with hatch% type.
  Valid numbers for hatch% are 0...25, there are that many different
  hatch types.
  
o SET FACI cindex%
  sets fill area colour index.

o SET BG cindex%
  set the background color for the current window, but do not clear the
  window.


o XSELWI win%
  Select and rise the window to which the subsequent graphics output will 
  be send. Window must exist or error will occur.


o XUPDATE
  Update an X11 window. Normally every drawing command will update 
  the X11 screen. However, if -u flag is specified during translation
  no update is made other than with XUPDATE command. This should
  improve speed if XUPDATE is used only when necessary. 


o XCLOSE [win%]
  Close the window win%. If the window win% doesn't exist, the command
  has no effect. If win% not specified, close the current window.
  If win% is the last existing window, XCLOSE also closes the graphics
  mode axlltogether. To open it again you must call the SCREEN function.
   

o XCLS [icol%]
  If icol% is not specified, clear the current X11 graphics window
  according to the current background of that window. If icol% specified,
  set the new background color to color icol% and then clear the window.
  The icol% is the color index as defined with PALETTE.
  NOTE: see SET BG.


o XCLIP (x1%, y1%)-(x2%, y2%), win%
  Set clipping rectangular region in the window win%. The clipping
  rectangle is defined with upper left (x1%, y1%) and lower right 
  (x2%, y2%) points.  Nothing could be drawn outside the clipping region
  of the window. To disable this, do XNOCLI win%. It is possible to set
  only one clipping rectangle per window with this command.

 
o XNOCLI win%
  Unset any clipping region for the window win%.


o XWARP (x%, y%)
  Move graphical cursor (pointer) to the position (x%, y%) in the current 
  window.


o XGETGE (x%, y%), w%, h%, win%
  Get geometry of a window win%. The window position is written to (x%, y%),
  window width and height are written to w% and h% respectively. If win%=-1
  get geometry of the root window.

  NOTE: This command works even if graphics has not been opened with the
  SCREEN command. In such a case it is only possible to get geometry of 
  the root window.

o 

ABOUT THE FORMAT OF INPUT FILES 

* A BASIC file input to qb2c must be in ASCII format (compressed QuickBASIC  
  format is not acceptable).

* In DOS, ASCII files have the carriage-return (Ctrl-M) character at the end 
  of each line. Input BASIC files to QB2C may be either in UNIX format 
  (i.e. without Ctrl-M's) or in DOS format. If a BASIC file to be translated 
  originates from DOS, Ctrl-M's are automatically striped off prior to 
  translation. However, all other files which are input to translated 
  programs must be in UNIX format, ie. without CR's at the end of each line.

TRANSLATOR OPTIONS

* Translation can be called with one or more of the following option flags:

   Option                        Meaning

  -i or -int        assume variables with first letter i,j,k,l,m,n 
                    (upper or lower case) to be of the C type 'int' 
                    if not a string;

  -D                assume variables starting with 'd' or 'D'
                    be of C type 'double', if not a string;

  -b or -bcpp       do not be sensitive about the case of QB command 
                    and function names or exact QB spacing of commands 
                    and variables. This actually turns on the bcpp 
                    preprocessor.
                    (However, mixed case is not acceptable even with this     
                    option.);

  -c64 or -C64      this option should be used with the option '-b' 
                    since it is passed to bcpp. It switches on some 
                    syntax features specific to C-64 (Commodore 64); 

  -l or -long       all integer variables except those declared 'short integer'                     became of type 'long' and all real variables became 
                    are declared as type 'long';

  -d or -double     all float variables are declared as type 'double'; 

  -p or -post       do not perform post-processing which changes variable                  
                    names like i%, i&, x#, a$, a? into C-acceptable forms:
                    i_int, i_long, x_double, a_S, a_byte and adds headers to
                    the C text. This is only useful for debugging output
                    C code or qb2c itself;

  -c or -C          this flag enables special handling of lines commented 
                    with "C", "CH " or "CM ". This makes possible direct 
                    insertion of lines written in C. For more information 
                    see the section "INSERTION OF LINES IN C" below;

  -m or -M          disallow logical expressions to combine with math. 
                    expressions (eg. i = (a = 1) AND (b <> 2) ). 

  -n or -N          disable SHELL "..." argument interpreter, i.e. the
                    argument of SHELL command in the BASIC program will be
                    send as it is to the system() command in the C translate.
                    By default argument of the SHELL command is translated
                    (for example: "dir" -> "ls -l" etc.)

  -u                do not XUPDATE the x-screen after every drawing 
                    command, such as LINE, PSET, BOX... 
                    This permits speedup of the drawing, if XUPDATE
                    is used only once in the while, when necessary

  -r                this option tells bcpp to replace every division
                    " / " with " / (double)". This is to comply with
                    BASIC's convention that division operator / always
                    convert both left and right side to real numbers
                    before dividing them, so that the result is also real.
                    For example 5 / 8 equals 0.625 rahter than 0 
                    This option is *NOT* a default.

  -s                by default, QB2C changes the names of numerical 
                    variables, arrays and functions by replacing    
                    suffixes '%', '&', '#' and '?' with respectively '_int',
                    '_long', '_double' and '_byte'.
                    Specifying flag -s tells QB2C to strip off suffixes 
                    '%', '&', '#' and '?' instead. 
                    WARNING ! It is up to user to ensure that there are
                    no variables with similar names in the program, which
                    will become the same after stripping suffixes, for
                    example 'a% and 'a'. In such a case, the translated code
                    will be invalid.

REMINDER

 Following pieces of syntax rules are a bit more restrictive than is 
common in various implementations of BASIC including QuickBASIC.
We want to stress their importance since QB2C may produce a bad C code 
without warnings if they are not obeyed:

* all used arrays must be explicitely declared (with DIM);

* array, constant or function declarations must occur first in a
  given module (MAIN, SUB...) ie. before any other expression or 
  command. THIS MAKES IT IMPOSSIBLE TO CHANGE ARRAY SIZE AT RUN-TIME,
  if you want to do so, you must do it directly from C;

* arguments to arrays *must* be integers. I could do differently, but
  it would both slow down both the translation and execution, besides,
  it is a good programming style to think of array arguments as integers;

* all SHARED arrays must be declared in MAIN module (even if they are not
  used in the MAIN);

* SHARED array names are passed with empty brackets eg. name();

* Files open in any module (MAIN, SUB or function) are "visible" from 
  all other modules;

* Return type of a FUNCTION is determined by its name, the rules are the
  same as for variables and arrays.

RESTRICTIONS

* Type of a constant, variable or array is determined by suffix in
  its name. The "AS" statement in variable type definition is *not* 
  supported.
  Here is the list of legal suffixes (as used by QuickBASIC) and
  their correspondence in C:

              QuickBASIC                         C
  $         -> string (or single character)     char *
  %         -> single integer                   int
  &         -> long integer                     long
  #         -> double float                     double
  ?         -> single byte integer              unsigned char
  _%        -> 2 byte integer                   signed short int
  no suffix -> single float                     float

  Note two additional types which did not exist in original QuickBASIC:
  single byte integer, and two byte integer, both introduced to minimize
  memory usage in graphics applications.

  If a numerical constant contains "." or ends up with an "!" then it is a
  single float (example: 100 is integer, 100. and 100! are single floats).
  On top of that, user can modify types during translation (options -l, -d).
    
* All array names MUST be declared explicitly (DIM) at the top of each
  module where they are used.
  In opposite case NO ERROR WILL BE DETECTED at translation time !

* The syntax must be strictly the one as written out by the QBASIC editor
  including case and spacing conventions. If not, preprocessor bcpp 
  should be used on the file:
  bcpp  infile  outfile
  or the option -b used to the qb2c translator (see the option list).
  The bcc compiling script already uses -b option.

  The bcpp preprocessor may be run with one or more of the following 
  option flags:

  -c64 or -C64      this option switches on recognition of some 
                    syntax features specific to C-64 (Commodore 64)

  -q                bcpp works quietly (suppresses warnings but not
                    errors).

* Arrays cannot be passed as variables to SUBroutines or functions - use 
  SHARED instead.

* IF clauses without THEN such as:  'IF a$ = "a" GOTO 100'
  are not allowed at this moment. In this particular case one should
  use instead: 'IF a$ = "a" THEN GOTO 100' or 'IF a$ = "a" THEN 100'.

* There is no support for sound except directly from C


EXAPMLE

I) As a simple example you may put the following text into a file named 
test.bas:

 for i=1 to 5 
  print i, i^2
 next

 Then do:
 bcpp -i -b test

 This will create the file test.c. Compile and run it with:
 cc -o test test.c -lm
 test

 The result should look like: 
 1          1
 2          4
 3          9
 4          16
 5          25

 Instead of all this you may just have typed: 

 brun test


INSERTION OF LINES IN C

  It is possible to mix BASIC and C. Lines written in C must be commented
  with "C " *at the beginning of a line* and -C option issued to qb2c 
  translator. For example:

  pi = 3.1415
C printf("%f\n",pi);
  END

  is equivalent to:

 pi = 3.1415
 PRINT pi
 END 

  The first example must be translated with the -C option:
  qb2c -C name

  During translation names of variables, open file pointers and labels are 
  changed in order to conform C conventions. This is done in the following 
  way:

  Variables: "$" at the end of variable name becomes "_S", "%" becomes "_int",
             "&" becomes "_long", "#" becomes "_double", and "?" becomes
             "_byte".

  Open files: An open file identified in BASIC with number 'n', becomes 
              identified with a pointer of name 'fp_n'.

  Labels:     Label numbers are added "Lab_" prefix, for example 
              "100" is renamed to "Lab_100".

  To make things more convenient it is possible to specify lines which
  are insert among the declaration lines of main routine with "CM " comment
  or in the overall header of the translated C program with "CH ". Variables
  and constants declared with "CH " are, of course, global.

  An example (the program asks for a word and then it prints out character
  codes and their squares):

   print "This is a small test of";
C  printf("mixing BASIC and C\n");
   REM We need to declare a variable in main:
CM static char c;
   input "Say a word"; a$
   for i%=1 to len(a$)      
C  c=a_S[i_int-1]; 
C  printf("%5d %.f\n",c, pow(c,2)); 
   next
C  /* I have used a math library function (pow) only in C, therefore 
C     a header <math.h> will not be specified. I must do it myself */
CH #include <math.h>
   end

 This program should be run in the following way:
 bcpp -b -C name
 run name
-----------------------------------------------------------------------------

ACKNOWLEDGEMENTS

 I wish to thank to the people from CERN, Geneve, for developing the 
interface to X11 library: O. Couet, I. Mclaren and E. Chernyaev, and for 
their help in understanding this package. A part of their so called HIGZ 
package only needed small changes to be runable from C, and included in QB2C.

-----------------------------------------------------------------------------
QB2C manual
First version:  4-Apr-1996
Last revision: 28.Apr-1998
Author: Stipcevic Mario  mario@darkstar.irb.hr
