Author - Dean Sharples

Variables and Dimensions

Variables and Dimensions are a way of storing information in STOS to use in your program. The two main pieces of information are words and numbers. Your program would make a decision if one of these equaled something and act upon it. Here’s a simple example of a variable being used.

VARIABLES

10 print “Please type in a number”
20 input A
30 print “You choose the number”;A

What happens here is that the computer labels a little box as ‘A’ and inserts the number you typed in at the input prompt into it. The number you typed is now stored in the computer’s memory in a little box called ‘A’. Line 30 looks in the box and prints its contents to the screen, which of course is the number you entered. ‘A’ is the name we have chosen for the variable and the input command is one way of putting information into it. Another way to put information into a variable is like this.

10 let NUMBER=100
20 print NUMBER

Line 10 tells the computer to get one of its boxes and stick a label on it and call it NUMBER, then puts the value ‘100’ inside it. Note, the use of the command ‘let’ is optional and can be removed so your routine would be.

10 NUMBER=100
20 print NUMBER

Variables can be called anything you wish, using letters, words and symbols, but you must make sure that there are no STOS commands in the name or else you get something like this……

10 sin GLE=10

If you used the word ‘SINGLE’ then STOS finds the command ‘sin’ and gets confused. Try different names until you find one that appears in capitals.

Not only numbers can be used in variables, so can words or letters. If you wanted to put a word into a variable then you must add a ‘$’ to the variable’s name and the word must be put in between two quotes. For example.

10 NAME$=”DEANO”
20 print “MY NAME IS “;NAME$

10 input “What is your name”;NAME$
20 print “Hello There “;NAME$

You can also add variable values together which can be used in a game to add points to your score, for example.

10 SC=100
20 print “Your score is “;SC
30 print “Press a Key”
40 SC=SC+10 : goto 20

Line 40 tells the variable SC to equal the value of itself which is ‘100’ and the add ’10’ to itself. The same applies to letters, usually known as strings of characters. For example.

10 input “What is your first name”;NAME$
20 input “What is your second name”;SURNAME$
30 A$=NAME$+” “+SURNAMES
40 print “Hello “;A$

DIMENSIONS

As you know, a variable is a little box inside the computers memory. A dimension is a large box full of little boxes. Think of a cassette box, it’s one big box with so many slots for your cassettes. A dimension allows you to store so many pieces of information inside one variable. Here’s an example of how one could be used.

10 dim A(2) : rem Set up one variable box with two slots
20 A(1)=100 : A(2)=200
30 print A(1),A(2)

The same method can be used with strings.

10 dim NAME$(2)
20 NAME$(1)=”ST” : NAME$(2)=”PLUS”
30 print NAME$(1),NAME$(2)

Dimensions can be used exactly the same way as variables, the only difference is that with dimensions you use the variable name plus the number of slots in the variable box….IE: dim SC(10).

Another type of dimension is the two way dimension. This is setting up so many boxes with so many slots. Try this example.

10 dim NUMBER(5,10) : rem Set up five boxes each with ten slots.
20 NUMBER(1,1)=100 : rem Put ‘100’ in box one, slot one
30 NUMBER(2,1)=500 : rem Put ‘500’ in box two, slot one.
40 print NUMBER(1,1)
50 print NUMBER(2,1)

This is useful for directions in adventure games. For example this routine sets up a dimension with five locations and four exits.

10 dim D$(5,4)
20 for X=1 to 5 : For Y=1 to 4
30 read D$(X,Y)
40 next Y : next X
50 data 2,3,4,5
60 data 1,2,3,4
70 data 5,2,4,3
80 data 7,6,2,1
90 data 2,4,1,2

I recommend you use clear variable names and plenty of REM statements in your program so you can keep track on what each variable and dimension does.

Stacking a Memory Bank

As you know, there are only fifteen memory banks that you can use in STOS. Yet some games have more than fifteen pictures or music files overcoming the fifteen bank limit. This is done by simply sticking all the files into one bank on top of each other. This is called Stacking a Bank.

