News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_AMSDOS

My BASIC Simple Platform Game w/ Alternative Sprite Drivers

Started by AMSDOS, 10:40, 06 November 18

Previous topic - Next topic

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,6
110 DEFINT a-z
120 SYMBOL 255,0,8,124,40,32,124,56,0:SYMBOL 254,0,16,62,20,4,62,28
130 GOSUB 1010
140 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 1160
170 WHILE d=0 ' Main Game Loop
180   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 1110
210   LOCATE bx,4:PRINT CHR$(32):bx=bx+bd:GOSUB 1160
220   IF bx=20 THEN bd=-1:bc=254 ELSE IF bx=1 THEN bd=1:bc=255
230   GOSUB 1130
240   IF x=20 THEN IF y=6 THEN d=1
250 WEND
260 LOCATE 1,10:PEN 1:END
1000 ' Draw Platforms
1010 FOR y=3 TO 7 STEP 2
1020   PEN 2:LOCATE 1,y
1030   PRINT STRING$(20,131);
1040 NEXT y
1050 RETURN
1100 ' Check if Character is over hole
1110 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:RETURN
1120 ' Check if Hazard has collided with Character
1130 IF x=bx THEN IF y=4 THEN d=1:RETURN
1140 RETURN
1150 ' Move Hazard
1160 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 :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

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

AMSDOS


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 p
110 DATA 0,18,3,11,2,26,6,15,12,10
120 DEFINT a-z
130 SYMBOL AFTER 230:GOSUB 2010
140 ton$=CHR$(22)+CHR$(1):toff$=CHR$(22)+CHR$(0)
150 GOSUB 1010
160 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 1410
180 bx=1:bc=230:bd=1:s=bc:e=235:c=1:x=bx:y=4:GOSUB 3050
190 WHILE d=0 ' Main Game Loop
200   IF INKEY(1)=0 THEN IF mx<20 THEN ms=242:me=246:c=3:GOSUB 1510:mx=mx+1:GOSUB 1210:GOSUB 1410
210   IF INKEY(8)=0 THEN IF mx>1 THEN ms=247:me=251:c=3:GOSUB 1510:mx=mx-1:GOSUB 1210:GOSUB 1410
220   GOSUB 1110
230   GOSUB 1710:bx=bx+bd:GOSUB 1610
240   IF bx=20 THEN bd=-1:bc=236 ELSE IF bx=1 THEN bd=1:bc=230
250   GOSUB 1210
260   IF mx=20 THEN IF my=6 THEN d=1
270 WEND
280 LOCATE 1,10:PRINT toff$;:PEN 1:END
1000 ' Draw Platforms
1010 FOR y=3 TO 7 STEP 2
1020   FOR x=1 TO 20
1030     s=252:e=253:c=8
1040     GOSUB 3050
1050   NEXT x
1060 NEXT y
1070 RETURN
1100 ' Check if Character is over hole
1110 WHILE TEST((mx-1)*32,398-(my*16))=0
1120   GOSUB 1510
1130   my=my+1
1140   GOSUB 1410
1150 WEND
1160 RETURN
1200 ' Check if Hazard has collided with Character
1210 IF mx=bx THEN IF my=4 THEN d=1:GOSUB 1510:GOSUB 1610:RETURN
1220 RETURN
1300 ' Transparent Mode off
1310 LOCATE 1,1:PRINT toff$;:RETURN
1400 ' Print Man
1410 s=ms:e=me:x=mx:y=my:c=3:GOSUB 3050
1420 RETURN
1500 ' Delete Man
1510 GOSUB 1310
1520 LOCATE mx,my:PRINT" ";
1530 RETURN
1600 ' Print Hazard
1610 s=bc:e=bc+5:c=1:x=bx:y=4:GOSUB 3050
1620 RETURN
1700 ' Delete Hazrd
1710 GOSUB 1310
1720 LOCATE bx,4:PRINT" ";
1730 RETURN
2000 ' Graphics
2010 SYMBOL 230,0,8,0,8,0,0,0,0   ' Pen 1
2020 SYMBOL 231,0,0,0,32,32,0,0,0 ' Pen 2
2030 SYMBOL 232,0,0,0,0,0,0,56,0  ' Pen 3
2040 SYMBOL 233,0,0,0,0,0,124,0,0 ' Pen 4
2050 SYMBOL 234,0,0,4,0,0,0,0,0   ' Pen 5
2060 SYMBOL 235,0,0,120,0,0,0,0,0 ' Pen 6
2070 SYMBOL 236,0,16,0,16,0,0,0,0 ' Pen 1
2080 SYMBOL 237,0,0,0,4,4,0,0,0   ' Pen 2
2090 SYMBOL 238,0,0,0,0,0,0,28,0  ' Pen 3
2100 SYMBOL 239,0,0,0,0,0,62,0,0  ' Pen 4
2110 SYMBOL 240,0,0,32,0,0,0,0,0  ' Pen 5
2120 SYMBOL 241,0,0,30,0,0,0,0,0  ' Pen 6
2130 SYMBOL 242,0,112,0,0,0,112,0,0   ' Pen 3
2140 SYMBOL 243,32,0,0,0,0,0,0,0      ' Pen 4
2150 SYMBOL 244,0,0,0,104,112,0,0,0   ' Pen 5
2160 SYMBOL 245,0,0,0,16,0,0,80,72    ' Pen 6
2170 SYMBOL 246,0,0,120,132,136,0,0,0 ' Pen 7
2180 SYMBOL 247,0,14,0,0,0,14,0,0  ' Pen 3
2190 SYMBOL 248,4,0,0,0,0,0,0,0    ' Pen 4
2200 SYMBOL 249,0,0,0,22,14,0,0,0  ' Pen 5
2210 SYMBOL 250,0,0,0,8,0,0,10,18  ' Pen 6
2220 SYMBOL 251,0,0,30,33,17,0,0,0 ' Pen 7
2230 SYMBOL 252,255,129,129,129,0,0,0,0 ' Pen 8
2240 SYMBOL 253,0,126,126,126,0,0,0,0   ' Pen 9
2250 RETURN
3000 ' Draw Sprites
3010 ' Entry: s = start char # of sprite
3020 '        e = end   char # of sprite
3030 '        c = colour
3040 '        x, y = xpos, ypos
3050 LOCATE 1,1:PRINT ton$;
3060 FOR i=s TO e
3070   PEN c
3080   LOCATE x,y:PRINT CHR$(i);
3090   c=c+1
3100 NEXT i
3110 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 :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

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

