## My BASIC Simple Platform Game w/ Alternative Sprite Drivers

Started by AMSDOS, 11:40, 06 November 18

0 Members and 1 Guest are viewing this topic.

#### AMSDOS

I thought I'd start a new thread based on there being some discussion about using Sprites in BASIC and Collision, I wasn't sure if this was worth writing a Wiki Article about it, but I'll just start from here.

What I've got here are a bunch of BASIC Platform Games, though I've taken these programmes and modified them, they all play the same and they all use Text Coordinates, so no pixel perfect animated graphics here, a couple of programmes I've added to demonstrate limitations or features, so following my really BASIC example, I have added a BASIC example which uses Transparent Mode, followed by BASIC programmes which are using Ariom Sprites, Easi-Sprite Driver, Spritemaker v2.3 and the Spriting Back Utility.

My aim here was to create a BASIC Platform Game with one hazard. The character in this routine cannot jump, but has to fall through the gaps in the floor and avoid the hazard which travels left->right and so on, there's nothing difficult about it (in fact it's dead easy), but it demonstrates how the TEST function can be used Locomotive BASIC instead of an Array or COPYCHR\$(#0).

`100 MODE 0:BORDER 0:INK 0,0:INK 1,26:INK 2,18:INK 3,6110 DEFINT a-z120 SYMBOL 255,0,8,124,40,32,124,56,0:SYMBOL 254,0,16,62,20,4,62,28130 GOSUB 1010140 x=INT(RND*15)+5:y=3:sx=x:sy=y:LOCATE x,y:PRINT" ";:x=INT(RND*20)+1:y=5:sx2=x:sy2=y:LOCATE x,y:PRINT" ";150 x=1:y=2:c=250:d=0:LOCATE x,y:PEN 1:PRINT CHR\$(c);160 bx=1:bc=255:bd=1:GOSUB 1160170 WHILE d=0 ' Main Game Loop180   IF INKEY(1)=0 THEN IF x<20 THEN c=250:LOCATE x,y:PRINT" ";:x=x+1:GOSUB 1130:LOCATE x,y:PEN 1:PRINT CHR\$(c);190   IF INKEY(8)=0 THEN IF x>1 THEN c=251:LOCATE x,y:PRINT" ";:x=x-1:GOSUB 1130:LOCATE x,y:PEN 1:PRINT CHR\$(c);200   GOSUB 1110210   LOCATE bx,4:PRINT CHR\$(32):bx=bx+bd:GOSUB 1160220   IF bx=20 THEN bd=-1:bc=254 ELSE IF bx=1 THEN bd=1:bc=255230   GOSUB 1130240   IF x=20 THEN IF y=6 THEN d=1250 WEND260 LOCATE 1,10:PEN 1:END1000 ' Draw Platforms1010 FOR y=3 TO 7 STEP 21020   PEN 2:LOCATE 1,y1030   PRINT STRING\$(20,131);1040 NEXT y1050 RETURN1100 ' Check if Character is over hole1110 WHILE TEST((x-1)*32,398-(y*16))=0:LOCATE x,y:PRINT" ";:y=y+1:LOCATE x,y:PRINT CHR\$(c);:CALL &BD19:WEND:RETURN1120 ' Check if Hazard has collided with Character1130 IF x=bx THEN IF y=4 THEN d=1:RETURN1140 RETURN1150 ' Move Hazard1160 LOCATE bx,4:PEN 3:PRINT CHR\$(bc);:CALL &BD19:RETURN`

So the program above setups some redefined graphics of my hazard (facing left and right), draws the platforms (1000-1050), puts two gaps in the platform (140), draws my main character (150) and the hazard (160 & 1160), before entering the Main Loop (170), Moving my character Left and Right (180 & 190), Line 200 takes the programme to 1110 where a check is done.
The TEST function in BASIC is used to return a pixel from Coordinates X & Y, however because I'm using Text Coordinates, I need to calculate that into the graphical coordinate positions and as this demo is using MODE 0, the calculations are converting it into a range where the MODE 0 cursor is situated. The only other trick involved here is based on the value of X. When using LOCATE for instance you don't say LOCATE 0,0 to position the cursor the top left of the screen, but when dealing in graphics top-left corner of the screen has a value of 0,398, which is why I have to subtract 1 in that TEST function.
The y coordinate is also 0 based, however for this example I'm testing what's under my character, so while y=1 for my characters initial position (above the platform), the WHILE statement in line 1110 only enters when a gap is detected with the code with in that WHILE loop causing my character to fall through.

Back to my Main Loop - the hazard is deleted and printed in it's new position (210 & 1160), if the hazard has reached the end of the screen it turns around (220), a check is carried out to see if the hazard has collided with my character (230 & 1130), this was also tested when I move my man left or right (180 & 190).

Which pretty much covers how that program works, there's no array's, no COPYCHR\$(#0), the TEST may only return a single pixel, though seems to be sufficient enough here.

* Using the old Amstrad Languages    * with the Firmware
* I also like to problem solve code in BASIC    * And type-in Type-Ins!

Home Computing Weekly Programs
Popular Computing Weekly Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

#### AMSDOS

#1

For my 2nd version of my BASIC Platform example, I've made a Multicoloured Graphical game using Transparent Mode and redefining the SYMBOL table, to try and speed the process along I've added a BASIC Sprite Routine (3050 to 3110) which functions as a Loop and I had to be clever where I placed my colours. Using Paint these were the characters I came up with:

The resulting programme is called BAS2PLAT.BAS

Some of the colours in the hazard for instance are used in my main character, fortunately there was no conflict, the platform itself also only has it's own set of colours. The resulting programme looks like this:

`100 MODE 0:BORDER 0:RESTORE 110:FOR p=0 TO 9:READ c:INK p,c:NEXT p110 DATA 0,18,3,11,2,26,6,15,12,10120 DEFINT a-z130 SYMBOL AFTER 230:GOSUB 2010140 ton\$=CHR\$(22)+CHR\$(1):toff\$=CHR\$(22)+CHR\$(0)150 GOSUB 1010160 x=INT(RND*15)+5:y=3:sx=x:sy=y:GOSUB 1310:LOCATE x,y:PRINT " ";:x=INT(RND*20)+1:y=5:sx2=x:sy2=y:GOSUB 1310:LOCATE x,y:PRINT " ";170 d=0:mx=1:my=2:ms=242:me=246:GOSUB 1410180 bx=1:bc=230:bd=1:s=bc:e=235:c=1:x=bx:y=4:GOSUB 3050190 WHILE d=0 ' Main Game Loop200   IF INKEY(1)=0 THEN IF mx<20 THEN ms=242:me=246:c=3:GOSUB 1510:mx=mx+1:GOSUB 1210:GOSUB 1410210   IF INKEY(8)=0 THEN IF mx>1 THEN ms=247:me=251:c=3:GOSUB 1510:mx=mx-1:GOSUB 1210:GOSUB 1410220   GOSUB 1110230   GOSUB 1710:bx=bx+bd:GOSUB 1610240   IF bx=20 THEN bd=-1:bc=236 ELSE IF bx=1 THEN bd=1:bc=230250   GOSUB 1210260   IF mx=20 THEN IF my=6 THEN d=1270 WEND280 LOCATE 1,10:PRINT toff\$;:PEN 1:END1000 ' Draw Platforms1010 FOR y=3 TO 7 STEP 21020   FOR x=1 TO 201030     s=252:e=253:c=81040     GOSUB 30501050   NEXT x1060 NEXT y1070 RETURN1100 ' Check if Character is over hole1110 WHILE TEST((mx-1)*32,398-(my*16))=01120   GOSUB 15101130   my=my+11140   GOSUB 14101150 WEND1160 RETURN1200 ' Check if Hazard has collided with Character1210 IF mx=bx THEN IF my=4 THEN d=1:GOSUB 1510:GOSUB 1610:RETURN1220 RETURN1300 ' Transparent Mode off1310 LOCATE 1,1:PRINT toff\$;:RETURN1400 ' Print Man1410 s=ms:e=me:x=mx:y=my:c=3:GOSUB 30501420 RETURN1500 ' Delete Man1510 GOSUB 13101520 LOCATE mx,my:PRINT" ";1530 RETURN1600 ' Print Hazard1610 s=bc:e=bc+5:c=1:x=bx:y=4:GOSUB 30501620 RETURN1700 ' Delete Hazrd1710 GOSUB 13101720 LOCATE bx,4:PRINT" ";1730 RETURN2000 ' Graphics2010 SYMBOL 230,0,8,0,8,0,0,0,0   ' Pen 12020 SYMBOL 231,0,0,0,32,32,0,0,0 ' Pen 22030 SYMBOL 232,0,0,0,0,0,0,56,0  ' Pen 32040 SYMBOL 233,0,0,0,0,0,124,0,0 ' Pen 42050 SYMBOL 234,0,0,4,0,0,0,0,0   ' Pen 52060 SYMBOL 235,0,0,120,0,0,0,0,0 ' Pen 62070 SYMBOL 236,0,16,0,16,0,0,0,0 ' Pen 12080 SYMBOL 237,0,0,0,4,4,0,0,0   ' Pen 22090 SYMBOL 238,0,0,0,0,0,0,28,0  ' Pen 32100 SYMBOL 239,0,0,0,0,0,62,0,0  ' Pen 42110 SYMBOL 240,0,0,32,0,0,0,0,0  ' Pen 52120 SYMBOL 241,0,0,30,0,0,0,0,0  ' Pen 62130 SYMBOL 242,0,112,0,0,0,112,0,0   ' Pen 32140 SYMBOL 243,32,0,0,0,0,0,0,0      ' Pen 42150 SYMBOL 244,0,0,0,104,112,0,0,0   ' Pen 52160 SYMBOL 245,0,0,0,16,0,0,80,72    ' Pen 62170 SYMBOL 246,0,0,120,132,136,0,0,0 ' Pen 72180 SYMBOL 247,0,14,0,0,0,14,0,0  ' Pen 32190 SYMBOL 248,4,0,0,0,0,0,0,0    ' Pen 42200 SYMBOL 249,0,0,0,22,14,0,0,0  ' Pen 52210 SYMBOL 250,0,0,0,8,0,0,10,18  ' Pen 62220 SYMBOL 251,0,0,30,33,17,0,0,0 ' Pen 72230 SYMBOL 252,255,129,129,129,0,0,0,0 ' Pen 82240 SYMBOL 253,0,126,126,126,0,0,0,0   ' Pen 92250 RETURN3000 ' Draw Sprites3010 ' Entry: s = start char # of sprite3020 '        e = end   char # of sprite3030 '        c = colour3040 '        x, y = xpos, ypos 3050 LOCATE 1,1:PRINT ton\$;3060 FOR i=s TO e3070   PEN c3080   LOCATE x,y:PRINT CHR\$(i);3090   c=c+13100 NEXT i3110 RETURN`

To try and simplify the code I added more subroutines, so now I have a routine for turning off the Transparent Mode (1310), Print Man (1410,1420), Deleting the Man (1510..1530), Printing the Hazard (1610..1620) & Deleting The Hazard (1710..1730). Initially I didn't have it coded that way, which lead me having Printing Issues by turning on & off the Transparent Mode. Even my Sprite Routine had to be modified.

I'm unsure if those problems may not have been evident if I was using BASIC 1.1, but from BASIC 1.0, it was creating quite a mess even though their only 8x8 Sprites.

Limitations
===========

Speed - the Sprites I've drawn here are using 5 & 6 colours for the Man and the Hazard.
Reducing the size or number of colours in the Sprites would speed up this example, though the game would have to have limited moving graphics.

Some Examples
==== ========

In the BASIC 10-Liners my Wild Entry game "Aliens Attack" uses transparent mode to create a couple of moving 3 coloured sprites and a Colourful explosion.
It's also possible to construct some colourful sprites by using the firmware and Assembly, to create a small assembly game, an example of this is on the CPCWiki.

* Using the old Amstrad Languages    * with the Firmware
* I also like to problem solve code in BASIC    * And type-in Type-Ins!

Home Computing Weekly Programs
Popular Computing Weekly Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

#### AMSDOS

#2

My next example takes that BASIC Platform Example and incorporates Ariom Sprites, resulting in ARM1PLAT.BAS & ARM2PLAT.BAS.
ARM1PLAT.BAS follows the instructions included within the Ariom Sprites programme to load the Sprite Data & Driver, however at some point I modified the file which reduced the file to 1k, Ariom Sprites can handle up to 256 Sprites and normally produces a file 9k in size.
ARM2PLAT.BAS is virtually the same, except I included a M/C loader in my programme, to show how compact using this Sprite Driver can be even after including 5 Sprites.

This is what my program looked like after using Ariom Sprites:

`100 MODE 0:BORDER 0110 DEFINT a-z120 IF PEEK(32000)=0 THEN SYMBOL AFTER 32:MEMORY 31999:LOAD"sdata",32000130 RESTORE 1210:FOR p=0 TO 9:READ i:INK p,i:NEXT p140 GOSUB 1010150 x=INT(RND*15)+5:y=3:sx=x:sy=y:CALL 32000,0,x,y:x=INT(RND*20)+1:y=5:sx2=x:sy2=y:CALL 32000,0,x,y160 x=1:y=2:c=3:d=0:CALL 32000,c,x,y170 bx=1:bc=1:bd=1:GOSUB 1160180 WHILE d=0 ' Main Game Loop190   IF INKEY(1)=0 THEN IF x<20 THEN CALL 32000,0,x,y:x=x+1:GOSUB 1130:c=3:CALL 32000,c,x,y200   IF INKEY(8)=0 THEN IF x>1 THEN CALL 32000,0,x,y:x=x-1:GOSUB 1130:c=4:CALL 32000,c,x,y210   GOSUB 1110220   CALL 32000,0,bx,4:bx=bx+bd:GOSUB 1160230   IF bx=20 THEN bd=-1:bc=2 ELSE IF bx=1 THEN bd=1:bc=1240   GOSUB 1130250   IF x=20 THEN IF y=6 THEN d=1260 WEND270 LOCATE 1,10:PEN 1:END1000 ' Draw Platforms1010 FOR y=3 TO 7 STEP 21020   FOR x=1 TO 20 1030     CALL 32000,5,x,y1040   NEXT x1050 NEXT y1060 RETURN1100 ' Check if Character is over hole1110 WHILE TEST((x-1)*32,398-(y*16))=0:CALL 32000,0,x,y:y=y+1:CALL 32000,c,x,y:CALL &BD19:WEND:RETURN1120 ' Check if Hazard has collided with Character1130 IF x=bx THEN IF y=4 THEN d=1:RETURN1140 RETURN1150 ' Move Hazard1160 CALL 32000,bc,bx,4:CALL &BD19:RETURN1200 ' Ink Data1210 DATA 0,26,11,6,26,15,2,3,10,12`

Ariom Sprites works by specifying the Sprite Number, followed by Text coordinates. If 0 is specified for the Sprite Number, the sprite is deleted, likewise printing another sprite over one will delete the old sprite.
Ariom Sprites comes with it's own 8x8 Sprite Editor (amazing since it was all in 10 Lines if you exclude the instructions), originally it was BASIC 1.1, though Nicholas Campbell has been able to get it to work in BASIC 1.0.

For a small piece of coding it's surprisingly fast, the Assembly coding itself uses no firmware, the only real limitation about it seems to be using the firmware to scroll the screen, because Ariom Sprites doesn't use the Firmware for calculating the position onscreen objects continue to appear as they roll down the screen. Ariom Sprites only works in MODE 0 as well, though larger Sprites could be built up.

* Using the old Amstrad Languages    * with the Firmware
* I also like to problem solve code in BASIC    * And type-in Type-Ins!

Home Computing Weekly Programs
Popular Computing Weekly Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

#### AMSDOS

Moving onto my next example, I've now got one working with Sean McManus' Easi-Sprite Driver.

This is the early version using Text Coordinates, however the coorinates vary slightly from standard LOCATE x,y coordinates, as a result this alters my collision test with the ground (at 1110) in my next programme, so I no longer need to subtract 1 from x, but I do need to add 1 when calculating the y coordinate, so the check is made below my character.

`100 DEFINT a-z110 IF PEEK(&9C40)=0 THEN MEMORY &44FF:LOAD"esd",&9C40:LOAD"esd1spr.add",&9D4F:LOAD"esd1spr.bnk",&4500:CALL &9C40120 MODE 0:BORDER 0130 RESTORE 1210:FOR p=0 TO 9:READ i:INK p,i:NEXT p140 GOSUB 1010150 x=INT(RND*15)+4:y=2:sx=x:sy=y:|SPRITE,5,x,y:x=INT(RND*20):y=4:sx2=x:sy2=y:|SPRITE,5,x,y160 x=0:y=1:c=3:d=0:|SPRITE,c,x,y170 bx=0:bc=1:bd=1:GOSUB 1160180 WHILE d=0 ' Main Game Loop190   IF INKEY(1)=0 THEN IF x<19 THEN |SPRITE,c,x,y:x=x+1:GOSUB 1130:c=3:|SPRITE,c,x,y200   IF INKEY(8)=0 THEN IF x>0 THEN |SPRITE,c,x,y:x=x-1:GOSUB 1130:c=4:|SPRITE,c,x,y210   GOSUB 1110220   GOSUB 1160:bx=bx+bd:GOSUB 1160230   IF bx=19 THEN |SPRITE,bc,bx,3:bd=-1:bc=2:|SPRITE,bc,bx,3 ELSE IF bx=0 THEN |SPRITE,bc,bx,3:bd=1:bc=1:|SPRITE,bc,bx,3240   GOSUB 1130250   IF x=19 THEN IF y=5 THEN d=1260 WEND270 LOCATE 1,10:PEN 1:END1000 ' Draw Platforms1010 FOR y=2 TO 6 STEP 21020   FOR x=0 TO 19 1030     |SPRITE,5,x,y1040   NEXT x1050 NEXT y1060 RETURN1100 ' Check if Character is over hole1110 WHILE TEST(x*32,398-((y+1)*16))=0:|SPRITE,c,x,y:y=y+1:|SPRITE,c,x,y:CALL &BD19:WEND:RETURN1120 ' Check if Hazard has collided with Character1130 IF x=bx THEN IF y=3 THEN |SPRITE,c,x,y:d=1:RETURN1140 RETURN1150 ' Move Hazard1160 |SPRITE,bc,bx,3:CALL &BD19:RETURN1200 ' Ink Data1210 DATA 0,26,6,3,2,11,15,18,12,10`

In appearance it's fairly much the same as the Ariom Sprites, though a bit more coding was required to have it act the same way as Ariom Sprites. Ariom Sprites simply deletes the sprite, though Easi-Sprite Driver uses Exclusive OR (XOR) mode to Print/Delete the Sprite. In order to Delete the Sprite, you simply Print the Sprite on top of itself to remove, this seem to cause some problems when my Hazard reached the ends of the screen, which forced me to alter my code on line 230.
I'm unsure if it's cost me some speed, though the programme is slightly slower than Ariom Sprites, though it maybe a contribution of things such as RSX which BASIC takes longer to intepret than a tokenised CALL, or the use of Firmware to position the Sprite. One benefit Easi-Sprite Driver has from Ariom Sprites is it's fully compatible with SCR Hardware Roll for Scrolling Objects up or down the screen.

I had some unusual experiences preparing the graphics for this version of my simple platform game:

* I seemed to be having problems using the Sprite Definer (despite having the instructions), initially, before discovering later on that it's BASIC 1.1, though I thought I was having problems with it in BASIC 1.1 as well.

* Not having access to the Sprite Definer, I was coding my own little BASIC programs to Draw the Sprites I wanted and using GRAB to capture them, which was just time consuming.

* I investigated the Sprite Definer further since I was aware of the one from the AA Covertape (from AA81), which was written for all machines and was able to quickly edit the images and use those files with my programme posted.

Using the Sprite Definer took a lot of the pressure of working out where the Sprites had to go, and the '.add' file which gets generated adds the sprite addresses, which gets stuck onto the end of ESD.

* Using the old Amstrad Languages    * with the Firmware
* I also like to problem solve code in BASIC    * And type-in Type-Ins!

Home Computing Weekly Programs
Popular Computing Weekly Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

#### AMSDOS

#4

Next I've been using Spritemaker v2.3, which is built-up with a few commands depending on a persons needs, the only thing lacking in it is the abscence of graphical positions, though as I said earlier, I'm only looking at the text coordinate based Sprite Drivers (innit surprising there's a few!).

Using Spritemaker v2.3 is much different from using Ariom Sprites or Easi-Sprite Driver, it has no editor and makes use of BASIC DATA statements to contain the Sprite Data, that is then compiled into memory by specifying the COMPILE command followed by the 1st line number and the last. With each COMPILE a Sprite Number is issued.
In next example below I've added an additional Background Graphic because now it's possible to Print Graphics over the top of Background Graphics, however what this means is I need to Compile my Moving Sprites Twice, this is so background can be stored over one of those positions and then restored back after the Sprite over the top has moved along.

`100 DEFINT a-z110 IF PEEK(&9000)=0 THEN MEMORY &7FFF:LOAD"sm.bin",&9000:CALL &9000120 MODE 0:BORDER 0:RESTORE 1210:FOR p=0 TO 9:READ i:INK p,i:NEXT p130 |CLEAR140 |COMPILE,2010,2080150 |COMPILE,2010,2080160 |COMPILE,2110,2180170 |COMPILE,2110,2180180 |COMPILE,2210,2280190 |COMPILE,2210,2280200 |COMPILE,2310,2380210 |COMPILE,2310,2380220 |COMPILE,2410,2480230 |COMPILE,2510,2580240 FOR y=1 TO 6250   FOR x=1 TO 20260     LOCATE x,y:|SPRITE,10270   NEXT x280 NEXT y290 GOSUB 1010300 x=INT(RND*15)+5:y=3:sx=x:sy=y:LOCATE x,y:|SPRITE,10:x=INT(RND*20)+1:y=5:sx2=x:sy2=y:LOCATE x,y:|SPRITE,10310 x=1:y=2:c=5:d=0:LOCATE x,y:|JAM,4:|STORE,4:|SPRITEP,c320 bx=1:bc=1:bd=1:LOCATE bx,4:|STORE,2:GOSUB 1160330 WHILE d=0 ' Main Game Loop340   IF INKEY(1)=0 THEN IF x<20 THEN LOCATE x,y:|SPRITE,4:x=x+1:GOSUB 1130:c=5:LOCATE x,y:|STORE,4:|SPRITEP,c350   IF INKEY(8)=0 THEN IF x>1 THEN LOCATE x,y:|SPRITE,4:x=x-1:GOSUB 1130:c=7:LOCATE x,y:|STORE,4:|SPRITEP,c360   GOSUB 1110370   LOCATE bx,4:|SPRITE,2:bx=bx+bd:LOCATE bx,4:|STORE,2:GOSUB 1160380   IF bx=20 THEN LOCATE bx,4:|SPRITE,2:bd=-1:bc=3:LOCATE bx,4:|STORE,2:|SPRITEP,bc ELSE IF bx=1 THEN LOCATE bx,4:|SPRITE,2:bd=1:bc=1:LOCATE bx,4:|STORE,2:|SPRITEP,bc390   GOSUB 1130400   IF x=20 THEN IF y=6 THEN d=1410 WEND420 LOCATE 1,10:PEN 1:END1000 ' Draw Platforms1010 FOR y=3 TO 7 STEP 21020   FOR x=1 TO 20 1030     LOCATE x,y:|SPRITEP,91040   NEXT x1050 NEXT y1060 RETURN1100 ' Check if Character is over hole1110 WHILE TEST((x-1)*32,398-(y*16))=0:LOCATE x,y:|SPRITE,4:y=y+1:|STORE,4:LOCATE x,y:|SPRITEP,c:CALL &BD19:WEND:RETURN1120 ' Check if Hazard has collided with Character1130 IF x=bx THEN IF y=4 THEN d=1:LOCATE bx,4:|SPRITE,4:|SPRITEP,bc:RETURN1140 RETURN1150 ' Move Hazard1160 LOCATE bx,4:|SPRITEP,bc1170 FOR p=0 TO 3:CALL &BD19:NEXT p:RETURN1200 ' Ink Data1210 DATA 0,26,11,6,18,15,2,3,10,122000 ' Sprite 1 2010 DATA 000000002020 DATA 000040002030 DATA 033331002040 DATA 003040002050 DATA 003000002060 DATA 066666002070 DATA 002220002080 DATA 000000002100 ' Sprite 32110 DATA 000000002120 DATA 000400002130 DATA 001333302140 DATA 000403002150 DATA 000003002160 DATA 006666602170 DATA 000222002180 DATA 000000002200 ' Sprite 52210 DATA 006000002220 DATA 022200002230 DATA 055550002240 DATA 511315002250 DATA 511150002260 DATA 022200002270 DATA 030300002280 DATA 030030002300 ' Sprite 72310 DATA 000006002320 DATA 000022202330 DATA 000555502340 DATA 005131152350 DATA 000511152360 DATA 000022202370 DATA 000030302380 DATA 000300302400 ' Sprite 92410 DATA 999999992420 DATA 988888892430 DATA 988888892440 DATA 988888892450 DATA 000000002460 DATA 000000002470 DATA 000000002480 DATA 000000002500 ' Sprite 102510 DATA 000000002520 DATA 077777702530 DATA 077777702540 DATA 077777702550 DATA 077777702560 DATA 077777702570 DATA 077777702580 DATA 00000000`

The result code generates quite well as well, though I had to slow things up a bit, the hazard look a bit hard to see with the background. The routine I've used for the Frame Flyback actually came from the Spritemaker article as published in ACU.

Other commands I've used here are:-

|CLEAR - this is used intially to CLEAR sprite data and variables
|SPRITE,<spr no> - this will display a sprite, along with any 0s around it.
|SPRITEP,<spr no> - as above, but removes the 0s.
|JAM,4 - is set to print sprites on top of a background.
|STORE,<spr no> - used to store background

When testing, the Sprite commands work with the BASIC Locate statement, which will work with standard firmware scrolling routine.

* Using the old Amstrad Languages    * with the Firmware
* I also like to problem solve code in BASIC    * And type-in Type-Ins!

Home Computing Weekly Programs
Popular Computing Weekly Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

#### AMSDOS

#5

The last example I have comes from the AA106 Covertape called the Spriting Back Utility. I used it back in the 90s on some demos I recently posted, however I've thrown out the rule book, though after reading about this package within the AA106 Covertape pages, it seems there was more to this package which was going to be covered in later issues, though never eventuated. I always remember AA106 taking a size reduction and that reduction only continued until AAs demise, though I guess I'll never know if this package would of been covered.

This routine also included an Editor:

though it's being a long time since I've used it. Using it now I had to go back to the AA Covertape pages just to understand the command structure which is quite long and complicated one.

So here's the code I came up with:

`100 MODE 0:BORDER 0110 DEFINT a-z120 RESTORE 130:FOR p=0 TO 9:READ i:INK p,i:NEXT p130 DATA 0,26,12,6,3,15,18,10,2,11140 IF PEEK(&A000)<>1 THEN MEMORY &8FFF:LOAD"SPRFILE.BIN",&9000:LOAD"SPRITE.BIN",&A000:CALL &A000150 FOR y=1 TO 6160   FOR x=0 TO 19170     |SPRDIS,&9600,(x*4)+1,(y*2)-1,4,2180   NEXT x190 NEXT y200 GOSUB 1010210 x=INT(RND*15)+4:y=3:|SPRDIS,&9600,(x*4)+1,(y*2)-1,4,2:x=INT(RND*20):y=5:|SPRDIS,&9600,(x*4)+1,(y*2)-1,4,2220 x=0:y=2:c=&9300:d=0:|SPRDIS,c,(x*4)+1,(y*2)-1,4,2230 bx=0:bc=&9100:bd=1:GOSUB 1210240 WHILE d=0 ' Main Game Loop250   IF INKEY(1)=0 THEN IF x<19 THEN c=&9300:|SPRDIS,&9600,(x*4)+1,(y*2)-1,4,2:x=x+1:GOSUB 1130:|SPRDIS,c,(x*4)+1,(y*2)-1,4,2260   IF INKEY(8)=0 THEN IF x>0 THEN c=&9400:|SPRDIS,&9600,(x*4)+1,(y*2)-1,4,2:x=x-1:GOSUB 1130:|SPRDIS,c,(x*4)+1,(y*2)-1,4,2270   GOSUB 1110280   |SPRDIS,&9600,(bx*4)+1,7,4,2:bx=bx+bd:GOSUB 1210290   IF bx=19 THEN bd=-1:bc=&9200 ELSE IF bx=0 THEN bd=1:bc=&9100300   GOSUB 1130310   IF x=19 THEN IF y=6 THEN d=1320 WEND330 LOCATE 1,10:PEN 1:END1000 ' Draw Platforms1010 FOR y=3 TO 7 STEP 21020   FOR x=0 TO 191030     |SPRDIS,&9500,(x*4)+1,(y*2)-1,4,21040   NEXT x1050 NEXT y1060 RETURN1100 ' Check if Character is over hole1110 WHILE TEST(x*32,398-(y*16))=0:|SPRDIS,&9600,(x*4)+1,(y*2)-1,4,2:y=y+1:|SPRDIS,c,(x*4)+1,(y*2)-1,4,2:GOSUB 1220:WEND:RETURN1120 ' Check if Hazard has collided with Character1130 IF x=bx THEN IF y=4 THEN d=1:RETURN1140 RETURN1200 ' Move Hazard1210 |SPRDIS,bc,(bx*4)+1,7,4,21220 FOR l=1 TO 3:CALL &BD19:NEXT l1230 RETURN`

So in the original AA pages, the whole idea of this Sprite Driver was to draw images in the editor with a Square around it, that Square (any pen except 0), could then be set to the same colour as the background causing the Sprite to wipe itself without any need of deleting the sprite and giving everything that smooth look.

What I found when I looked further into this package is a coordinate system which doesn't comply with either Text or Graphical coordinates, the closest thing I can see is a Sprite Table which works on a 80x50 principal. So it's almost MODE 2 with half a cursor block and that's the other funny thing about this package, when setting the height of the Sprite, a Sprite which is normally 8 bytes high becomes 2 when specifying the height. So the command to print the sprite looks like this:

To make this program work with the MODE 0 cursor, I had to come up with a new formula with X being 0 on the left side of the screen. Y seems to be the opposite with Y being 1 for the top of the screen.

Unlike what AA were doing, I've turn this into a Text coordinated based Sprite Driver, my sprites haven't got Squares around them and I'm using other graphics to clear around the moving sprites. Initially I thought I could draw sprites around other sprites like Spritemaker, though the screenshot below shows the Sprites are deleting some of the background.

Also unlike Spritemaker, a noticable blank area exists under the platform, this relates to me setting the platform height to 2 despite only being 4 pixels in height - or 1 if I use their system.

The Sprite Editor saves the sprites has an unusual way of placing them in memory. Sprites are stored &9000 onwards and every &100 bytes a new sprite is stored, allowing for only 16 Sprites stored (as mention in the AA pages), so was perhaps made to try make a simple no nonsence Sprite Driver.

Upon further tests with Firmware Scrolling Routines, I discovered this program has the same flaws as Ariom Sprites, though like Ariom Sprites works quite fast.

* Using the old Amstrad Languages    * with the Firmware
* I also like to problem solve code in BASIC    * And type-in Type-Ins!

Home Computing Weekly Programs
Popular Computing Weekly Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

#### AMSDOS

And finally an attached DSK image with Included files to go with BASIC examples:-

`* BAS1PLAT.BAS - BASIC Platform Game* BAS2PLAT.BAS - BASIC Platform Game with Transparent Mode* ARM1PLAT.BAS - BASIC Platform Game using Ariom Sprites* ARM2PLAT.BAS - As above, but single file with M/C Loader of Ariom & Sprite Data.* ESD1PLAT.BAS - BASIC Platform Game using Easi-Sprite Driver* SM1PLAT.BAS - BASIC Platform Game using Spritemaker v2.3* SBU1PLAT.BAS - BASIC Platform Game using Spriting Back Utility.`

* Using the old Amstrad Languages    * with the Firmware
* I also like to problem solve code in BASIC    * And type-in Type-Ins!

Home Computing Weekly Programs
Popular Computing Weekly Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

#### AMSDOS

I've added another Sprite Driver called "A new image" (or "CPC464 Graphics extension") to the collection, which I was playing around with a couple of years ago. It's one of the earliest Sprite Driver programs I've come across which was published in Popular Computing Weekly December 1984. Like the others it also uses Text Coordinate for positioning the Sprite, though unlike the others it's got no Sprite Editor as well as some other nasty surprises.

Some History

"A new image" was written by Brian Cadge, who is perhaps the earliest coders to bring Machine Code routines to Locomotive BASIC in the form of RSXs (Resident System Extensions). From what I can tell he wrote exclusively for Popular Computing Weekly (PCW), a fortnightly magazine which focused on many computer systems, a few of these Multiplatform magazines were floating around then though by the same publishing company I think, so Brian may have had other material in those magazines too, though from what I can tell, it seems Brian had a number of programs published within PCW.

Using these tools

In "A new image" 2 new RSX commands are installed:

`|DEFINE,<image no>,<width>,<height>|PLACE,<image no>,<xpos>,<ypos>`

DEFINE is used for grabbing an image, it works by grabbing what's in the Top Left Hand Corner of the screen and assigning a number to it. Width as usual like other Sprite Definers is measured in Bytes, so in Mode 2 a Byte is 8 pixels, Mode 1 a Byte is 4 pixels & Mode 0 has 2 pixels in a byte. The height however is measured in Blocks, so a Height of 1 is 8 pixels and so on, which differs from other Sprite Drivers.
PLACE simply draws the image to screen at xpos,ypos text coordinates. The images drawn simply fill the area, so anything in that position gets overwritten, to delete an image the best tactic is to setup a blank image and use that to clear that spot before drawing a new image in the new position.

No Sprite Designer means graphics still have to be drawn onscreen with the general idea of using DEFINE to capture them, in my case I have a simple platform game with 5 sprites and a 6th to blank that with. However, that's just one piece of the puzzle. To use "A New Image", I also need to allocate space for those Images, this is where HIMEM comes in, though for each image the HIMEM has to be Lowered by 256 bytes!

So I came up with a programme to work out all that which looks like this:

`100 MODE 0:DEFINT a-z:DIM s\$(5,64):MEMORY 41416-(7*256)110 RESTORE 120:BORDER 0:FOR p=0 TO 9:READ i:INK p,i:NEXT p120 DATA 0,26,6,3,2,11,15,18,12,10130 IF PEEK(&A1C8)<>1 THEN LOAD"ANS.BIN",&A1C8140 CALL 41416200 ' Setup Images210 |DEFINE,1,4,1220 RESTORE 2020:no=1:GOSUB 1010:|DEFINE,2,4,1:CALL &BB18230 RESTORE 2110:no=2:GOSUB 1010:|DEFINE,3,4,1:CALL &BB18240 RESTORE 2200:no=3:GOSUB 1010:|DEFINE,4,4,1:CALL &BB18250 RESTORE 2290:no=4:GOSUB 1010:|DEFINE,5,4,1:CALL &BB18260 RESTORE 2380:no=5:GOSUB 1010:|DEFINE,6,4,1:CALL &BB18270 SAVE"ANSET.BIN",B,&9AC8,&80A280 CLEAR:LOCATE 1,10:END1000 ' Plot Data to Screen - Top Left Corner1010 p1=1:x=0:y=3981020 FOR ln=1 TO 81030   READ a\$1040   FOR p=1 TO 81050     s\$(no,p1)=MID\$(a\$,p,1)1060     PLOT x,y,VAL(s\$(no,p1))1070     p1=p1+1:x=x+41080   NEXT p1090   y=y-2:x=01100 NEXT ln1110 RETURN2000 ' Sprite Data - 5 Images, Sprite 1 = Blank2010 ' Sprite 22020 DATA 000000002030 DATA 000070002040 DATA 022221002050 DATA 003070002060 DATA 003000002070 DATA 044444002080 DATA 005550002090 DATA 000000002100 ' Sprite 32110 DATA 000000002120 DATA 000700002130 DATA 001222202140 DATA 000703002150 DATA 000003002160 DATA 004444402170 DATA 000555002180 DATA 000000002190 ' Sprite 42200 DATA 004000002210 DATA 055500002220 DATA 066660002230 DATA 611216002240 DATA 611160002250 DATA 055500002260 DATA 020200002270 DATA 020020002280 ' Sprite 52290 DATA 000004002300 DATA 000055502310 DATA 000666602320 DATA 006121162330 DATA 000611162340 DATA 000055502350 DATA 000020202360 DATA 000200202370 ' Sprite 62380 DATA 888888882390 DATA 899999982400 DATA 899999982410 DATA 899999982420 DATA 000000002430 DATA 000000002440 DATA 000000002450 DATA 00000000`

This programme works by drawing each image individually top left of the screen and once each one has been drawn DEFINE stores it and CALL &BB18 waits for keypress before drawing the next image. At one stage I tested by removing the keypress routine and discovered the images weren't being correctly defined! RESTORE at the start of each line points to the data for each image to draw with a routine (1000-1110) to store that data into an array and plot the image. I'm using an array here because I need to store the image somewhere, but at the same time not store using MEMORY because I need that area for storing the final image.

Problems Encountered

One of the other interesting aspects I found out a few years ago when I first started playing around with this program, was it was written so early and set so high in memory, that it is in fact or was originally written with Cassette users in mind, fortunately PCW were also publishing the Assembly Source code back then too along with a BASIC M/C Loader programme, which with the Assembly source, makes it easier to locate to a different address. What I noticed with the original program though was a large area of space was being allocated after the Driver code, so what I did was allocate that space by subtracting it from HIMEM and that's how I came to the weird value of 41416 as a base value. From that I taken each image (including the black) and added 1 to that, which represents the 7 then multiplied by 256. After doing all that I was able to create a working program from Disk. However for those interested to see how the Images are stored in memory do a Memory Dump &9AC8 onwards and you will see a couple of lines of data, then a lot of 0s before finishing with the bytes 55,01,04 - these bytes represent the last 3 bytes of each image, which is used by A new image, scrolling down you'll see a few more, followed by some DATA which was dumped there from a Disk Catalog, how that came to get there is puzzling (because I was trying not to CAT!), but it must of been there prior to writing the images (which overwrites some of it), amazingly it doesn't interfere with the Images I've included in this programme. Though it just goes to show that when this programme was written Disks hadn't been considered.

My Test Platform Game

With the modifications in place this is what I came up with:

`100 MODE 0:DEFINT a-z:MEMORY 41415-(7*256)110 RESTORE 120:BORDER 0:FOR p=0 TO 9:READ i:INK p,i:NEXT p120 DATA 0,26,6,3,2,11,15,18,12,10130 IF PEEK(&A1C8)<>1 THEN LOAD"ANSET.BIN",&9AC8140 CALL 41416150 GOSUB 1010160 x=INT(RND*15)+5:y=3:|PLACE,1,x,y:x=INT(RND*20)+1:y=5:|PLACE,1,x,y170 x=1:y=2:c=4:d=0:|PLACE,c,x,y180 bx=1:bc=2:bd=1:GOSUB 1160190 WHILE d=0 ' Main Game Loop200   IF INKEY(1)=0 THEN IF x<20 THEN c=4:|PLACE,1,x,y:x=x+1:GOSUB 1130:|PLACE,c,x,y210   IF INKEY(8)=0 THEN IF x>1 THEN c=5:|PLACE,1,x,y:x=x-1:GOSUB 1130:|PLACE,c,x,y220   GOSUB 1110230   |PLACE,1,bx,4:bx=bx+bd:GOSUB 1160240   IF bx=20 THEN bd=-1:bc=3 ELSE IF bx=1 THEN bd=1:bc=2250   GOSUB 1130260   IF x=20 THEN IF y=6 THEN d=1270 WEND280 LOCATE 1,10:PEN 1:END1000 ' Draw Platforms1010 FOR y=3 TO 7 STEP 21020   FOR x=1 TO 201030     |PLACE,6,x,y1040   NEXT x1050 NEXT y1060 RETURN1100 ' Check if Character is over hole1110 WHILE TEST((x-1)*32,398-(y*16))=0:|PLACE,1,x,y:y=y+1:|PLACE,c,x,y:CALL &BD19:WEND:RETURN1120 ' Check if Hazard has collided with Character1130 IF x=bx THEN IF y=4 THEN d=1:RETURN1140 RETURN1150 ' Move Hazard1160 |PLACE,bc,bx,4:CALL &BD19:RETURN`

Results

Overall performance is actually very good, though I haven't slowed the code a great deal and have only got single MC FRAME FLYBACK (CALL &BD19) doing the job after modifying my earlier BASIC example to use A new image.

Pros

• Fast Multicoloured Sprites were possible in 1984!
• Assembly Source was provided in PCW
• Can be used with SCR HW ROLL to Scroll the screen.
Cons

• No Sprite Editor
• 256 bytes is used up for each image!
• Limited to 7x4 - 14x32 pixels in MODE 0
• Dumping memory revealed other garbage present prior to setting up MEMORY for sprite data.
On this new disk image are:

`ANS1PLAT.BAS - Simple BASIC Platform Game using A new imageANSPIC1 .BAS - Initially used for Drawing and storing the new imagesANSET   .BIN - Generated file from ANSPIC1.BAS with images and driver ready for useANS     .BIN - Sprite Driver in new MEMORY location to allow for Disks.`

* Using the old Amstrad Languages    * with the Firmware
* I also like to problem solve code in BASIC    * And type-in Type-Ins!

Home Computing Weekly Programs
Popular Computing Weekly Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

#### AMSDOS

#8

I thought it would be interesting to see how those Sprite Driver programmes would go when creating larger sprites. In the process its created new challenges as well as expose some setbacks while using them.

The task I've set this time is for a simple platform game with 16x16 Graphics, the characters move in double step, I haven't created any full BASIC versions this time, though all the previously used Sprite Drivers have been used again to show how they would go about creating 16x16 sprite, with the exception of "A New Image" which couldn't handle this size.

Challenges Set

• New Sprites - I wanted to create new sprites, rather than just enlarge the old ones, this itself was a challenge and as you'll see my larger graphics have a very 1984 look about them.
• The Double Step - to make the demonstration faster, this in fact also created another challenge;
• Holes in the Platform - the holes now have to be in sync with the double step movement of the character.
• Lower Hole must be offset from Upper Hole - in my earlier Platform game, the gap in the platform would occasionally follow one after another.
• Additional Scenery where supported - the Spritemaker version includes some rushes, which the Snake and your character appear behind. I could of included some in the Easi-Sprite Driver version, though the use of Exclusive OR (XOR) means the colours would clash as the scenery passes over it (which doesn't look very good).
Addressing the Holes in the Platform

To make it work in sync with the double step, each 16x16 sprite occupies 2 characters x 2 characters, the left size starting on an odd number with the right side being an even. Well that's half true because for Easi-Sprite Driver the left side begins at zero (not one), and for the Spriting Back Utility which I modified earlier to have it as a Text Coordinate Sprite Driver, my calculations convert the position of xpos into an odd value. So it seems I need a routine which returns a series of odd and even random numbers. This is how I went about it:

`10000 FOR a=1 TO 10010010   n=INT(RND*15)+410020   WHILE (n MOD 2=0)10030     n=INT(RND*15)+410040   WEND10050   PRINT n;10060 NEXT a`

This routine returns a series of random odd numbers, it works by assigning a random number, to prevent a hole appearing over my character 4 has been added to the random number (up to 15), so numbers up to 19 could be obtained. If the value obtained in 10010 is odd, then the WHILE loop at 10020 is skipped, otherwise a new random value is obtained, looking at this now, it could have just been simplified with:

`10030     n=n+1`

to make it an odd number! But may have ran into problems with my 2nd  hole, so might have done the correct thing in this case.

For even numbers it's just a matter of altering line 10020 to read:

`10020   WHILE (n MOD 2)=1)`

Checking the lower platform hole isn't the same as the upper platform hole was a simple matter of assigning two variables for the upper hole and lower hole and making sure they weren't equal the same. In my Ariom Sprite example Lines 140 & 160 deal in the placement of the lower and upper holes.

With that I'll start looking at these programmes.

* Using the old Amstrad Languages    * with the Firmware
* I also like to problem solve code in BASIC    * And type-in Type-Ins!

Home Computing Weekly Programs
Popular Computing Weekly Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

#### AMSDOS

Ariom Sprites version

`100 MODE 0:DEFINT a-z:BORDER 23:RESTORE 110:FOR p=0 TO 12:READ i:INK p,i:NEXT p110 DATA 23,6,6,3,0,0,15,18,12,10,24,0,0120 IF PEEK(32000)=0 THEN SYMBOL AFTER 32:MEMORY &7CFF:GOSUB 1210130 GOSUB 700 ' Draw Platforms140 r1=INT(RND*13)+5:WHILE (r1 MOD 2=0):r1=INT(RND*13)+5:WEND150 CALL 32000,0,r1,3:CALL 32000,0,r1+1,3160 r2=INT(RND*15):WHILE (r2 MOD 2=0) OR (r2=r1):r2=INT(RND*15):WEND170 CALL 32000,0,r2,6:CALL 32000,0,r2+1,6180 mx=1:my=1:f=1:GOSUB 1010190 bx=19:by=4:bd=-2:GOSUB 1130200 WHILE d=0 ' Main Game Loop210   IF INKEY(1)=0 THEN IF mx<19 THEN f=1:ox=mx:oy=my:GOSUB 1090:mx=mx+2:GOSUB 500:GOSUB 1010220   IF INKEY(8)=0 THEN IF mx>1 THEN f=2:ox=mx:oy=my:GOSUB 1090:mx=mx-2:GOSUB 500:GOSUB 1050230   GOSUB 600240   ox=bx:oy=by:GOSUB 1090:bx=bx+bd:IF bd=2 THEN GOSUB 1170 ELSE GOSUB 1130250   IF bx=1 THEN bd=2 ELSE IF bx=19 THEN bd=-2260   GOSUB 500270   IF mx=19 THEN IF my=7 THEN d=1280 WEND290 LOCATE 1,10:PEN 1:END500 IF mx=bx THEN IF my=by THEN d=1510 RETURN600 WHILE TEST((mx-1)*32,398-((my+1)*16))=0610   ox=mx:oy=my:GOSUB 1090620   my=my+1630   IF f=1 THEN GOSUB 1010 ELSE GOSUB 1050640   CALL &BD19650 WEND660 RETURN700 FOR y=3 TO 9 STEP 3710   FOR x=1 TO 19 STEP 2720     CALL 32000,17,x,y:CALL 32000,18,x+1,y730   NEXT x740 NEXT y750 RETURN1000 ' Draw Ranger - Facing Right1010 CALL 32000,1,mx,my:CALL 32000,2,mx+1,my1020 CALL 32000,3,mx,my+1:CALL 32000,4,mx+1,my+11030 RETURN1040 ' Draw Ranger - Facing Left1050 CALL 32000,6,mx,my:CALL 32000,5,mx+1,my1060 CALL 32000,8,mx,my+1:CALL 32000,7,mx+1,my+11070 RETURN1080 ' Delete Sprite1090 CALL 32000,0,ox,oy:CALL 32000,0,ox+1,oy1100 CALL 32000,0,ox,oy+1:CALL 32000,0,ox+1,oy+11110 RETURN1120 ' Draw Snake - Facing Right1130 CALL 32000,14,bx,by:CALL 32000,13,bx+1,by1140 CALL 32000,16,bx,by+1:CALL 32000,15,bx+1,by+11150 RETURN1160 ' Draw Snake - Facing Left1170 CALL 32000,9,bx,by:CALL 32000,10,bx+1,by1180 CALL 32000,11,bx,by+1:CALL 32000,12,bx+1,by+11190 RETURN1200 ' Ariom Sprites & Graphics1210 RESTORE 1290:addr=&7D001220 FOR ln=1 TO 391230   READ a\$1240   FOR p=1 TO 31 STEP 21250     POKE addr,VAL("&"+MID\$(a\$,p,2))1260     addr=addr+11270   NEXT p1280 NEXT ln:RETURN1290 DATA DD460411200021157D1910FDE5DD46021300 DATA 21ACBF1E041910FD1E50DD46001910FD1310 DATA D10E08E506041A77231310FAE13E08841320 DATA 670D20EFC9000044CC0000CCCCCC88CC1330 DATA CC0044CCCC00003C3C0014C0C00014C01340 DATA C00014C0C0CC880000CCCC0000CCCC441350 DATA CCCCCC88003C3C0000C4C82800C4C8941360 DATA 00C0C094000014C0C0000068C00000141370 DATA 3C000041C300000183000001430000011380 DATA 000000010091332800C09400003C28001390 DATA 00C382000083820000C30200000100001400 DATA 0000020000CC880000CCCC0000CCCC441410 DATA CCCCCC88003C3C0000C0C02800C0C0281420 DATA 00C0C02800000044CC0000CCCCCC88CC1430 DATA CC0044CCCC00003C3C0014C4C80068C41440 DATA C80068C0C0C0C02800C09400003C28001450 DATA 00C382000043020000830200000002001460 DATA 000002000000143362000068C00000141470 DATA 3C000041C300004143000001C30000001480 DATA 0200000100000011220000333300113C1490 DATA 3C0022333311001123220000330000111500 DATA 360000233300000000000011002200231510 DATA 223311131313112322331122002201221520 DATA 000014130000112322002333001136021530 DATA 001129000011162322003636130011131540 DATA 290000113300112900000136000036131550 DATA 003613280013292200293600003613001560 DATA 001300000011220000333300003C3C221570 DATA 003333110013220022330000113922001580 DATA 003313000000000000002200001113001590 DATA 112323223311132223001122330011021600 DATA 110023280011132200003313000001391610 DATA 220000162211132922233939001623221620 DATA 003322000000162200003902000023391630 DATA 000014233900111623000039160000231640 DATA 3900000023DCDC5EDCECAD8DECFCECEC1650 DATA FCDC8DFCDC00000000000000000000001660 DATA 00000000005EDC5EAD4E0FECECADDC8D1670 DATA ADDCEC5EDC0000000000000000000000`

Overview

As mentioned previously, Ariom Sprites has an 8x8 Sprite Editor, though allows up to 256 Sprites (0-255), so 16x16 sprites can be made by creating 4 Sprites to build up each Sprite, which is what I've done here. Normally Ariom Sprites creates a 9k Binary File which includes Driver & Images, though I've decided to include that information here as Machine Code.

Performance

The code runs fast enough for these large images, despite requiring more CALL commands (Lines 1000-1190), to draw the Images.

Using the Editor

Editing the images was also very good with Options to Copy the Graphics to other Sprite Numbers and also facility to Mirror the Image to create Left/Right Facing Sprites, was perhaps a little tricky where to Copy the Sprite to with Numbers being reserve (my Ranger Facing Right for example being Sprite 1 & 2 and then becoming Sprite 6 & 5 for the Left Facing side), though was sorted.

Benefits and Setbacks

Given Ariom Sprites is a 10-Liner and has those features is very good considering the other Sprite Drivers I've looked at here, don't have that.
My only niggle with the Sprite Editor is a lack of Picking which INK colours to change in the Palette, though otherwise this programme was crammed with other useful routines.

The graphics in my final version weren't totally to my satisfaction and are quite simple, I had more fun making 8x8 graphics compared to my 16x16 counterparts.

* Using the old Amstrad Languages    * with the Firmware
* I also like to problem solve code in BASIC    * And type-in Type-Ins!

Home Computing Weekly Programs
Popular Computing Weekly Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

#### AMSDOS

Easi-Sprite Driver version

`100 DEFINT a-z:BORDER 6:RESTORE 110:FOR p=0 TO 6:READ i:INK p,i:NEXT p110 DATA 0,26,12,15,10,12,3120 IF PEEK(&9C40)=0 THEN MEMORY &44FF:MODE 2:LOAD"ESD",&9C40:LOAD"ESD2SPR.ADD",&9D4F:LOAD"ESD2SPR.BNK",&4500:CALL &9C40:CALL &BB18130 MODE 0:GOSUB 700 ' Draw Platforms140 r1=INT(RND*14)+4:WHILE (r1 MOD 2=1):r1=INT(RND*14)+4:WEND150 |SPRITE,5,r1,2160 r2=INT(RND*14):WHILE (r2 MOD 2=1) OR (r2=r1):r2=INT(RND*14):WEND170 |SPRITE,5,r2,5180 mx=0:my=0:s=1:GOSUB 1010 ' Draw Ranger190 bx=18:by=3:bd=-2:n=3:GOSUB 1040200 WHILE d=0 ' Main Game Loop210   IF INKEY(1)=0 THEN IF mx<18 THEN GOSUB 1010:s=1:mx=mx+2:GOSUB 500:GOSUB 1010220   IF INKEY(8)=0 THEN IF mx>0 THEN GOSUB 1010:s=4:mx=mx-2:GOSUB 500:GOSUB 1010230   GOSUB 600 ' Check if over hole240   GOSUB 1040:bx=bx+bd:GOSUB 1040250   IF bx=18 THEN GOSUB 1040:bd=-2:n=3:GOSUB 1040 ELSE IF bx=0 THEN GOSUB 1040:n=2:bd=2:GOSUB 1040260   GOSUB 500270   IF mx=18 THEN IF my=6 THEN d=1280 WEND290 LOCATE 1,10:PEN 1:END500 IF mx=bx THEN IF my=by THEN GOSUB 1010:d=1510 RETURN600 WHILE TEST(mx*32,398-((my+2)*16))=0610   GOSUB 1010620   my=my+1630   GOSUB 1010640 WEND650 RETURN700 FOR y=2 TO 8 STEP 3710   FOR x=0 TO 18 STEP 2720     |SPRITE,5,x,y730   NEXT x740 NEXT y750 RETURN1000 ' Draw Ranger Sprite, mx = xpos, my = ypos, s = sprite number1010 CALL &BD19:|SPRITE,s,mx,my1020 RETURN1030 ' Draw Snake, bx = xpos, by = ypos, n = sprite number1040 CALL &BD19:|SPRITE,n,bx,by1050 RETURN`

Using the Editor

The Sprite Definer which accompanies Easi-Sprite Driver allows you to specify the size of the Sprite(s) you want to make, however I had to be very careful when specifying the size of a sprite initially and once a new sprite has been setup you cannot delete (unless you exit the programme and run), though it seems Sean has an option for Trimming the size of a sprite and suggests specifying a large sprite then trimming it before moving onto a new sprite. In my circumstance I made an error initially of specifying 8x16, thinking it was after the number of bytes x number of bytes, though as I discovered it created a 8 x 16 pixel image.

Benefits and Setbacks

Unlike Ariom Sprites, the Colours in the Palette can be changed, though to do that you need to go back to the Main Menu and change it there and then go back and check the Sprite. I just thought it would of been nicer if you could change the colours whilst looking at your Sprite. And when I got stuck into editing the sprites, I had no options for Copying or Mirroring an Image.

* Using the old Amstrad Languages    * with the Firmware
* I also like to problem solve code in BASIC    * And type-in Type-Ins!

Home Computing Weekly Programs
Popular Computing Weekly Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

#### AMSDOS

#11

Spritemaker version

`100 DEFINT a-z110 IF PEEK(&9000)=0 THEN MEMORY &7FFF:LOAD"sm.bin",&9000:CALL &9000:CALL &BB18120 MODE 0:BORDER 0:RESTORE 1410:FOR p=0 TO 7:READ i:INK p,i:NEXT p130 |CLEAR140 |COMPILE,2010,2160150 |COMPILE,2010,2160160 |COMPILE,2210,2360170 |COMPILE,2210,2360180 |COMPILE,2410,2560190 |COMPILE,2410,2560200 |COMPILE,2610,2760210 |COMPILE,2610,2760220 |COMPILE,2810,2840230 |COMPILE,2910,3060240 GOSUB 1010250 hx=INT(RND*13)+5:WHILE (hx MOD 2=0):hx=INT(RND*13)+5:WEND:sx=hx:LOCATE hx,3:PRINT"  ";260 hx=INT(RND*13)+5:WHILE (hx MOD 2=0) OR (hx=sx):hx=INT(RND*13)+5:WEND:LOCATE hx,7:PRINT"  ";270 sx=hx280 FOR n=1 TO INT(RND*4)+2290   px=0300   WHILE (px MOD 2=0) OR (sx=px)310     px=INT(RND*15)+3320   WEND330   LOCATE px,5340   |SPRITE,10350 NEXT n360 x=1:y=1:c=1:d=0:LOCATE x,y:|JAM,5:|STORE,2:|SPRITEP,c370 bx=19:bd=-2:bc=7:LOCATE bx,5:|STORE,8:GOSUB 1310380 WHILE d=0 ' Main Game Loop390   IF INKEY(1)=0 THEN IF x<19 THEN LOCATE x,y:|SPRITE,2:x=x+2:GOSUB 1210:c=1:LOCATE x,y:|STORE,2:|SPRITEP,c400   IF INKEY(8)=0 THEN IF x>1 THEN LOCATE x,y:|SPRITE,2:x=x-2:GOSUB 1210:c=3:LOCATE x,y:|STORE,2:|SPRITEP,c410     GOSUB 1110420     LOCATE bx,5:|SPRITE,8:bx=bx+bd:LOCATE bx,5:|STORE,8:GOSUB 1310430     IF bx=19 THEN LOCATE bx,5:|SPRITE,8:bd=-2:bc=7:LOCATE bx,5:|STORE,8:|SPRITEP,bc ELSE IF bx=1 THEN LOCATE bx,5:|SPRITE,8:bd=2:bc=5:LOCATE bx,5:|STORE,8:|SPRITEP,bc440     GOSUB 1210450     IF x=19 THEN IF y=9 THEN d=1460 WEND470 LOCATE 1,12:PEN 1:END1000 ' Draw Platforms1010 FOR y=3 TO 11 STEP 41020   FOR x=1 TO 19 STEP 2 1030     LOCATE x,y:|SPRITEP,91040   NEXT x1050 NEXT y1060 RETURN1100 ' Check if Character is over hole1110 WHILE (TEST(x*32,398-((y+1)*16))=0) AND d<>11120   LOCATE x,y:|SPRITE,21130   y=y+21140   LOCATE x,y:|STORE,21150   |SPRITEP,c1160   CALL &BD191170 WEND:GOSUB 12101180 RETURN1200 ' Check if hazard has collided with Character1210 IF x=bx THEN IF y=5 THEN d=1:LOCATE bx,5:|SPRITE,2:|SPRITEP,bc:RETURN1220 RETURN1300 ' Move Hazard1310 LOCATE bx,5:|SPRITEP,bc1320 FOR p=1 TO 2:CALL &BD19:NEXT p:RETURN1400 ' Ink Data1410 DATA 1,26,9,15,3,0,10,122000 ' Sprite 12010 DATA 00000444444000002020 DATA 00004444444400002030 DATA 44404444444404442040 DATA 00044444444440002050 DATA 00003333333300002060 DATA 00031111144130002070 DATA 00031111144113002080 DATA 00031111111113002090 DATA 00031111155530002100 DATA 00003111111300002110 DATA 00000333333000002120 DATA 00000666666000002130 DATA 00000767676000002140 DATA 00000776667000002150 DATA 00000700070000002160 DATA 00000700007000002200 ' Sprite 32210 DATA 00000444444000002220 DATA 00004444444400002230 DATA 44404444444404442240 DATA 00044444444440002250 DATA 00003333333300002260 DATA 00031441111130002270 DATA 00311441111130002280 DATA 00311111111130002290 DATA 00035551111130002300 DATA 00003111111300002310 DATA 00000333333000002320 DATA 00000666666000002330 DATA 00000676767000002340 DATA 00000766677000002350 DATA 00000070007000002360 DATA 00000700007000002400 ' Sprite 52410 DATA 00000550000000002420 DATA 00005555000005002430 DATA 00053333500057502440 DATA 00505555550575752450 DATA 05000557750557502460 DATA 50000055550550002470 DATA 00000553500750002480 DATA 00005755000375002490 DATA 00055750000537002500 DATA 00575500000753002510 DATA 05537000005375002520 DATA 05370007537530002530 DATA 05735753753750002540 DATA 00535375375300002550 DATA 00057537537500002560 DATA 00000555750000002600 ' Sprite 72610 DATA 00000000055000002620 DATA 00500000555500002630 DATA 05750005333350002640 DATA 57575055555505002650 DATA 05755057755000502660 DATA 00055055550000052670 DATA 00057005355000002680 DATA 00573000557500002690 DATA 00735000057550002700 DATA 00357000005575002710 DATA 00573500000735502720 DATA 00035735700073502730 DATA 00057357357537502740 DATA 00003573573535002750 DATA 00005735735750002760 DATA 00000057555000002800 ' Sprite 92810 DATA 66666666666666662820 DATA 64444444444444442830 DATA 64444444444444442840 DATA 64444444444444442900 ' Sprite 102910 DATA 00000000000000002920 DATA 00000000000000002930 DATA 00000000000000002940 DATA 00000000000000002950 DATA 00000000000000002960 DATA 00000000000000002970 DATA 00000000000000002980 DATA 00000000000000002990 DATA 00000000000000003000 DATA 00000000000000003010 DATA 00020002020020003020 DATA 00200020002020003030 DATA 00200020002002003040 DATA 00020200020002003050 DATA 00200020002002003060 DATA 0222222222222220`

Overview

The Spritemaker version of my 16x16 Simple Platform game threw some challenges at me. No Sprite Editor, though was simple enough to have the DATA for the sprite and work out which inks to use. In this version I added another sprite to PRINT a series of Rushes for the Snake and my character to move though, however I found a problem in the code which existed from my previous Sprite Maker programme, however in that version my Background Scenery is all over the place. The problem was occurring when my character fell onto a Rush, initially it would be present, though moving my character caused it to disappear. A check of my code revealed I'd increase my Y variable, but not use LOCATE x,y prior to |STORE,2 in the falling sequence (Lines 1100-1180). The other challenge I had was to also make sure the Rushes were placed in line with the platform as well as avoid being placed over a hole.

Setbacks

The only setbacks I can see with Spritemaker apart from being very orientated towards BASIC, is the large BASIC files created, as a result this Simple game is 5k big. The ACU article which compromises this programme does include additional programmes one for the Machine Coders to Locate each Sprite, though no information about using Spritemaker from an Assembly Programme. Michael Gledhill also points out that the suite is very Unlocatable, it maybe possible to use other Compilers (CPC BASIC 3, Hisoft Pascal, C) which support RSXs though it's dialect to incorporate within, though care would have to be taken where code was going to reside.

* Using the old Amstrad Languages    * with the Firmware
* I also like to problem solve code in BASIC    * And type-in Type-Ins!

Home Computing Weekly Programs
Popular Computing Weekly Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

#### AMSDOS

#12

Spriting Back Utility version

`100 MODE 0:BORDER 1110 DEFINT a-z120 RESTORE 130:FOR p=0 TO 9:READ i:INK p,i:NEXT p130 DATA 1,26,0,16,3,15,22,12,10,22140 IF PEEK(&A000)<>1 THEN MEMORY &8FFF:LOAD"spr16x16.bin",&9000:LOAD"sprite.bin",&A000:CALL &A000150 GOSUB 1010160 x=INT(RND*15)+4:WHILE (x MOD 2=1):x=INT(RND*15)+4:WEND:sx=x:y=3170 |SPRDIS,&9000,(x*4)+1,(y*2)-1,8,1180 x=INT(RND*15)+4:WHILE (x MOD 2=1) OR (x=sx):x=INT(RND*15)+4:WEND:y=6190 |SPRDIS,&9000,(x*4)+1,(y*2)-1,8,1200 x=0:y=1:c=&9100:d=0:|SPRDIS,c,(x*4)+1,(y*2)-1,8,4210 bx=18:bc=&9400:bd=-2:GOSUB 1210220 WHILE d=0 ' Main Game Loop230   IF INKEY(1)=0 THEN IF x<18 THEN c=&9100:|SPRDIS,&9000,(x*4)+1,(y*2)-1,8,4:x=x+2:GOSUB 1310:|SPRDIS,c,(x*4)+1,(y*2)-1,8,4240   IF INKEY(8)=0 THEN IF x>0 THEN c=&9200:|SPRDIS,&9000,(x*4)+1,(y*2)-1,8,4:x=x-2:GOSUB 1310:|SPRDIS,c,(x*4)+1,(y*2)-1,8,4250   GOSUB 1110260   |SPRDIS,&9000,(bx*4)+1,7,8,4:bx=bx+bd:GOSUB 1210270   IF bx=18 THEN bd=-2:bc=&9400 ELSE IF bx=0 THEN bd=2:bc=&9300280   GOSUB 1310290   IF x=18 THEN IF y=7 THEN d=1300 WEND310 LOCATE 1,10:PEN 1:END1000 ' Draw Platform1010 FOR y=3 TO 9 STEP 31020   FOR x=0 TO 18 STEP 21030     |SPRDIS,&9500,(x*4)+1,(y*2)-1,8,11040   NEXT x1050 NEXT y1060 RETURN1100 ' Check if Character is over hole1110 WHILE TEST(x*32,398-((y+1)*16))=01120   |SPRDIS,&9000,(x*4)+1,(y*2)-1,8,41130   y=y+11140   CALL &BD191150   |SPRDIS,c,(x*4)+1,(y*2)-1,8,41160 WEND1170 RETURN1200 ' Move Hazard1210 CALL &BD191220 |SPRDIS,bc,(bx*4)+1,7,8,41230 RETURN1300 ' Check if Hazard has collided with Character1310 IF x=bx THEN IF y=4 THEN d=1:RETURN1320 RETURN`

Problems Encountered

Using the Spriting Back Editor, it's possible to specify larger sprites, the sprite editor reserves 256 bytes for each sprite which in MODE 0 works out to be 32x16 or 16x32 Sprite, however while using the Sprite Editor I found two problems with it, which I'm unsure AA ever corrected.

Problem #1 - Compatibility problem on 464. For smaller sprites, it's not a problem, but once your sprite reaches the edge of the Red window, other machines will scroll the image along. This wasn't occurring with the 464. When I looked at the Listing I discovered the line which had the command to print the cursor had some Control Codes before it for altering the PEN colours (to allow the alternating INKs). I changed this to:

`1110 PEN#1,12:PRINT#1,CHR\$(233);`

and with that alteration, the program now works on the 464 too!

Problem #2 - This problem actually extends to all machines, and this occurs as you scroll down the screen, the pixels from a PLOT command along the ypos position are PLOTted in the wrong position. To correct that problem I had to alter the formula in line 850 so:

`850 PLOT (32+(xds+xps-1)*4),(190+(yds-yps+1)*2),x`

becomes:

`850 PLOT (32+(xds+xps-1)*4),(188-(yps+yds-2)*2),x`

save that as DEFINE and now works as it should.

Setbacks

Apart from the faults found, the editor is limited to the number of colours you can use (0-9) is all you're restricted to as well as no way of altering the colour palette, there's also no COPY or MIRROR facilities, though was only designed to be a simple Sprite Editor.

* Using the old Amstrad Languages    * with the Firmware
* I also like to problem solve code in BASIC    * And type-in Type-Ins!

Home Computing Weekly Programs
Popular Computing Weekly Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

#### AMSDOS

I've added a new DSK Image Below which just includes these new larger Sprite Examples:

`ARM3PLAT.BAS - 16x16 Example using Ariom SpritesESD2PLAT.BAS - Easi-Sprite Driver versionSBU2PLAT.BAS - Spriting Back Utility versionSM2PLAT .BAS - Spritemaker v2.3 version`

* Using the old Amstrad Languages    * with the Firmware
* I also like to problem solve code in BASIC    * And type-in Type-Ins!

Home Computing Weekly Programs
Popular Computing Weekly Programs