
                        GEM PROGRAMMING by Jonathan White

                                   ARTICLE 6

                                  VDI part II.

     Hello again, and welcome to our  further  exploration of the VDI. Last
     time we mainly covered the  'graphics primitives' which, despite their
     name, are actually the higher level functions of the VDI. This week we
     shall look at the simple line and point (or marker) drawing functions,
     along with mouse and keyboard polling.

     While we are going to cover  these  two points, unless you are writing
     some sort  of  arcade  game  which  requires  exact  mouse  / keyboard
     control, I don't advise you to  use  these functions for GEM programs.
     Why? It's simple. Any routine you call  takes up processor time. It is
     much more 'processor efficient' to let  the  system TELL you the mouse
     has moved or a key  has  been  pressed,  rather than have your program
     continually make the system CHECK for  these events. But since you CAN
     write programs that use the VDI without using the AES  and its message
     based systems, these functions need to included.


     BASIC DRAWING FUNCTIONS

     The most basic drawing  function  is  to  colour  one  pixel in on the
     screen a specific colour.  To  do  this,  a  set  of  steps  has to be
     followed.

     A) Prepare the screen display and palette (as last week).

     B) Set the attributes you require. The VDI has no function for drawing
     a specific pixel;  there  is  no  'plot  (x,y)'  routine.  What it has
     instead are a group of routines  to display small 'markers' or shapes.
     The shapes are..

             a single pixel
             a cross (+)
             a star  (*)
             a square
             an 'X'
             a diamond

     Obviously, to plot a single pixel, you choose to plot a marker which
     is only one pixel in size.

        The marker attributes are set by the following functions :-

        vsm_color()  sets the colour (palette entry) the marker uses.
        vsm_height() sets the size of the marker. The pixel marker is not
                     affected by this.
        vsm_type()   sets the marker type to use.


     C) Once these setting have been made, you can set your point with :-

        v_pmarker()

     You  can  also  find  the  currently  set  attributes  with  the  call
     vqm_attributes()

     Lines are  slightly  more  complex.  They  take  on  the  current line
     attributes of colour,  style,  width  and  end  styles  (see  the last
     article  for  details  on  setting  these  using  the  vsl_  group  of
     functions). But, just as it is impossible  to just plot a point, it is
     impossible to plot just  a  line.  The  relevant  VDI function plots a
     series of lines, and to plot a single  line, you have to plot a series
     of one line. While this  makes  the  function  more versatile, it also
     makes it slightly more complicated to use.

     The function in  question  is  v_pline(),  short  for  polyline. It is
     listed as the following prototype :-

     VOID v_pline(WORD handle, WORD counts, WORD *points)

     Handle is the VDI handle, counts  is  the  number of x,y points in the
     array points which define the vertices  to  draw. Note that the end of
     the first line is considered to be  the start of the second, therefore
     to draw a square requires points as follows..


     points[0],points[1]-----------------------------points[2],points[3]
     points[8],points[9]                                             |
                 |                                                   |
                 |                                                   |
                 |                                                   |
                 |                                                   |
                 |                                                   |
                 |                                                   |
                 ~                                                   ~
                 |                                                   |
       points[6],points[7]---------------------------points[4],points[5]


     Thus to draw any shape,  regular  or  irregular,  requires an array of
     (sides+1)*2 points, as  in a closed  shape  the last point must always
     be the same as the first. You CAN draw a point with this function too,
     using the start and end points  as  the same, but given variations due
     to  line  style  and  end  style,   the  exact  results  are  somewhat
     unpredictable.

     VDI Inquire  Functions

     There is a  set  of  functions  which  allow  a  program  to  find out
     information as to the current state of the VDI. They are characterised
     as starting 'vq...'. Most of these  give quite useful information. The
     most commonly used ones are :-

     vq_chcells()     returns the size of the screen in text characters
     vq_color()       returns the RGB information  for  a particular palette
                      entry
     vq_curaddres()   returns the current location of the text cursor
     vq_extnd()       gives much extra information about the current device
     vq_gdos()        tells if GDOS is installed,  and  what sort of GDOS it
                      is
     vq__key_s()      returns the state of the shift keys (and ctrl and alt)
     vq_mouse()       returns the state and position of the mouse
     vqf_attributes() returns the current fill attributes
     vql_attributes() returns the current line attributes
     vqm_attributes() returns the current polymarker attributes
     vqt_attributes() returns the current text attributes
     vqt_extent()     returns the pixel area taken up by a string of text
     v_get_pixel()    returns the colour value for a particular pixel

     There are other inquire  functions,  mostly  to  do  with GDOS output,
     which we will detail when we  deal  with GDOS. Most of these functions
     work in a similar fashion. You  pass  a  pointer to an array, which is
     filled with the appropriate  information.  See  this month's reference
     for details on any of these.

     VDI input functions

     The ST (TT / Falcon) has  two  major  input devices, the mouse and the
     keyboard. Both of these can be read  either  by the VDI or by the AES.
     The difference is that the AES uses  a message system, whereas for the
     VDI you must inquire or 'poll'  the  device for information. Both have
     their advantages and disadvantages. The AES method uses less processor
     time, but the VDI method allows  you  to find the information when you
     want it, rather than when the message gets to the front of the queue.

     A) The mouse

     The VDI - Obviously, you use vq_mouse, along with vq_keys_S. vq_mouse
     returns three words, two containing the  current  x and y positions of
     the mouse, and a  word in which  the  first two bits reflect the state
     of the  buttons.

     The AES - Uses the evnt_mouse()  call.  This  basically sits and waits
     until a mouse event (which is the mouse moving into a specific area of
     the screen) and  then  returns  the  same  information  as  the above.
     However, if the mouse  doesn't  enter  the  area,  the system will not
     respond to other messages, and  you  are  stuck.  A similar call named
     evnt_button() waits for  a  mouse  click.  Monitoring  both (and other
     messages) at once requires the  use    of    the    monolithic    call
     evnt_multi(), which we will discuss in  a later article. This function
     takes (at the last count) 22 parameters, and basically watches for all
     goings on under the AES.

     B) The keyboard

     The VDI - There are two  ways  to  get  keyboard  input under the VDI,
     depending upon the exact nature of input. The input can be sampled (in
     which case the system does not  wait  for  return to be pressed before
     passing the keys pressed back) and request (when it does). Since there
     are few (if any) replacement keyboards  for  the Atari line, or things
     which emulate  them,  you  are  probably  safe  using  the  standard C
     keyboard input functions, However, you  should be careful to correctly
     position the text cursor first. The  mode of input (sample or request)
     must be set beforehand. The two functions are :-

             vrq_string()    request mode
             vsm_string()    sample mode

     The AES - much  simpler.  When  reading  from  the  keyboard  you  use
     evnt_keybd() function which waits for a keypress, or alternatively use
     the evnt_multi call.

     Both of these sets of functions  return  a WORD. The bottom byte being
     the ASCII code  of  the  key  pressed,  and  the  upper  one being the
     scancode, to facilitate the reading of  keys which have no ASCII code,
     such as the cursor, help and function keys.

     OTHER STUFF

     I will end by mentioning a  few  other useful VDI functions we haven't
     talked  about  yet.  These  basically  didn't  fit  into  any  of  the
     categories we have looked at,  but  since  they  are there we might as
     well point them out..

     v_fillarea()    outputs a filled irregular polygon. You pass it a set
                     of vertices to draw and it fills it with the current
                     style. It automatically joins the last point to the
                     first to ensure there is no 'spill' of the fill.

     v_contourfill() basically this is the VDI 'flood fill' command. You
                     pass it an x,y  'seed  point'  and  a  colour, and the
                     routine fills outward from the  seed  point,  stopping
                     the fill at an edge of the colour you pass it.

     And that about does it  for  this  one.  Next  time, we'll look at the
     functions to draw and control bitmaps  with  the VDI,  which have more
     applications than sprites in games...