AMSDOS


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 0
110 DEFINT a-z
120 IF PEEK(32000)=0 THEN SYMBOL AFTER 32:MEMORY 31999:LOAD"sdata",32000
130 RESTORE 1210:FOR p=0 TO 9:READ i:INK p,i:NEXT p
140 GOSUB 1010
150 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,y
160 x=1:y=2:c=3:d=0:CALL 32000,c,x,y
170 bx=1:bc=1:bd=1:GOSUB 1160
180 WHILE d=0 ' Main Game Loop
190   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,y
200   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,y
210   GOSUB 1110
220   CALL 32000,0,bx,4:bx=bx+bd:GOSUB 1160
230   IF bx=20 THEN bd=-1:bc=2 ELSE IF bx=1 THEN bd=1:bc=1
240   GOSUB 1130
250   IF x=20 THEN IF y=6 THEN d=1
260 WEND
270 LOCATE 1,10:PEN 1:END
1000 ' Draw Platforms
1010 FOR y=3 TO 7 STEP 2
1020   FOR x=1 TO 20
1030     CALL 32000,5,x,y
1040   NEXT x
1050 NEXT y
1060 RETURN
1100 ' Check if Character is over hole
1110 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:RETURN
1120 ' Check if Hazard has collided with Character
1130 IF x=bx THEN IF y=4 THEN d=1:RETURN
1140 RETURN
1150 ' Move Hazard
1160 CALL 32000,bc,bx,4:CALL &BD19:RETURN
1200 ' Ink Data
1210 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 :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer 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-z
110 IF PEEK(&9C40)=0 THEN MEMORY &44FF:LOAD"esd",&9C40:LOAD"esd1spr.add",&9D4F:LOAD"esd1spr.bnk",&4500:CALL &9C40
120 MODE 0:BORDER 0
130 RESTORE 1210:FOR p=0 TO 9:READ i:INK p,i:NEXT p
140 GOSUB 1010
150 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,y
160 x=0:y=1:c=3:d=0:|SPRITE,c,x,y
170 bx=0:bc=1:bd=1:GOSUB 1160
180 WHILE d=0 ' Main Game Loop
190   IF INKEY(1)=0 THEN IF x<19 THEN |SPRITE,c,x,y:x=x+1:GOSUB 1130:c=3:|SPRITE,c,x,y
200   IF INKEY(8)=0 THEN IF x>0 THEN |SPRITE,c,x,y:x=x-1:GOSUB 1130:c=4:|SPRITE,c,x,y
210   GOSUB 1110
220   GOSUB 1160:bx=bx+bd:GOSUB 1160
230   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,3
240   GOSUB 1130
250   IF x=19 THEN IF y=5 THEN d=1
260 WEND
270 LOCATE 1,10:PEN 1:END
1000 ' Draw Platforms
1010 FOR y=2 TO 6 STEP 2
1020   FOR x=0 TO 19
1030     |SPRITE,5,x,y
1040   NEXT x
1050 NEXT y
1060 RETURN
1100 ' Check if Character is over hole
1110 WHILE TEST(x*32,398-((y+1)*16))=0:|SPRITE,c,x,y:y=y+1:|SPRITE,c,x,y:CALL &BD19:WEND:RETURN
1120 ' Check if Hazard has collided with Character
1130 IF x=bx THEN IF y=3 THEN |SPRITE,c,x,y:d=1:RETURN
1140 RETURN
1150 ' Move Hazard
1160 |SPRITE,bc,bx,3:CALL &BD19:RETURN
1200 ' Ink Data
1210 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 :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

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

