GFA BASIC TIPS & TRICKS by Richard Karsmakers
Things are really going swell lately with regard to this service.
The Tips & Tricks column has been published in some major Dutch
magazines by now and people do not only send in questions, but
answers as well.
Well, let's start with the questions and the answers:
1) How do I change the screen resolution?
Answer: If you are in monochrome mode, it is impossible to change
the screen resolution. However, when you're in color mode, you
can swap between medium and low resolution. But you'll note that
(if you swap from low to medium) the mouse will not cover the
whole screen. I have not yet quite solved this problem myself,
but some acquaintances of mine a working on it at the moment.
From low to medium resolution:
Void Xbios(5,L:-1,L:-1,W:1)
From medium to low resolution:
Void Xbios(5,L:-1,L:-1,W:0)
2) Some people have problems converting the ST Basic command
LPRINT USING to GfA Basic. GfA turn out not to understand this
syntax, and will handle the command as a variable name instead.
How should it be done?
Answer: Since I do not have a printer myself, I have not been
able to test the solution I am about to give, but theoretically
it should work perfectly.
There where you want to start using the printer to print on, you
should use one of the following lines:
Open "O",#1,"LST:" !For Centronics printers
Open "O",#1,"AUX:" !For serial (RS232) printers
After that, you should replace all commands LPRINT USING by:
Print #1,Using..........
Of course, you can replace the '#1' by another channel number, as
long as you take care that you print to the same channel as the
one you've opened. After all printing is done, you need to close
the channel. This needs to be done by use of the following line:
Close #1
3) How do I make a menu-entry 'light', so that it cannot be
selected anymore?
Answer: When you initialise a menu, you need an array to do that.
That array consists of all menu bar titles, etc. and should end
with two empty strings. All pull-down menus should be seperated
by an empty string as well.
Each 'drawer' in that array has its own index number. We will
call this index number 'X'. The line to make a menu entry light
is then:
Menu X,2
It can be put back to normal again with:
Menu X,3
The MENU command can also be used to put a checkmark Chr$(8) in
front of it, to indicate that a title has been selected. Thsi can
be put there with:
Menu X,1
And it can be removed by use of:
Menu X,0
4) My cursor is not visible when I write a custom input routine
using INPUT$. How can I make it visible?
Answer: It can be made visible by use of the following line:
Print Chr$(27);"e" !The 'e' must be small!
And it can be turned off again by use of:
Print Chr$(27);"f" !The 'f' must be small!
5) How do I write a communication program using GfA Basic?
R. Bitter, Goes, Netherlands
6) How do I change the shape of the cursor?
G.A.J. van Oene, Udenhout,
Netherlands
7) How does one use non-rectangular blocks in GfA Basic?
Answer (story-like, by Stefan Posthuma):
It's Sunday night, I'm sitting in my room behind my ST. My skin
burns because I've been spending the entire day laying in the sun
at 'Het Blauwe Meer' (The Blue Lake) in Den Bosch. There is a
cold beer at my side, the Beasty Boys are bustin' my speakers
(and my parents and my neighbours and in fact the rest of the
neighbourhood because my window is wide open). My thumb aches
from tapping the firebutton on my joystick like a maniac while
amessing a huge score on Plutos. (Yes folks, I got my hands on a
Color Monitor! I will not be long until some Color Stuff is
released from the offices of Digital Insanity.) And also...Stefke
got professional! Yes, I now officially work as a programmer for
a Software house, on an IBM-AT under XENIX, quite a lovely
operating system. I program in C and Informix 4GL-SQL, some
fantastic fourth-generation language. But don't worry, the AT is
my job, but the ST still is and will be my greatest hobby! It all
makes me feel great, and wat else can I do than write an article
for ST-NEWS? But enough of this smalltalk, let's get to business!
The BITBLT command, built into the line-a routines is heavily
used by GEM and by most GfA programs because GET and PUT use it
extensively. BITBLT can perform raster operations on retangular
memory blocks that are bit images (phew, quite a complicated
sentence!) It means, that you can move or copy parts of the
screen around memory. This is how GET and PUT work. GET bitblits
a part of the screen into a string and PUT bitblits it right back
into the screen! The only drawback of bitblit is that you can
only BITBLT rectangular parts. So you can't just copy a circular
or randomly formed part of the screen. Most drawing programs can
only use rectangular blocks, but recently some programs can also
handle non-rectangular blocks. Just check out STAD, MonoSTar+ and
The Final ArtiST! (A final version of The ArtiST is scheduled for
September) Yes, I also found it out after hours of GETting and
PUTting. Of course, I didn't write my own BITBLT routine. It can
be done with the standard GET and PUT routines, only you have to
use a few tricks. I am going to try and explain it to you. There
should be a program on this disk that is fully documented
(BLOCKS.BAS), refer to it if you get a little confused, because
it is very hard to explain it.
Let's think about the way we are going to do it. If you want to
put a circular block on the screen, you have to do the following:
first put a black image of your block (in this case, a filled
circle) on the screen in mode 4. This will mean that the part of
the screen that is overlapped by the black block image (the disk
in this case) will be erased, and that the rest of the screen
will remain unchanged. Now we have a 'hole' in the screen were
the block will come. Now we put the block we grabbed from the
screen over the hole in transparent mode (mode 7). But this block
should have the same shape as the hole in the screen. This can be
done by 'masking' the block with the black image. Just put the
black image over the block in mode 1. Mode 1 means that
everything under the black image will remain unchanged, and that
everything that is not under the black image will be erased. It
all sounds very complicated, but maybe a little GfA will make it
clearer. We are still working with a circular block (it sounds
silly, 'a circular block' how can a block be circular??? I guess
the answer is 42....) that has a radius of 50 and the coordinates
of its center point are 320,200.
- GET 270,150,370,250,Block$
just capture the entire part of the screen in wich the circle
remains
- SGET Buffer$
save the actual screen
- CLS
clear it
- DEFFILL 1,1,0
we want a black fill pattern
- PCIRCLE 320,200,50
draw the black block image (I will call it the mask from now on)
- GET 270,150,370,250,Mask$
get the mask
- CLS
at this stage, we have captured the entire part of the screen in
which the block falls in block$, and the mask (a black image of
our circular block) in mask$. Now we have to mask off the parts of
the screen in block$ that is outside the circle. We will just
clear it.
- PUT 0,0,Block$
- PUT 0,0,Mask$,1
the block we captured from the screen will now be reduced to the
actual circular shape we want. Now we have the desired things, and
now we can start moving it around.
SPUT Buffer$
MOUSE X%,Y%,K%
X1%=X%
Y1%=Y%
REPEAT
MOUSE X%,Y%,K% !get mouse position
IF X%<>X1% OR Y%<>Y1% !have we moved the mouse?
SPUT Buffer$ !restore background
X1%=X%
Y1%=Y%
PUT X%,Y%,Mask$,4 !now we have a circular hole in the screen
PUT X%,Y%,Block$,7 !and here is our block!
ENDIF
IF K%=1
SGET Buffer$ !paste down the block by pressing left button
END IF
UNTIL K%=2 !press right button to exit
CLR Buffer$ !we don't need the buffer anymore.
That's it! A very small routine indeed. It's very simple as you
can see. In this case, I used a circular block, but you can use
any shape you want. Just use a polyline to define a random shape.
Just fill the polyline with a black pattern (other patterns can
produce some crazy effects...try it..) and capture it in Mask$. I
used these techniques in The Final ArtiST. As you can see, it
uses quite some memory (twice the captured block, which can be as
large as the entire screen, and a buffer screen. So in extreme
cases it will take 3*32 = 96K) and if the blocks are large, it
will be a bit slow (come on Blitterchip!) I hope it is all a bit
clear to you. Just check out the program. It will draw a few
boxes on the screen and use the routines above to do some nice
block capturing. Have fun.
If you have any questions (or suggestions for nice articles
perhaps) just call me (073-416499). After 8 pm I will probably be
home (not in the weekend though, Friday and Saturday night I hang
out in all kinds of places except my home). You can also try
calling me on a Sunday, but not before 1 o'clock because waking
me up can have some desastrous consequences.
I would like to congratulate the guys from the Strike-a-Light
group who are now an official and commercial software house. They
threw a nice party on which Richard Karsmakers said the historical
words: 'I will do the dishes!' after drinking lots of cola and
eating too much 'drink-nuts' as he calls them.
See you,
Stefan Posthuma
Now, let's go on with the regular stuff!
Mr. G.A. Tijssen from Groningen, The Netherlands, has succeeded
in finding out more with regard to the SPMOD.PRG program, that
allows speech in GfA Basic. By the way, this program is located
on our Compilation disk #1 under the name STSPEECH.PRG, or under
the same name on PD disk A21 of the SAG, Stichting ST and ST Club
Eindhoven. Here, you'll find the adapted version of the program:
' Program to use speech in GfA Basic
' Research by RĂ¼diger Eichin and G.A. Tijsen
'
Cls
A$="\SPMOD.PRG"
Reserve 150000
A=Exec(3,A$,"","") !Load program
If A<>0 Then
Print "Load error!"
Stop
Endif
A=A+256 !Jump over basepage
Dpoke A+&HE,&H4E75 !Poke RTS
Dpoke A+&H6C,&H4E75 !Poke RTS
Dpoke A+&H76,&H4E71 !Poke NOP
Dpoke A+&H84,&H4E71 !Poke NOP
Dpoke A+&HE2,&H4E71 !Poke NOP
Dpoke A+&HFC,&H4E71 !Poke NOP
Buffer=A+&H6EEE
Adr1=A+&H32 !Work input string
Speech=1
'
@Print ("Hello! Have you ever heard software speech on the")
@Print ("Atari before? Well, this is it!")
End
Procedure Print (Txt$)
If Speech=1 !Flag set?
Poke Buffer,Len(Txt$)+3
Poke Buffer+1,Len(Txt$)
For I%=1 to Len(Txt$)
Poke Buffer+1+I%, Asc(Mid$(Txt$,I%,1))
Print Mid$(Txt$,I%,1)
Next I%
Print
Void C:Adr1() !Speak!
Else
Print Txt$
Endif
Return
Mr. Tijsen also found out that it is possible to change pitch
(tone height) and speed:
'%k' in the string determines the speed, where k can range from
20 to 127.
'!k' in the string determines the pitch, where k can range from
76 to 127.
Further, the string may not be longer than 256 bytes in total.
That was it for today! I hope to offer you some more tips &
tricks in the next issue of ST NEWS - Volume 2 Issue 6.
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.