Skip to main content
© Deekay

 GEM VDI CALLS PART II by Manus

In  this article,  I'll give you some more GEM-routines which  you 
can use in ST BASIC. The subjects in this article are:
 - getting the mouse-position
 - definition of a new mouse
 - mark-statements
 - some graphic statements

MOUSE-POSITION AND KEYS:

To  get  the  mouse-position is  certainly  the  most  interesting 
routine  in  GEM,  because  with this routine you  can  make  your 
programs  professional;  no more input of a  character,  but  just 
click the wanted option.
The  routine gives you the wanted values in the variables  XMOUSE, 
YMOUSE  and  KEY,  but remember we have to correct the  values  in 
XMOUSE and YMOUSE (see PART 1, RECTANGLE).
The variable KEY can have three different values:

   Pressed key       Value
 -------------       -----
     Left              1
     Right             2
 Left and right        3

The syntax is:

     gosub MOUSE  

The routine is:

63000 MOUSE:
63002 ' <----- XMOUSE ; YMOUSE ; KEY
63004 poke contrl, 124
63006 vdisys
63008 xmouse = peek(ptsout    ) - 1
63010 ymouse = peek(ptsout + 2) - 38
63012 key = peek(intout)
63014 return

Try this:

5   ' merge "MOUSE.bas"
10  fullw 2: clearw 2
20  color 1,1,1,1,1
30  start:   gosub MOUSE
40  if key = 1 then pcircle xmouse, ymouse, 5, 0, 3600:
50  if key = 2 then gotoxy 0,0 : print xmouse, ymouse
60  if key = 3 then clearw 2
70  goto start

SHOW-MOUSE:

Sometimes,  it  is very annoying that you can not see  the  mouse-
symbol at all times,  because he gets invisible with every  output 
on the screen or every input on your keyboard.  Only when you move 
the mouse, you can see him again.
With  the next GEM-routine you can make the mouse visible  at  any 
time you want.The syntax is:

     gosub SHOWMOUSE 

The routine is:

63030 SHOWMOUSE:
63032 poke contrl, 122
63034 poke intin, 0
63036 vdisys
63038 return

MOUSE-SHAPE:

The Atari has 8 different mouse-shapes,  which we can also use  in 
Basic. The mouse-shapes are:
   Shape:           Value:
---------------     ------
Arrow                 0
Stretched rounded X   1
Bee                   2
Pointing hand         3
Open hand             4
Cross                 5
Fat cross             6
Outlined cross        7
To do this,  we have to use a little AES-programming.  The  syntax 
is:
     MOUSENUMBER = 0...7 :
     gosub MOUSESHAPE
  

                     The routine is:
63280 MOUSESHAPE:
63282 ' -----> MOUSENUMBER
63284 '         0 - 7
63286 if mousenumber > 7 then return
63288 add# = gb
63290 gintin = peek(add# + 8 )
63292 addrin = peek(add# + 16)
63294 poke gintin, mousenumber
63296 poke addrin, 0
63298 gemsys (78)
63300 return

DEFINITION OF A MOUSE-SYMBOL:

It is possible to create your own mouse-symbol,  like in  drawing-
programs,   with   the   VDI-routine  111.   The  grid   and   the 
backgroundgrid are each 16 words of 16 bits. We have to POKE these 
values  on  certain addresses.  The backgroundgrid  defines  which 
screenpoint of the field (16 by 16) under the mouse-symbol has  to 
stay visible and which point has to been wiped.  That is specially 
important when the mouse-symbol goes over a dark field.  Therefore 
it is advisable to make the backgroundgrid greater then the mouse-
grid.
We have to use the next addresses:
 INTIN + 8    color of the mouse: black or white
 INTIN + 6    color of the backgroundgrid
 INTIN + 2  ) point of the mouse, valid for determination
 INTIN + 4  )  of the mouse-position
In the following program we have put the information of  different 
mouse-symbols in DATA-lines. To read these DATA we have to put the 
DATA-pointer to these data.
The syntax is:

               Restore dataline 
               gosub MOUSEDATA
 

The routine is on the next page.