AMSDOS


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-z
110 IF PEEK(&9000)=0 THEN MEMORY &7FFF:LOAD"sm.bin",&9000:CALL &9000
120 MODE 0:BORDER 0:RESTORE 1210:FOR p=0 TO 9:READ i:INK p,i:NEXT p
130 |CLEAR
140 |COMPILE,2010,2080
150 |COMPILE,2010,2080
160 |COMPILE,2110,2180
170 |COMPILE,2110,2180
180 |COMPILE,2210,2280
190 |COMPILE,2210,2280
200 |COMPILE,2310,2380
210 |COMPILE,2310,2380
220 |COMPILE,2410,2480
230 |COMPILE,2510,2580
240 FOR y=1 TO 6
250   FOR x=1 TO 20
260     LOCATE x,y:|SPRITE,10
270   NEXT x
280 NEXT y
290 GOSUB 1010
300 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,10
310 x=1:y=2:c=5:d=0:LOCATE x,y:|JAM,4:|STORE,4:|SPRITEP,c
320 bx=1:bc=1:bd=1:LOCATE bx,4:|STORE,2:GOSUB 1160
330 WHILE d=0 ' Main Game Loop
340   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,c
350   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,c
360   GOSUB 1110
370   LOCATE bx,4:|SPRITE,2:bx=bx+bd:LOCATE bx,4:|STORE,2:GOSUB 1160
380   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,bc
390   GOSUB 1130
400   IF x=20 THEN IF y=6 THEN d=1
410 WEND
420 LOCATE 1,10:PEN 1:END
1000 ' Draw Platforms
1010 FOR y=3 TO 7 STEP 2
1020   FOR x=1 TO 20
1030     LOCATE x,y:|SPRITEP,9
1040   NEXT x
1050 NEXT y
1060 RETURN
1100 ' Check if Character is over hole
1110 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:RETURN
1120 ' Check if Hazard has collided with Character
1130 IF x=bx THEN IF y=4 THEN d=1:LOCATE bx,4:|SPRITE,4:|SPRITEP,bc:RETURN
1140 RETURN
1150 ' Move Hazard
1160 LOCATE bx,4:|SPRITEP,bc
1170 FOR p=0 TO 3:CALL &BD19:NEXT p:RETURN
1200 ' Ink Data
1210 DATA 0,26,11,6,18,15,2,3,10,12
2000 ' Sprite 1
2010 DATA 00000000
2020 DATA 00004000
2030 DATA 03333100
2040 DATA 00304000
2050 DATA 00300000
2060 DATA 06666600
2070 DATA 00222000
2080 DATA 00000000
2100 ' Sprite 3
2110 DATA 00000000
2120 DATA 00040000
2130 DATA 00133330
2140 DATA 00040300
2150 DATA 00000300
2160 DATA 00666660
2170 DATA 00022200
2180 DATA 00000000
2200 ' Sprite 5
2210 DATA 00600000
2220 DATA 02220000
2230 DATA 05555000
2240 DATA 51131500
2250 DATA 51115000
2260 DATA 02220000
2270 DATA 03030000
2280 DATA 03003000
2300 ' Sprite 7
2310 DATA 00000600
2320 DATA 00002220
2330 DATA 00055550
2340 DATA 00513115
2350 DATA 00051115
2360 DATA 00002220
2370 DATA 00003030
2380 DATA 00030030
2400 ' Sprite 9
2410 DATA 99999999
2420 DATA 98888889
2430 DATA 98888889
2440 DATA 98888889
2450 DATA 00000000
2460 DATA 00000000
2470 DATA 00000000
2480 DATA 00000000
2500 ' Sprite 10
2510 DATA 00000000
2520 DATA 07777770
2530 DATA 07777770
2540 DATA 07777770
2550 DATA 07777770
2560 DATA 07777770
2570 DATA 07777770
2580 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 :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

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