Let’s say we have five pieces of chip music that we want to save along with the program in one bank and call each piece when we need it. Well first to get them all in the bank we need to add up the total length of the files and reserve a bank to this length. If you put your five selected tunes on a disk then type ‘dir’ you should get a list like this.

Drive A:

MADMAX.MUS 4200
KILLING.MUS 2100
CIRCUS.MUS 8244
ALEC.MUS 4774
STOMP.MUS 8000

Here we have first the filenames followed by the file length, the file lengths need to be added up and then a bank reserved…..

4200+2100+8244+4774+8000=27318

10 reserve as work 5,27320+100

Note how the value in line 10 is slightly higher than the calculated figure. This is because we must always reserve a round figure for the length, we then add 100 bytes just to make a bit more space in the bank. Now we can add more lines to this routine to load the music files into the bank.

20 bload “MADMAX.MUS”,start(5)
30 bload “KILLING.MUS”,start(5)+4200
40 bload “CIRCUS.MUS”,start(5)+4200+2100
50 bload “ALEC.MUS”,start(5)+4200+2100+8250
60 bload “STOMP.MUS”,start(5)+4200+2100+8250+4780
70 rem SAVE BANK
80 bsave “M_BANK.DAT”,start(5) to start(5)+length(5)

The first file has loaded into the large bank starting from the start of the bank so it has taken up 4200 bytes of the bank which is the length of the first file (MADMAX.MUS). To load the second file in we have to make sure it slots in after the first one so we load in into the bank starting at the position where the first file ends. The next file has to load in and slot in the bank after the first two so we add the values of the first two files to give us the starting position where to load the third file.

So basically, we are loading in each file after the other adding up the values of the previous files to find the start position of the present file in the large reserved bank. Rather than have all this value+value bit we can add up the values into one length like so.

20 bload “MADMAX.MUS”,start(5)
30 bload “KILLING.MUS”,start(5)+4200 : rem Length of first file
40 bload “CIRCUS.MUS”,start(5)+6300 : rem Length of files 1 and 2
50 bload “ALEC.MUS”,start(5)+14550 : rem Length of files 1,2 and 3
60 bload “STOMP.MUS”,start(5)+19330 : rem Length of files 1,2,3 and 4

Note its also important that file lengths that are not even must be rounded up to the nearest even figure for the bank to stack properly.

In order to use the stacked bank in our program we just reserve a bank to the full length and bload it in. Now the easiest and quickest way to play the music is like this. First we need two arrays which will hold the start address of each file, and the length of each file. The music can easily be played by one line, saving a load of IF statements.

10 reserve as work 5,27320+100
20 bload “M_BANK.DAT”,5
30 dim MUS_ST(5) : rem Reserve array for start addresses
40 dim MUS_LE(5): rem Reserve array for file lengths
50 MUS_ST(1)=0 : MUS_ST(2)=4200 : MUS_ST(3)=6300 : MUS_ST(4)=14550 :
MUS_ST(5)=19330
60 MUS_LE(1)=4200 : MUS_LE(2)=2100 : MUS_LE(3)=8250 : MUS_LE(4)=4780 :
MUS_LE(5)=8000
70 input “Choose tune to play (1 to 5)”;PL
80 if PL=0 or PL>5 then goto 70
90 rem Play chosen music file
100 A=musauto(start(5)+MUS_ST(PL),1,MUS_LE(PL))
110 wait key
120 A=musauto(0,0,0) : goto 70

You can use the same method with packed pictures. In your game you just load in the bank of stacked binary packed pictures and call them up in the same way……for example.

10 reserve as work 10,50000
20 bload “PICS.PAC”,10
30 dim SCR_ST(4)
40 SCR_ST(1)=4000 : SCR_ST(2)=3200 : SCR_ST(3)=6500 : SCR_ST(4)=9000
50 for X=1 to 5
60 unpack start(5)+SCR_ST(X) : wait 50
70 next X

