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.