AMSDOS


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 0
110 DEFINT a-z
120 RESTORE 130:FOR p=0 TO 9:READ i:INK p,i:NEXT p
130 DATA 0,26,12,6,3,15,18,10,2,11
140 IF PEEK(&A000)<>1 THEN MEMORY &8FFF:LOAD"SPRFILE.BIN",&9000:LOAD"SPRITE.BIN",&A000:CALL &A000
150 FOR y=1 TO 6
160   FOR x=0 TO 19
170     |SPRDIS,&9600,(x*4)+1,(y*2)-1,4,2
180   NEXT x
190 NEXT y
200 GOSUB 1010
210 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,2
220 x=0:y=2:c=&9300:d=0:|SPRDIS,c,(x*4)+1,(y*2)-1,4,2
230 bx=0:bc=&9100:bd=1:GOSUB 1210
240 WHILE d=0 ' Main Game Loop
250   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,2
260   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,2
270   GOSUB 1110
280   |SPRDIS,&9600,(bx*4)+1,7,4,2:bx=bx+bd:GOSUB 1210
290   IF bx=19 THEN bd=-1:bc=&9200 ELSE IF bx=0 THEN bd=1:bc=&9100
300   GOSUB 1130
310   IF x=19 THEN IF y=6 THEN d=1
320 WEND
330 LOCATE 1,10:PEN 1:END
1000 ' Draw Platforms
1010 FOR y=3 TO 7 STEP 2
1020   FOR x=0 TO 19
1030     |SPRDIS,&9500,(x*4)+1,(y*2)-1,4,2
1040   NEXT x
1050 NEXT y
1060 RETURN
1100 ' Check if Character is over hole
1110 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:RETURN
1120 ' Check if Hazard has collided with Character
1130 IF x=bx THEN IF y=4 THEN d=1:RETURN
1140 RETURN
1200 ' Move Hazard
1210 |SPRDIS,bc,(bx*4)+1,7,4,2
1220 FOR l=1 TO 3:CALL &BD19:NEXT l
1230 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:


SPRDIS,<sprite addr>,<x>,<y>,<width>,<height>


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 :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer 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 :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer 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 p
120 DATA 0,26,6,3,2,11,15,18,12,10
130 IF PEEK(&A1C8)<>1 THEN LOAD"ANS.BIN",&A1C8
140 CALL 41416
200 ' Setup Images
210 |DEFINE,1,4,1
220 RESTORE 2020:no=1:GOSUB 1010:|DEFINE,2,4,1:CALL &BB18
230 RESTORE 2110:no=2:GOSUB 1010:|DEFINE,3,4,1:CALL &BB18
240 RESTORE 2200:no=3:GOSUB 1010:|DEFINE,4,4,1:CALL &BB18
250 RESTORE 2290:no=4:GOSUB 1010:|DEFINE,5,4,1:CALL &BB18
260 RESTORE 2380:no=5:GOSUB 1010:|DEFINE,6,4,1:CALL &BB18
270 SAVE"ANSET.BIN",B,&9AC8,&80A
280 CLEAR:LOCATE 1,10:END
1000 ' Plot Data to Screen - Top Left Corner
1010 p1=1:x=0:y=398
1020 FOR ln=1 TO 8
1030   READ a$
1040   FOR p=1 TO 8
1050     s$(no,p1)=MID$(a$,p,1)
1060     PLOT x,y,VAL(s$(no,p1))
1070     p1=p1+1:x=x+4
1080   NEXT p
1090   y=y-2:x=0
1100 NEXT ln
1110 RETURN
2000 ' Sprite Data - 5 Images, Sprite 1 = Blank
2010 ' Sprite 2
2020 DATA 00000000
2030 DATA 00007000
2040 DATA 02222100
2050 DATA 00307000
2060 DATA 00300000
2070 DATA 04444400
2080 DATA 00555000
2090 DATA 00000000
2100 ' Sprite 3
2110 DATA 00000000
2120 DATA 00070000
2130 DATA 00122220
2140 DATA 00070300
2150 DATA 00000300
2160 DATA 00444440
2170 DATA 00055500
2180 DATA 00000000
2190 ' Sprite 4
2200 DATA 00400000
2210 DATA 05550000
2220 DATA 06666000
2230 DATA 61121600
2240 DATA 61116000
2250 DATA 05550000
2260 DATA 02020000
2270 DATA 02002000
2280 ' Sprite 5
2290 DATA 00000400
2300 DATA 00005550
2310 DATA 00066660
2320 DATA 00612116
2330 DATA 00061116
2340 DATA 00005550
2350 DATA 00002020
2360 DATA 00020020
2370 ' Sprite 6
2380 DATA 88888888
2390 DATA 89999998
2400 DATA 89999998
2410 DATA 89999998
2420 DATA 00000000
2430 DATA 00000000
2440 DATA 00000000
2450 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 p
120 DATA 0,26,6,3,2,11,15,18,12,10
130 IF PEEK(&A1C8)<>1 THEN LOAD"ANSET.BIN",&9AC8
140 CALL 41416
150 GOSUB 1010
160 x=INT(RND*15)+5:y=3:|PLACE,1,x,y:x=INT(RND*20)+1:y=5:|PLACE,1,x,y
170 x=1:y=2:c=4:d=0:|PLACE,c,x,y
180 bx=1:bc=2:bd=1:GOSUB 1160
190 WHILE d=0 ' Main Game Loop
200   IF INKEY(1)=0 THEN IF x<20 THEN c=4:|PLACE,1,x,y:x=x+1:GOSUB 1130:|PLACE,c,x,y
210   IF INKEY(8)=0 THEN IF x>1 THEN c=5:|PLACE,1,x,y:x=x-1:GOSUB 1130:|PLACE,c,x,y
220   GOSUB 1110
230   |PLACE,1,bx,4:bx=bx+bd:GOSUB 1160
240   IF bx=20 THEN bd=-1:bc=3 ELSE IF bx=1 THEN bd=1:bc=2
250   GOSUB 1130
260   IF x=20 THEN IF y=6 THEN d=1
270 WEND
280 LOCATE 1,10:PEN 1:END
1000 ' Draw Platforms
1010 FOR y=3 TO 7 STEP 2
1020   FOR x=1 TO 20
1030     |PLACE,6,x,y
1040   NEXT x
1050 NEXT y
1060 RETURN
1100 ' Check if Character is over hole
1110 WHILE TEST((x-1)*32,398-(y*16))=0:|PLACE,1,x,y:y=y+1:|PLACE,c,x,y:CALL &BD19:WEND:RETURN
1120 ' Check if Hazard has collided with Character
1130 IF x=bx THEN IF y=4 THEN d=1:RETURN
1140 RETURN
1150 ' Move Hazard
1160 |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 image
ANSPIC1 .BAS - Initially used for Drawing and storing the new images
ANSET   .BIN - Generated file from ANSPIC1.BAS with images and driver ready for use
ANS     .BIN - Sprite Driver in new MEMORY location to allow for Disks.
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

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