So there you have it. With this method you can have as many binary files in a bank as memory permits, and put an end to the bank limit.

Using The STOS Sprite, Move and Anim commands

Sprites are the little graphical images that move about on screen such as ships, aliens, bullets, little men, etc. Let’s look at how we can do this.

THE SPRITE COMMAND

Before you can use the sprite command you will need some sprites in memory. For example, try loading the animals1.mbk sprite bank from the STOS disk.

EG: load”animals1.mbk”

As it’s a sprite bank, STOS automatically loads them into bank one. Now let’s put it on screen.

10 sprite 1,100,100,14

This put a monkey sprite on screen. Now lets take a closer look at the sprite command.

sprite NUMBER,X,Y,IMAGE

NUMBER is the number of the sprite which ranges from 1 to 15. You can only place 15 sprites on screen at any one time.

X AND Y are the X and Y co-ordinates where you want to put the sprite. So in the above example, the sprite is placed 100 pixels across the screen and 100 pixels down the screen.

IMAGE is the number of the sprite from the sprite bank you want to place on
screen. In the above example its image 14 which is the monkey.

Let’s try two sprites on the screen.

10 sprite 1,100,100,14
20 sprite 2,160,100,14

So we now have two copies of the monkey on screen. Try changing the image number and the second sprite will be another one from the bank. Sprites can be designed using the sprite editor accessory. Refer to the STOS manual on how to create sprites.

MOVING A SPRITE:

The sprite can be moved across the screen by using the MOVE command. It goes like this.

move X 1,(1,2,300) or move Y 1,(1,2,300)

Let’s look at the command in more detail.

move DIRECTION,NUMBER,(SPEED,STEPS,PIXELS)

DIRECTION can be X or Y, it tells STOS to move the sprite either X (across the screen) or Y (up or down the screen).

NUMBER is the number of the sprite to move.

SPEED is the speed to move the sprite which ranges from 1 (fast) to 4 (slow).

STEPS tells STOS how many pixels to move the sprite at a time.

PIXELS tells STOS how many pixels to move the sprite.

Look at this example

10 sprite 1,10,10,14
20 move x 1,(1,2,100)
30 move on

So the sprite is moving across the screen at a speed of 1, in steps of 2 pixels at a time, and 100 pixels across the screen. The move on command tells STOS to start the movement. Note that sprites work on interrupt so your program can be doing over things while the sprite is working.

We can add extra letters to the move command to make it do other things like L and E. Normally the sprite will move and stop at the PIXELS parameter you choose but you can fix STOS to keep moving the sprite along its set strings by adding the letter L at the end of the move command. Using the E command allows you to stop the movement at a certain point.

EG:

10 sprite 1,10,10,14
20 move x 1,”(1,2,100)(1,-2,100)L” :rem keep moving sprite
30 sprite 2,10,50,14
40 move Y 1,”(1,2,100)E50″:rem stop sprite at Y co-ordinate 50
50 move on

ANIMATING THE SPRITE

We can step through the images of a sprite by using the ANIM command. The format goes like this…

anim NUMBER,(IMAGE1,DELAY),(IMAGE2,DELAY) etc

NUMBER is the number of sprite to animate.

IMAGE is the image number to show.

DELAY is the time to pause between each image.

Lets animate the monkey.

10 sprite 1,100,100,14
20 anim 1,”(14,5)(15,5)(16,5)(17,5)L” : anim on

So this command flicks the sprite between images 14 to 17 and then loops back to the start. We now have a walking monkey.

OTHER COMMANDS

MOVON(NUMBER)

This command checks to see if the sprite is still moving. It returns 0 if it isn’t and 1 if it is.

UPDATE, UPDATE ON, UPDATE OFF

