INTRODUCTION TO QBASIC SERIES #3
Writer: Matthew River Knight
Welcome to the third part in the Introduction to Qbasic Series! We went
over quite a lot of information last time, having covered some more of the
capabilites of Qbasic with regard to the handling of text, demonstrated how
to allow the user input from the keyboard, did some LOOPing, and we even took
a brief look at how to display graphics in Qbasic. This time I'd like to 
cover some more of these simple things before we go onto more difficult areas
of programming, hopefully picking up some information that we left out along
the way.
First of all, let's take a look at what else we can do with Qbasic as far as
text handling is concerned. For starters, it would be nice if we could place
text at a specific location on the screen wouldn't it? Lucky for us, Microsoft
wrote made a nice little routine to do this for us. This is the LOCATE 
statement. The LOCATE statement tells the computer at which location on the
screen the next PRINTed text must be placed. You'll recall that last issue,
in order to explain how PSET works, I described the screen as a grid. When
using LOCATE you also have to think of the screen as a grid, but it works
a little differently. The 'grid' that we're talking about when using LOCATE
is not made up of pixel spaces, it is made up of much larger blocks that are
basically the same size as your average ASCII character. And what is an 
ASCII character you ask? Well, all the letters and numbers you see on the
screen in DOS are ASCII characters. Apart from the number and letter
characters, there are also some other ASCII's which look quite strange. You
have seen some of them before. Some of them are used by the Qbasic editor
to draw the menu's and the scrollbar, etc. ASCII stands for American Standard
Code for Information Interchange. 
Another way of thinking about how LOCATE works is like this: suppose you
wanted to put some text, for example "Qbasic rulz!", 5 ASCII spaces across
the screen, and 10 ASCII spaces down. Then all you'd have to do is this:
LOCATE 10, 5
PRINT "Qbasic rulz!"
Try experimenting with different numbers and see what results you get. Using
LOCATE will make your life much easier when using text! There are some other
similar text handling routines, but there is no need to use them since LOCATE
is generally capable of doing exactly the same as them, but is easier to use
and more versatile.
Okay, now onto something more fun ^_^ Last time when we looked at using
graphics in Qbasic we really didn't do very much. All we used was PSET and
LINE - not too interesting. So we'll cover some better stuff this time round.
It is sometimes necessary that you know the color code of a certain pixel on
the screen. You can actually do some pretty cool graphics effects just by
knowing this simple information. In Qbasic, we use the POINT statement to
obtain the color code of a certain pixel on the screen. The POINT statement
is very versatile in the way that it may be used, and this makes it very
easy to understand.
For example, if you wish to get the color of a pixel at the coordinates (2,5)
on the screen 'grid' into the Col variable then all you do is this:
PSET (2, 5), 2  'Place a green pixel at coodinates (2,5)
Col = POINT(2, 5)  'Get the color code of the pixel at (2,5)
You can also use POINT like this:
IF POINT(2, 5) = 2 THEN PRINT "That pixel is green"
Try playing around with this, and maybe you'll figure out how to do something
cool using a combination of POINT and one of the other Qbasic drawing routines.
I once wrote a little program using PSET and POINT that allowed you to print
text on the screen, and it melted what looked like lava around it. There is
no reason why you couldn't write a program to do exactly that!
Okay, now on to something a bit more cool. You have probably found that using
LINE to draw graphics is rather difficult and time consuming. There is
another Qbasic command for drawing that is much easier to use. It's called
DRAW! It works quite unlike any other Qbasic routines we have covered so
far, as you'll soon see.
The DRAW statement has its own commands for doing things. For example, it
has the U command for drawing lines up, and the D command for drawing lines
down. Let's demonstrate this by means of an example:
PSET (10, 10), 2  'Start drawing at (10,10) in green
DRAW "U100"  'Draw a line up, 100 pixels in length
PSET (100, 100), 14  'Start drawing at (100,100) in yellow
DRAW "D20"  'Draw a line down, 20 pixels in length
There are lots of commands used with DRAW, but you'll probably never use half
of them. We'll cover the most commonly used ones. If you want to know the
others then you'll have to take a look at the Qbasic help file.
You have probably already guessed that in order to draw right, you use the
DRAW command R, and to draw left you use L. This should have been obvious.
But what if you want to draw diagonally? Well, to draw diagonally up and
right you use the DRAW command En, where n is a number specifying the pixel
length of the line to be drawn. To draw diagonally down and right you use the
commnd, F. To draw diagonally down and left you use G, and lastly, to
draw diagonally up and left you use H. Simple no? Okay, here's an example:
PSET (160, 100), 2  'Start drawing at (160,100) in green
DRAW "H20 E20 F20 G20"
Note that I have put a space between each of the DRAW commands in order to
make it easier for you to read. You don't have to do it this way though. You
could just as easily have left them out, and it would do exactly the same
thing. Like this:
PSET (160, 100), 2  'Start drawing at (160,100) in green
DRAW "H20E20F20G20"
It really doesn't make a difference. 
Another usefull DRAW command is C which sets the DRAWing color. All you do
is say Cn where n is the color code of the color in which you'd like to 
DRAW, and voila - you're DRAWing in that color. Could it really be any 
easier?! Let's demonstrate this by means of an example:
PSET (160, 100), 2  'Start drawing at (160,100) in green
DRAW "C2 H20 C3 E20 C4 F20 C5 G20"
Once again you can see that I've put spaces between each of the DRAW commands
in order to make this easier to read and understand. If I were writing a 
program in which readability was not a necessity, I'd have left the spaces
out since they're a waste of space.
There are many other DRAW commands that can be used, but I'm not going to 
cover it all here, when there is a perfectly good description of all of them
sitting right there in the Qbasic help files. One thing that I should 
mention before we go onto something else is that you are able to use DRAW 
with strings instead of specifying it right after the command. This allows
you to save a lot of space. To clarify this further, here's an example:
Diamond$ = "C2 H20 C3 E20 C4 F20 C5 G20"
PSET (160, 100), 2  'Start drawing at (160,100) in green
DRAW Diamond$
In the above example you can clearly see that we have used DRAW with a string
variable, instead of placing all the commands right after the DRAW statement.
You will find this ability very usefull when you find the need to DRAW an
object more than once. Without this ability you'd have to specify all those
commands to draw the object again, and again, and again, which is really a
waste of space.
Right. Now we've covered PSET, POINT, LINE and DRAW. With that you can, with
some ingenuity, draw some fairly good graphics. But what if you want to draw
a circle? Can you imagine writing the DRAW code for all of that! Yeah, it 
would be a total nightmare! Fortunately there is a Qbasic statement called
CIRCLE which allows you to draw circles. It's actually a bit more versatile
than that in the light that it can not only draw circles, but also ellipses,
and fractions of circles/elipses. It's a really great little routine. So
let's learn how to use it!
We'll start off using CIRCLE just to do simple stuff, and then we'll work
our way up, step-by-step, finally getting onto some more difficult stuff.
Okay. In order to draw a yellow (color code 14) circle with a radius of 15 at
the coordinates (160,100) on the screen 'grid' we'd type the following code:
CIRCLE (160, 100), 15, 14
Now that wasn't so hard, was it? Right, now that we've mastered the drawing
of circles, I think it's time that we move onto ellipses. You may not have 
heard of an ellipse before, so this is what it is: an ellipse is, in the
most simple terms I can think of, basically like a squashed circle! You can
probably imagine what I mean. It can be squashed from the top, or from the
side. It doesn't really matter. Any squashed circle is an ellipse!
Let's, for example, say you wanted to have a circle that looked squashed 
from the top. First thing you have to think about is how squahed you want it
to be. If we wanted to squash the circle, from the top, by 50% then we'd do
CIRCLE (160, 100), 15, 14, , , 50 / 100
If we wanted it squashed by 70%, from the top, then we'd do this:
CIRCLE (160, 100), 15, 14, , , 30 / 100
Simple no? Unfortunately, although we are able to describe the squashing 
effect in degrees here, the CIRCLE routine doesn't actually think of it that
way, and that makes life quite difficult when we want to squash a circle
from the sides - the degrees thing doesn't work anymore. It actually works
like this: the division (above it is 29/100) which is actually called the
aspect describes the ratio of the x radius to the y radius (x;y). The 
defualt aspect ratio depends on the screen mode, but gives a visual circle
in any graphics mode, assuming a standard monitor screen aspect ratio of 4:3.
Did that make you a little dizzy? Yep? Okay, well, then let's go about it
this way...practise! Play around with this until you understand! That's the
best way to understand programming. Just to get you started, here's an
example program showing you how to squash a circle from the side:
CIRCLE (160, 100), 15, 14, , , 170 / 100
Play around with this and it'll soon make sense.
Okay, as I mentioned earlier, it is possible to draw fractions of the circle,
but that is slightly mathematical so I'll leave that for another time. I
think I've confused you enough for one day!
There are still other graphics routines to cover, but we'll have to leave 
that for another issue. We have said more than enough about graphics this
Okay, we'll cover one more aspect of programming before I leave you to play
around with what you've learned this issue. Sound in Qbasic! Before we 
even start this I need to explain one simple thing - Qbasic is, ordinarily,
only able to produce sound through the internal PC speaker. You probably
didn't even know that you have a speaker inside your computer, but you do.
In the old days of computing there was no such thing as sound cards, and
sound amplifiers for the computer. Such things were unheard of. In those
days everyone used to have to play sound through the little speaker inside
the computer. Unfortunately the internal speaker is really junky. Any sound
that comes from it sounds terrible. But, as a newbie, it's the only sound 
that'll be available to you for a while. There are ways to use the sound 
card in Qbasic, but it's really difficult, so we are not going to cover that
at this stage.
Okay, I have rambled on long enough! We have quite a few Qbasic statements
at hand which generate sound through the PC speaker. We'll start off with
some simple stuff. It's fairly clear that the simplest form of sound we
could possibly get the computer to do is just a beep. What could be easier 
than that? Well, there is a Qbasic statement called BEEP that does just that!
BEEP generates a beep-like noise from the internal speaker at 800hz (800 
cycles per second) for one-quarter of a second. It's really easy to use 
BEEP. Let's test it:
Yep! That's it! That's all you have to type to use BEEP. Could anything be
any easier than that?! Well congratulations, you've just mastered yet another
Qbasic statement, and it's only taken you two seconds! ^_^
Okay, soon you're likely to get bored with BEEP. With BEEP you are not able
to specify the pitch of the BEEP and the duration for which it plays. And
that is no good. No good at all. Okay, well this isn't much of a problem.
There is a Qbasic statement called SOUND which allows you to do exactly 
what BEEP won't allow you to do! The syntax of SOUND is:
SOUND frequency, duration
frequency is the pitch of the sound. For those of you who don't know what this
means (get a dictionary!) here's some examples - an example of a low pitch
would be thunder. It sounds deep and has a low pitch. An example of a high
pitch would be the squeek of a mouse. It has a high pitch. The higher the
number is in place of frequency, the higher the pitch of the sound. The 
frequency may not be lower than 37, and not higher than 32767.
duration specifies the amount of time the computer has to spend making the
sound. It is measured in clock ticks. Clock ticks occur 18.2 times per 
second. The duration may not be less than 0, and not higher than 65535.
Ah, okay, now is a good time for an example, no?
SOUND 300, 70
If you really want to give yourself a headache (why would you want to do 
that?!) then run the following program:
SOUND 5000, 65535
I would not advise running that program. You'll get a terrible headache. You
could easily write a program that would trick somebody into thinking there's
a mosquito in the room ;)
Now the problem with this stuff is that it's really hard to write music 
with it. It's even harder to try and write sound effects. With music we
are accustomed to sounds being described as A,B,C,D,E,F and G. Well 
here's a list of the equivelent frequency's for them! ^_^
I took this list from a book I have on Qbasic. For some reason there are
a number of different A's, B's, C's...etc. I know nothing about music so
I have no idea why this is the case. Those of you who know about music will
be able to make more sense of this than I can ;)
Note   Frequency   Note   Frequency
C      130.810     C*     523.250
D      146.830     D      587.330
E      164.810     E      659.260
F      174.610     F      698.460
G      196.000     G      783.990
A      220.000     A      880.000
B      246.940     B      987.770
C      261.630     C     1046.500 
D      293.660     D     1174.700
E      329.630     E     1318.500
F      349.230     F     1396.900
G      392.000     G     1568.000
A      440.000     A     1760.000
B      493.880     B     1975.500
*Middle C.
By doubling or halving the frequency, the coinciding note values can be 
estimated for the preceding and following octaves.
To produce periods of silence, use the following statement:
SOUND 32767, duration
To calculate the duration of one beat, divide the beats per minute into the
number of clock ticks in a minute (1092).
The following table illustrates tempos requested by clock ticks:
Tempo       Notation       Beats/Minute       Ticks/Beat
very slow   Larghissimo
            Largo          40-46              27.3-18.2
            Larghetto      60-66              18.2-16.55
            Adagio         66-76              16.55-14.37
slow        Adagietto
            Andante        76-108             14.37-10.11
medium      Andantino
            Moderato       108-120            10.11-9.1
fast        Allegretto
            Allegro        120-168            9.1-6.5
very fast   Prestissimo
Like I said, I know nothing about music, and I thus have no idea what the
above table is talking about. The only thing that I know about music is
that it comes out of the radio! ;) Those of you who know about music will
probably find the above information very usefull, but as for the rest of you
who know no more about that stuff than me, don't worry about it. It's still
possible to do cool stuff with SOUND without any knowledge of music.
There's another way to use music with the internal speaker in Qbasic, but
we'll cover that (and other things) next issue. Until next month, just play
around with what you have learned, and see if you can come up with something
cool. If you make a little program, and you are proud of it and would like
others to see it, then email it to me at horizonsqb@hotmail.com and I'll
include with the next issue of the QBCM! Have fun with Qbasic!!! ^_^
Cya next month!