AMSDOS


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 100
10010   n=INT(RND*15)+4
10020   WHILE (n MOD 2=0)
10030     n=INT(RND*15)+4
10040   WEND
10050   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 :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer 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 p
110 DATA 23,6,6,3,0,0,15,18,12,10,24,0,0
120 IF PEEK(32000)=0 THEN SYMBOL AFTER 32:MEMORY &7CFF:GOSUB 1210
130 GOSUB 700 ' Draw Platforms
140 r1=INT(RND*13)+5:WHILE (r1 MOD 2=0):r1=INT(RND*13)+5:WEND
150 CALL 32000,0,r1,3:CALL 32000,0,r1+1,3
160 r2=INT(RND*15):WHILE (r2 MOD 2=0) OR (r2=r1):r2=INT(RND*15):WEND
170 CALL 32000,0,r2,6:CALL 32000,0,r2+1,6
180 mx=1:my=1:f=1:GOSUB 1010
190 bx=19:by=4:bd=-2:GOSUB 1130
200 WHILE d=0 ' Main Game Loop
210   IF INKEY(1)=0 THEN IF mx<19 THEN f=1:ox=mx:oy=my:GOSUB 1090:mx=mx+2:GOSUB 500:GOSUB 1010
220   IF INKEY(8)=0 THEN IF mx>1 THEN f=2:ox=mx:oy=my:GOSUB 1090:mx=mx-2:GOSUB 500:GOSUB 1050
230   GOSUB 600
240   ox=bx:oy=by:GOSUB 1090:bx=bx+bd:IF bd=2 THEN GOSUB 1170 ELSE GOSUB 1130
250   IF bx=1 THEN bd=2 ELSE IF bx=19 THEN bd=-2
260   GOSUB 500
270   IF mx=19 THEN IF my=7 THEN d=1
280 WEND
290 LOCATE 1,10:PEN 1:END
500 IF mx=bx THEN IF my=by THEN d=1
510 RETURN
600 WHILE TEST((mx-1)*32,398-((my+1)*16))=0
610   ox=mx:oy=my:GOSUB 1090
620   my=my+1
630   IF f=1 THEN GOSUB 1010 ELSE GOSUB 1050
640   CALL &BD19
650 WEND
660 RETURN
700 FOR y=3 TO 9 STEP 3
710   FOR x=1 TO 19 STEP 2
720     CALL 32000,17,x,y:CALL 32000,18,x+1,y
730   NEXT x
740 NEXT y
750 RETURN
1000 ' Draw Ranger - Facing Right
1010 CALL 32000,1,mx,my:CALL 32000,2,mx+1,my
1020 CALL 32000,3,mx,my+1:CALL 32000,4,mx+1,my+1
1030 RETURN
1040 ' Draw Ranger - Facing Left
1050 CALL 32000,6,mx,my:CALL 32000,5,mx+1,my
1060 CALL 32000,8,mx,my+1:CALL 32000,7,mx+1,my+1
1070 RETURN
1080 ' Delete Sprite
1090 CALL 32000,0,ox,oy:CALL 32000,0,ox+1,oy
1100 CALL 32000,0,ox,oy+1:CALL 32000,0,ox+1,oy+1
1110 RETURN
1120 ' Draw Snake - Facing Right
1130 CALL 32000,14,bx,by:CALL 32000,13,bx+1,by
1140 CALL 32000,16,bx,by+1:CALL 32000,15,bx+1,by+1
1150 RETURN
1160 ' Draw Snake - Facing Left
1170 CALL 32000,9,bx,by:CALL 32000,10,bx+1,by
1180 CALL 32000,11,bx,by+1:CALL 32000,12,bx+1,by+1
1190 RETURN
1200 ' Ariom Sprites & Graphics
1210 RESTORE 1290:addr=&7D00
1220 FOR ln=1 TO 39
1230   READ a$
1240   FOR p=1 TO 31 STEP 2
1250     POKE addr,VAL("&"+MID$(a$,p,2))
1260     addr=addr+1
1270   NEXT p
1280 NEXT ln:RETURN
1290 DATA DD460411200021157D1910FDE5DD4602
1300 DATA 21ACBF1E041910FD1E50DD46001910FD
1310 DATA D10E08E506041A77231310FAE13E0884
1320 DATA 670D20EFC9000044CC0000CCCCCC88CC
1330 DATA CC0044CCCC00003C3C0014C0C00014C0
1340 DATA C00014C0C0CC880000CCCC0000CCCC44
1350 DATA CCCCCC88003C3C0000C4C82800C4C894
1360 DATA 00C0C094000014C0C0000068C0000014
1370 DATA 3C000041C30000018300000143000001
1380 DATA 000000010091332800C09400003C2800
1390 DATA 00C382000083820000C3020000010000
1400 DATA 0000020000CC880000CCCC0000CCCC44
1410 DATA CCCCCC88003C3C0000C0C02800C0C028
1420 DATA 00C0C02800000044CC0000CCCCCC88CC
1430 DATA CC0044CCCC00003C3C0014C4C80068C4
1440 DATA C80068C0C0C0C02800C09400003C2800
1450 DATA 00C38200004302000083020000000200
1460 DATA 000002000000143362000068C0000014
1470 DATA 3C000041C300004143000001C3000000
1480 DATA 0200000100000011220000333300113C
1490 DATA 3C002233331100112322000033000011
1500 DATA 36000023330000000000001100220023
1510 DATA 22331113131311232233112200220122
1520 DATA 00001413000011232200233300113602
1530 DATA 00112900001116232200363613001113
1540 DATA 29000011330011290000013600003613
1550 DATA 00361328001329220029360000361300
1560 DATA 001300000011220000333300003C3C22
1570 DATA 00333311001322002233000011392200
1580 DATA 00331300000000000000220000111300
1590 DATA 11232322331113222300112233001102
1600 DATA 11002328001113220000331300000139
1610 DATA 22000016221113292223393900162322
1620 DATA 00332200000016220000390200002339
1630 DATA 00001423390011162300003916000023
1640 DATA 3900000023DCDC5EDCECAD8DECFCECEC
1650 DATA FCDC8DFCDC0000000000000000000000
1660 DATA 00000000005EDC5EAD4E0FECECADDC8D
1670 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 :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer 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 p
110 DATA 0,26,12,15,10,12,3
120 IF PEEK(&9C40)=0 THEN MEMORY &44FF:MODE 2:LOAD"ESD",&9C40:LOAD"ESD2SPR.ADD",&9D4F:LOAD"ESD2SPR.BNK",&4500:CALL &9C40:CALL &BB18
130 MODE 0:GOSUB 700 ' Draw Platforms
140 r1=INT(RND*14)+4:WHILE (r1 MOD 2=1):r1=INT(RND*14)+4:WEND
150 |SPRITE,5,r1,2
160 r2=INT(RND*14):WHILE (r2 MOD 2=1) OR (r2=r1):r2=INT(RND*14):WEND
170 |SPRITE,5,r2,5
180 mx=0:my=0:s=1:GOSUB 1010 ' Draw Ranger
190 bx=18:by=3:bd=-2:n=3:GOSUB 1040
200 WHILE d=0 ' Main Game Loop
210   IF INKEY(1)=0 THEN IF mx<18 THEN GOSUB 1010:s=1:mx=mx+2:GOSUB 500:GOSUB 1010
220   IF INKEY(8)=0 THEN IF mx>0 THEN GOSUB 1010:s=4:mx=mx-2:GOSUB 500:GOSUB 1010
230   GOSUB 600 ' Check if over hole
240   GOSUB 1040:bx=bx+bd:GOSUB 1040
250   IF bx=18 THEN GOSUB 1040:bd=-2:n=3:GOSUB 1040 ELSE IF bx=0 THEN GOSUB 1040:n=2:bd=2:GOSUB 1040
260   GOSUB 500
270   IF mx=18 THEN IF my=6 THEN d=1
280 WEND
290 LOCATE 1,10:PEN 1:END
500 IF mx=bx THEN IF my=by THEN GOSUB 1010:d=1
510 RETURN
600 WHILE TEST(mx*32,398-((my+2)*16))=0
610   GOSUB 1010
620   my=my+1
630   GOSUB 1010
640 WEND
650 RETURN
700 FOR y=2 TO 8 STEP 3
710   FOR x=0 TO 18 STEP 2
720     |SPRITE,5,x,y
730   NEXT x
740 NEXT y
750 RETURN
1000 ' Draw Ranger Sprite, mx = xpos, my = ypos, s = sprite number
1010 CALL &BD19:|SPRITE,s,mx,my
1020 RETURN
1030 ' Draw Snake, bx = xpos, by = ypos, n = sprite number
1040 CALL &BD19:|SPRITE,n,bx,by
1050 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 :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

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