63140 '--------------- MOUSEDATA --------------------------
63141 HAMMER:
63142 data 96,480,960,1984,3968,8064
63143 data 7936,16256,15872,32512,32512,65408
63144 data 65408,65472,63424,65504,25568,65520
63145 data 496,62456,248,508,124,254
63146 data 62,127,31,63,14,31
63147 data 4,14
63150 COFFEE:
63151 data 4624,16184,9248,32376,4640,16368
63152 data 4672,16352,4384,16352,2624,8128
63153 data 0,16320,16352,32764,16380,32766
63154 data 16358,32767,16354,32767,16358,32767
63155 data 16380,32767,16352,32766,8128,16352
63156 data 0,8128
63160 WORM:
63161 data 0,8064,8064,16320,16320,32736
63162 data 26208,65520,30560,65520,32736,65532
63163 data 29132,65534,16318,32767,8054,16383
63164 data 7782,16383,7372,16382,7384,16380
63165 data 4080,8184,2022,4095,60,2046
63166 data 24,62
63199 '-------------------------------------------------
63200 MOUSEDATA:
63202 '---> restore line
63204 for a = 0 to 15
63206 read gridfront,gridback
63208 poke intin + a * 2 + 42, gridfront
63210 poke intin + a * 2 + 10, gridback
63212 next
63214 '-------------------------------------------------
63250 MOUSENEW:
63252 poke contrl    , 111
63254 poke contrl + 6, 37
63256 poke intin    , 5
63258 poke intin + 2, 5
63260 poke intin + 4, 1
63262 poke intin + 6, 0
63264 poke intin + 8, 1
63266 vdisys
63268 out 2,7
63270 return

Example:

5   ' merge "MOUSEDATA.bas"
6   ' merge "SHOWMOUSE.bas"
9   '
10  restore worm: gosub mousedata: gosub showmouse
20  waiting = inp(2)
30  restore hammer: gosub mousedata: gosub showmouse
40  waiting = inp(2)
50  restore coffee: gosub mousedata: gosub showmouse
60  waiting = inp(2)
70  end

MOUSE-EDITOR:

This  next  program  can  be  used  to  create  mouse-symbols;  it 
calculates  the  necessary  bit-values  and  pokes  them  in   the 
addresses. After the input of:
                gosub MOUSEEDITOR 
the new calculated mouse-symbol appears on the screen.
You  have to write down the decimal values of the  mouse-grid  and 
its  backgroundgrid  and put them in DATA-lines (see  line  63106, 
remove the REM-statement) like in MOUSEDATA. Using DATA-statements 
is much faster then using this program for your new mouse-symbol.
When your new mouse-symbol disappears you can recall it through:
               gosub MOUSENEW 
The routine is:

63050 MOUSEEDITOR:
63052 dim a$(16),b$(16)
63054 a$( 0)="---*--*----*----":b$( 0)="--******--***---"
63056 a$( 1)="--*--*----*-----":b$( 1)="-******--****---"
63058 a$( 2)="---*--*---*-----":b$( 2)="--**********----"
63060 a$( 3)="---*--*--*------":b$( 3)="--*********-----"
63062 a$( 4)="---*---*--*-----":b$( 4)="--*********-----"
63064 a$( 5)="----*-*--*------":b$( 5)="---*******------"
63066 a$( 6)="----------------":b$( 6)="--********------"
63068 a$( 7)="--*********-----":b$( 7)="-*************--"
63070 a$( 8)="--************--":b$( 8)="-**************-"
63072 a$( 9)="--*********--**-":b$( 9)="-***************"
63074 a$(10)="--*********---*-":b$(10)="-***************"
63076 a$(11)="--*********--**-":b$(11)="-***************"
63078 a$(12)="--************--":b$(12)="-***************"
63080 a$(13)="--*********-----":b$(13)="-**************-"
63082 a$(14)="---*******------":b$(14)="--*********-----"
63084 a$(15)="----------------":b$(15)="---*******------"
63086 for a = 0 to 15
63088 gridfront = 0: gridback = 0
63090 for b = 15 to 0 step -1
63092 if mid$(a$(a),b+1,1)="*" then bit = 1 else bit = 0
63094 gridfront = gridfront + 2 ^(15 - b) * bit
63096 if mid$(b$(a),b+1,1)="*" then bit = 1 else bit = 0
63098 gridback = gridback + 2^(15 - b) * bit
63100 next
63102 poke intin + a * 2 + 42, gridfront
63104 poke intin + a * 2 + 10, gridback
63106 ' lprint gridfront, gridback
63108 next
63110 goto mousenew
63112 '---------------------------------------------------