STOS updates sprites every 50th of a second. This can be arkward when you want to do other things and STOS is using processor time for its updating. STOS is always checking a sprite and updating its position and you can turn the feature off by using the Update Off command, and Update On can return things back to normal. You can then update the sprite when you want freeing some processor time like so…

10 update off
20 for X=10 to 100
30 sprite 1,X,10,1 : update
40 next X

Try removing the update command from this example and the sprite will not be displayed on screen. It’s still there but just not being copied to the screen.

Create Pre-shifted Sprites Without Missing Link

What has always been a pain for ST users is the ST’s sixteen pixel boundary problem. This means that any graphic has to be copied in multiples of sixteen pixels. For example, if you used the command screen copy to put a piece of picture on screen then it will round its x co-ordinates to the nearest sixteen pixels. Look at this example.

screen copy 5,10,10,100,100 to physic,10,10

The command would ignore the value of 10 for the x co-ordinate and place it on screen at x co-ordinate 16. Always rounding up to the nearest step of 16, EG: 16,32,48,64 etc. This can be arkward if you need your piece of graphic to be in its exact place.

The only way to overcome this problem is by pre-shifting. This means making a number of copies of the graphic with a smaller pixel gap in between. Try this example…

10 key off : curs off : flash off : hide on : mode 0
20 dim SP$(16)
30 for X=1 to 16
40 sprite 1,X,16,1 : put sprite 1 : wait vbl : sprite off
50 SP$(X)=screen$(logic,0,16 to 16,32) : cls
60 next X
70 rem Show It
80 logic=back
90 for X=1 to 16
100 cls logic
110 screen$(logic,X,16)=SP$(X) : wait 5
120 screen swap : wait vbl
130 next X

This routine shows how to make pre-shifted sprites. Lines 10 to 60 make sixteen copies of sprite one and the rest of the routine moves it across the screen at a step of one pixel at a time. Each image of sprite one is caught in the ‘screen$’ command, each one captured in its own different position moved one pixel across further than the last one. Might you, sixteen images in memory can cost a lot of memory so we can make less images, this means the pre-shifted graphic moves in bigger steps but takes up less memory. The pre-shifed graphic can move in either 1,2,4,8, or 16 pixels across the screen. In other words we are cutting down the 16 pixel box into smaller equal size boxes. We can work out how many images we need and how many steps we need to move in like this.

16/STEPS=?

So we take the number 16 which is the boundary and we divide it by the number of steps or pixels we want the pre-shifted graphic to move and we get the answer to how many copies we need to make of it. For example, if you wanted to move the sprite across the screen at four pixels at a time then you could try this sum.

16/4=4

This means you would have to make four copies of the sprite. Try other sums but remember ‘STEPS’ must be either 1,2,4,8, or 16.

Now let’s imagine we have a block of a picture 100×100 pixels in size and we wanted to place it at co-ordinates 36,0 on the screen. Using screen copy would place the block at 32,0. Therefore we need to screen copy the block to a dummy screen at co-ordinates 32,0 and scroll it along to 36,0. To do this we need to use the Def Scroll command like this.

10 key off : curs off : hide on : flash off : mode 0
20 reserve as screen 5 : rem Dummy screen
30 screen copy 6,0,0,100,100 to 5,32,0 : rem copy block from bank 6
40 def scroll 1,32,0 to 132,100,4,0 : rem Set block to scroll 4 pixels
50 logic=5
60 scroll 1 : wait vbl
70 ink 0 : bar 32,0 to 35,100 : rem Get rid of picture trail
80 logic=physic
90 A$=screen$(5,0,0 to 320,100) : rem Capture preshifted block
100 rem merge it onto screen at right place
110 screen$(logic,0,0)=A$
120 A$=”” : erase 5 : stop

So what this routine is actually doing is putting our block on a sixteen pixel boundary in a bank and scrolling it along from X Co-ordinate 32 to X Co_ordinate 36. Then we can merge it on screen, this takes it from its exact position and puts it on screen at its exact position.