AMSDOS


Spritemaker version




100 DEFINT a-z
110 IF PEEK(&9000)=0 THEN MEMORY &7FFF:LOAD"sm.bin",&9000:CALL &9000:CALL &BB18
120 MODE 0:BORDER 0:RESTORE 1410:FOR p=0 TO 7:READ i:INK p,i:NEXT p
130 |CLEAR
140 |COMPILE,2010,2160
150 |COMPILE,2010,2160
160 |COMPILE,2210,2360
170 |COMPILE,2210,2360
180 |COMPILE,2410,2560
190 |COMPILE,2410,2560
200 |COMPILE,2610,2760
210 |COMPILE,2610,2760
220 |COMPILE,2810,2840
230 |COMPILE,2910,3060
240 GOSUB 1010
250 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=hx
280 FOR n=1 TO INT(RND*4)+2
290   px=0
300   WHILE (px MOD 2=0) OR (sx=px)
310     px=INT(RND*15)+3
320   WEND
330   LOCATE px,5
340   |SPRITE,10
350 NEXT n
360 x=1:y=1:c=1:d=0:LOCATE x,y:|JAM,5:|STORE,2:|SPRITEP,c
370 bx=19:bd=-2:bc=7:LOCATE bx,5:|STORE,8:GOSUB 1310
380 WHILE d=0 ' Main Game Loop
390   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,c
400   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,c
410     GOSUB 1110
420     LOCATE bx,5:|SPRITE,8:bx=bx+bd:LOCATE bx,5:|STORE,8:GOSUB 1310
430     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,bc
440     GOSUB 1210
450     IF x=19 THEN IF y=9 THEN d=1
460 WEND
470 LOCATE 1,12:PEN 1:END
1000 ' Draw Platforms
1010 FOR y=3 TO 11 STEP 4
1020   FOR x=1 TO 19 STEP 2
1030     LOCATE x,y:|SPRITEP,9
1040   NEXT x
1050 NEXT y
1060 RETURN
1100 ' Check if Character is over hole
1110 WHILE (TEST(x*32,398-((y+1)*16))=0) AND d<>1
1120   LOCATE x,y:|SPRITE,2
1130   y=y+2
1140   LOCATE x,y:|STORE,2
1150   |SPRITEP,c
1160   CALL &BD19
1170 WEND:GOSUB 1210
1180 RETURN
1200 ' Check if hazard has collided with Character
1210 IF x=bx THEN IF y=5 THEN d=1:LOCATE bx,5:|SPRITE,2:|SPRITEP,bc:RETURN
1220 RETURN
1300 ' Move Hazard
1310 LOCATE bx,5:|SPRITEP,bc
1320 FOR p=1 TO 2:CALL &BD19:NEXT p:RETURN
1400 ' Ink Data
1410 DATA 1,26,9,15,3,0,10,12
2000 ' Sprite 1
2010 DATA 0000044444400000
2020 DATA 0000444444440000
2030 DATA 4440444444440444
2040 DATA 0004444444444000
2050 DATA 0000333333330000
2060 DATA 0003111114413000
2070 DATA 0003111114411300
2080 DATA 0003111111111300
2090 DATA 0003111115553000
2100 DATA 0000311111130000
2110 DATA 0000033333300000
2120 DATA 0000066666600000
2130 DATA 0000076767600000
2140 DATA 0000077666700000
2150 DATA 0000070007000000
2160 DATA 0000070000700000
2200 ' Sprite 3
2210 DATA 0000044444400000
2220 DATA 0000444444440000
2230 DATA 4440444444440444
2240 DATA 0004444444444000
2250 DATA 0000333333330000
2260 DATA 0003144111113000
2270 DATA 0031144111113000
2280 DATA 0031111111113000
2290 DATA 0003555111113000
2300 DATA 0000311111130000
2310 DATA 0000033333300000
2320 DATA 0000066666600000
2330 DATA 0000067676700000
2340 DATA 0000076667700000
2350 DATA 0000007000700000
2360 DATA 0000070000700000
2400 ' Sprite 5
2410 DATA 0000055000000000
2420 DATA 0000555500000500
2430 DATA 0005333350005750
2440 DATA 0050555555057575
2450 DATA 0500055775055750
2460 DATA 5000005555055000
2470 DATA 0000055350075000
2480 DATA 0000575500037500
2490 DATA 0005575000053700
2500 DATA 0057550000075300
2510 DATA 0553700000537500
2520 DATA 0537000753753000
2530 DATA 0573575375375000
2540 DATA 0053537537530000
2550 DATA 0005753753750000
2560 DATA 0000055575000000
2600 ' Sprite 7
2610 DATA 0000000005500000
2620 DATA 0050000055550000
2630 DATA 0575000533335000
2640 DATA 5757505555550500
2650 DATA 0575505775500050
2660 DATA 0005505555000005
2670 DATA 0005700535500000
2680 DATA 0057300055750000
2690 DATA 0073500005755000
2700 DATA 0035700000557500
2710 DATA 0057350000073550
2720 DATA 0003573570007350
2730 DATA 0005735735753750
2740 DATA 0000357357353500
2750 DATA 0000573573575000
2760 DATA 0000005755500000
2800 ' Sprite 9
2810 DATA 6666666666666666
2820 DATA 6444444444444444
2830 DATA 6444444444444444
2840 DATA 6444444444444444
2900 ' Sprite 10
2910 DATA 0000000000000000
2920 DATA 0000000000000000
2930 DATA 0000000000000000
2940 DATA 0000000000000000
2950 DATA 0000000000000000
2960 DATA 0000000000000000
2970 DATA 0000000000000000
2980 DATA 0000000000000000
2990 DATA 0000000000000000
3000 DATA 0000000000000000
3010 DATA 0002000202002000
3020 DATA 0020002000202000
3030 DATA 0020002000200200
3040 DATA 0002020002000200
3050 DATA 0020002000200200
3060 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 :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

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