POLYMARK:

We can use different drawings as mark, these drawings are:
 - point                      - cross
 - star                       - rectangle
 - slanting cross             - diamond
All marks can be made in every size. The syntax is:
     XPOS = .... : YPOS = ....
     MARKFORM = ....
     MARKSIZE = ....
     gosub POLYMARK
 
To draw an other one:  
     XPOS = .... : YPOS = ....
     gosub POLYMARK
 
It is possible to draw several marks at the same time.  We have to 
use some addresses:
    PTSIN + 4, PTSIN + 6, ....    Positionparameters
    CONTRL + 2                    Number of marks

Theoretically we can  wipe a mark by drawing  it  again  with  the 
backgroundcolor.  But then we lose the background-information  and 
it is impossible to draw on dark backgrounds.
Therefore  we  use  the routine 'TEXTFORM'  with  its  option  XOR 
(form=3). By using XOR twice we get the original screeninformation 
again and the background stays unchanged.
The routine is:

63400 POLYMARK:
63402 ' ----> XPOS ; YPOS
63404 ' ----> MARKFORM ; MARKSIZE
63406 '
63408 poke contrl    , 18
63410 poke contrl + 2, 0
63412 poke contrl + 6, 1
63414 poke intin, markform
63416 vdisys
63418 poke contrl    , 19
63420 poke contrl + 2, 1
63422 poke contrl + 6, 0
63424 poke ptsin    , 0
63426 poke ptsin + 2, marksize
63428 vdisys
63430 '
63432 MARKSETTING:
63434 ' (----> XPOS ; YPOS )
63436 poke contrl    , 7
63438 poke contrl + 2, 1 : ' or more
63440 poke ptsin    , xpos + 1
63442 poke ptsin + 2, ypos + 38
63444 vdisys
63446 return
63448 '---------------------------------------------------

The routine 'TEXTFORM':

65130 TEXTFORM:
65132 ' -----> FORM ( 1 - 4)
65134 '
65138 poke contrl    ,32
65140 poke contrl + 2,0
65142 poke contrl + 6,1
65144 poke intin, form
65146 vdisys
65148 return

A test:

5   ' merge "POLYMARK.bas"
6   ' merge "TEXTFORM.bas"
9   '
10  fullw 2: clearw 2
20  color 1,1,1,1,1
30  form = 3: gosub TEXTFORM
40  pellipse 310, 200, 140, 80, 0, 3600
50  start:
60  xpos = 50: ypos = 160 : marksize = 50
70  for markform = 1 to 7
80  xpos = xpos + 60
90  gosub POLYMARK
100 next
110 gotoxy 15,11: print "ST NEWS IS THE BEST"
120 waiting = inp(2)
125 end
130 goto start

POLYLINE:

This  routine  is the same as the statement 'LINEF' in  ST  Basic, 
but much faster.
The syntax is:

     XCOORD ( 1,.....,N ) 
     YCOORD ( 1,.....,N ) 
     gosub POLYLINE
 

The routine is:

64300 POLYLINE:
64301 ' -----> NUMBER ; XCOORD ; YCOORD
64302 poke contrl    , 6
64304 poke contrl + 6, 0
64306 poke contrl + 2, number
64308 for i = 0 to number
64310 poke ptsin + i * 4, xcoord(i) + 1
64312 poke ptsin + 2 + i * 4, ycoord(i) + 38
64314 next
64316 vdisys
64318 return
64320 '---------------------------------------------------

Try this and compare the speed:

5   ' merge "POLYLINE.bas"
9   '
10  dim xcoord(200), ycoord(200)
20  fullw 2: clearw 2
30  number = 80
40  for i = 0 to number
50  xcoord(i) = 10 + i * 600/number
60  ycoord(i) = 100 + rnd(1) * 200
70  next
80  gosub polyline
90  waiting = inp(2)
100 end

POLYGON:

With this routine we can draw and fill all imaginable figures. The 
routine works much faster then the 'LINEF' - and 'FILL'-statement.
The grid is defined through the 'COLOR'-statement.
The syntax is:

    XCOORD ( 1,.....,N ) 
    YCOORD ( 1,.....,N ) 
    gosub POLYGON
 

The routine is:

64140 POLYGON:
64142 ' -----> ANGLES ; XCOORD ; YCOORD
64144 poke contrl    , 9
64146 poke contrl + 6, 0
64148 poke contrl + 2, angles
64150 for i = 1 to angles
64152 poke ptsin + (i - 1) * 4, xcoord(i) + 1
64154 poke ptsin + 2 + (i - 1) * 4, ycoord(i) + 38
64156 next
64158 vdisys
64160 return
64162 '---------------------------------------------------

Example:

5   ' merge "POLYGON.bas"
9   '
10  dim xcoord(20), ycoord(20)
20  color 1,1,1,7,2
30  fullw 2: clearw 2
40  angles = 6
50  for i = 1 to angles
60  read xcoord(i), ycoord(i)
70  next
80  gosub polygon
90  waiting = inp(2)
100 end
110 data  10,100,400, 40,250,200
120 data 380,290,150,230, 70,240

POLYGON2:

This routine is a special Polygon-routine for drawing  symmetrical 
polygons with self-defined number of angles.
The syntax is:

    XPOS = ....   : YPOS = ....
    RADIUS = .... : ANGLES = ....
    gosub POLYGON2
 

The 'COLOR'-statement defines the grid. The routine is:

64100 POLYGON2:
64102 ' -----> XPOS ; YPOS
64104 '        RADIUS ; ANGLES
64106 phi = 3.141593/angles/2
64108 STAR:
64110 ' -----> PHI
64112 poke contrl    , 9
64114 poke contrl + 6, 0
64116 poke contrl + 2, angles
64118 for angle = 0 to angles * 4 step 4
64120 poke ptsin+angle    ,  1+xpos+cos(phi*angle)*radius
64122 poke ptsin+(angle+2), 38+ypos+sin(phi*angle)*radius
64124 next
64126 vdisys
64128 return
64130 '--------------------------------------------------

Example:

5   ' merge "POLYGON2.bas"
9   '
10  fullw 2: clearw 2
20  color 1,1,1,7,2
30  xpos = -50 : ypos = 150
35  radius = 50
40  for angles = 3 to 7
50  xpos = xpos + 120
55  gosub polygon2
60  next
70  waiting = inp(2)
80  end

STARS:

Using the routine 'POLYGON2' and with  a little adjustment of  the 
angle  and  like  magic  beautiful  stars  appear  on  the  screen 
(something for Christmas ?)

5   ' merge "POLYGON2.bas"
9   '
10  fullw 2: clearw 2
20  color 1,1,1,8,2
30  ypos = 150 : radius = 50
40  angles = 7
50  xpos = 100 : phi = 3.1416/2/angles * 2   : gosub star
60  xpos = 200 : phi = 3.1416/2/angles * 3   : gosub star
70  xpos = 300 : phi = 3.1416/2/angles * 2.8 : gosub star
80  xpos = 400 : phi = 3.1416/2/angles * 1.7 : gosub star
90  xpos = 500 : phi = 3.1416/2/angles * 2.5 : gosub star
100 angles = 11: ypos = 250
110 xpos = 100 : phi = 3.1416/angles * 1.5   : gosub star
120 xpos = 200 : phi = 3.1416/angles * 2     : gosub star
130 xpos = 300 : phi = 3.1416/angles * 2.5   : gosub star
140 xpos = 400 : phi = 3.1416/angles * 1.9   : gosub star
150 xpos = 500 : phi = 3.1416/angles * 2.6   : gosub star
160 waiting = inp(2)
170 end

Disclaimer
The text of the articles is identical to the originals like they appeared in old ST NEWS issues. Please take into consideration that the author(s) was (were) a lot younger and less responsible back then. So bad jokes, bad English, youthful arrogance, insults, bravura, over-crediting and tastelessness should be taken with at least a grain of salt. Any contact and/or payment information, as well as deadlines/release dates of any kind should be regarded as outdated. Due to the fact that these pages are not actually contained in an Atari executable here, references to scroll texts, featured demo screens and hidden articles may also be irrelevant.