So that’s it, with a bit of work you can have a large block moving across the screen like a sprite. This is how to do it all if you don’t have the missing link or extra extensions. In missing link you can set up your own pre-shifted sprites using a special MAKE program and you can position blocks anywhere on screen using the ppsc command from the Extra extension.

How to Store Variable Information on Disk

When I write a program, I sometimes find it easier to store variables on disk rather than inside the program. Using a few variables its okay to store them in a program but what about storing lots of information in variables. This makes your program a lot longer. Lets say for example, I was writing an adventure game and I wanted 100 location descriptions. In my game I could have a routine like this.

10 dim LOCATION$(100) 20 for X=1 to 100 : read LOCATION$(x) : next X
1000 rem LOCATION DESCRIPTIONS
1010 data “This is location one.”
1020 data “This is location two.”

And so on, adding a hundred lines to STOS. How about doing it this way.

10 LOCATION=1
20 print “Type in the description for location “+str$(LOCATION)
30 input L$
40 F$=file select$(“*.DAT”)
50 open out #1,F$
60 print #1,L$
70 close #1
80 cls : inc LOCATION : goto 20

Doing things this way with this separate routine allows me to enter the description as I would see it on screen, all nicely spaced out, rather than playing about spacing out the words in a data statement. I could save each file out under names like LOC1.DAT for location one and LOC2.DAT for location two etc. Once all descriptions are saved then I could put a routine in the game to load each file when I need it…..for example.

10 LOCATION=1
15 F$=”LOC”+str$(LOCATION)-” “+”.DAT”
20 open in #1,F$
30 input #1,L$
40 close #1
50 print L$ : rem print Location
60 print : inc LOCATION : goto 15

Here’s another tip for a program which needs loads of zones on screen on loads of pictures. Just simply type out a program which allows you to create the zone data using just the mouse.

10 key off : flash off : curs off : mode 0
15 dim X1(10,10),Y1(10,10),X2(10,10),Y2(10,10)
20 ZP=1 : ZA=1 : rem ZP=Zone Picture ZA=Zone Area
30 F$=”PIC”+str$(ZP)-” “+”.PI1″
40 load F$ : screen copy physic to back
50 repeat : until mouse key=1 : X1=xmouse : Y1=ymouse
60 wait 40
70 repeat : until mouse key=1 : X2=xmouse : Y2=ymouse
80 rem X1,Y1 : Top left hand co-ordinates of zone
90 rem X2,Y1 : Bottom right hand co-ordinates of zone
100 X1(ZP,ZA)=X1 : Y1(ZP,ZA)=Y1 : X2(ZP,ZA)=X2 : Y2(ZP,ZA)=Y2
110 if ZA<10 then inc ZA : goto 50
120 if ZA=10 and ZP<10 then inc ZP : ZA=1 : goto 50
130 open out #1,”ZONE.DAT”
140 for X=1 to 10 : for Y=1 to 10
150 print #1,X1(X,Y),Y1(X,Y),X2(X,Y),Y2(X,Y)
160 close #1

Once this is done you simply load this file into your program using ‘Open In’ and you can set your zones easier. For example.

10 key off : curs off : flash off : mode 0
20 dim X1(10,10),Y1(10,10),X2(10,10),Y2(10,10)
30 open in #1,”ZONE.DAT”
40 for X=1 to 10 : for Y=1 to 10
50 input #1,X1(X,Y),Y1(X,Y),X2(X,Y),Y2(X,Y)
60 close #1
70 ZP=1
80 unpack 5 : rem unpack picture one
90 for ZA=1 to 10
100 set zone ZA,X1(ZP,ZA),Y1(ZP,ZA) TO X2(ZP,ZA),Y2(ZP,ZA)
110 next ZA
120 repeat : CH=zone(0) : until mouse key=1

There are loads of things you can do to improve the length of your programs and makes things easier. One thing you can do is write a routine to record the X and Y co-ordinates of alien movement instead of typing in the co- ordinates in data statements by hand.