AMSDOS


Spriting Back Utility version




100 MODE 0:BORDER 1
110 DEFINT a-z
120 RESTORE 130:FOR p=0 TO 9:READ i:INK p,i:NEXT p
130 DATA 1,26,0,16,3,15,22,12,10,22
140 IF PEEK(&A000)<>1 THEN MEMORY &8FFF:LOAD"spr16x16.bin",&9000:LOAD"sprite.bin",&A000:CALL &A000
150 GOSUB 1010
160 x=INT(RND*15)+4:WHILE (x MOD 2=1):x=INT(RND*15)+4:WEND:sx=x:y=3
170 |SPRDIS,&9000,(x*4)+1,(y*2)-1,8,1
180 x=INT(RND*15)+4:WHILE (x MOD 2=1) OR (x=sx):x=INT(RND*15)+4:WEND:y=6
190 |SPRDIS,&9000,(x*4)+1,(y*2)-1,8,1
200 x=0:y=1:c=&9100:d=0:|SPRDIS,c,(x*4)+1,(y*2)-1,8,4
210 bx=18:bc=&9400:bd=-2:GOSUB 1210
220 WHILE d=0 ' Main Game Loop
230   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,4
240   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,4
250   GOSUB 1110
260   |SPRDIS,&9000,(bx*4)+1,7,8,4:bx=bx+bd:GOSUB 1210
270   IF bx=18 THEN bd=-2:bc=&9400 ELSE IF bx=0 THEN bd=2:bc=&9300
280   GOSUB 1310
290   IF x=18 THEN IF y=7 THEN d=1
300 WEND
310 LOCATE 1,10:PEN 1:END
1000 ' Draw Platform
1010 FOR y=3 TO 9 STEP 3
1020   FOR x=0 TO 18 STEP 2
1030     |SPRDIS,&9500,(x*4)+1,(y*2)-1,8,1
1040   NEXT x
1050 NEXT y
1060 RETURN
1100 ' Check if Character is over hole
1110 WHILE TEST(x*32,398-((y+1)*16))=0
1120   |SPRDIS,&9000,(x*4)+1,(y*2)-1,8,4
1130   y=y+1
1140   CALL &BD19
1150   |SPRDIS,c,(x*4)+1,(y*2)-1,8,4
1160 WEND
1170 RETURN
1200 ' Move Hazard
1210 CALL &BD19
1220 |SPRDIS,bc,(bx*4)+1,7,8,4
1230 RETURN
1300 ' Check if Hazard has collided with Character
1310 IF x=bx THEN IF y=4 THEN d=1:RETURN
1320 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 :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer 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 Sprites
ESD2PLAT.BAS - Easi-Sprite Driver version
SBU2PLAT.BAS - Spriting Back Utility version
SM2PLAT .BAS - Spritemaker v2.3 version
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

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

Powered by SMFPacks Menu Editor Mod