News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_AMSDOS

Dodging Obstacles in BASIC and Assembly

Started by AMSDOS, 10:23, 18 April 18

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

AMSDOS

The other week, I constructed a simple BASIC game of Dodging the Rocket around the Grumpy faces, which I thought worked quite nicely.



10 MODE 0:DEFINT a-z:INK 0,11:INK 1,26:BORDER 11:PEN 1
20 RANDOMISE TIME:RANDOMIZE RND
30 FOR a=1 TO 25
40   x=INT(RND*20)+1
50   LOCATE x,1
60   PRINT CHR$(225)
61   GOSUB 1000
70 NEXT a
80 x=10:y=12:PEN 3:LOCATE x,y:PRINT CHR$(239)
90 d=1
100 WHILE d=1
101   IF INKEY(1)=0 THEN IF x<20 THEN LOCATE x,y:PRINT" ":x=x+1:LOCATE x,y:PEN 3:PRINT CHR$(239)
102   IF INKEY(=0 THEN IF x>1 THEN LOCATE x,y:PRINT" ":x=x-1:LOCATE x,y:PEN 3:PRINT CHR$(239)
110   ax=INT(RND*20)+1
120   LOCATE ax,1:PEN 1
130   PRINT CHR$(225)
135   IF TEST((x-1)*32+4,238)=1 THEN d=0
140   LOCATE x,y:PRINT" "
150   GOSUB 1000
160   LOCATE x,y:PEN 3:PRINT CHR$(239)
170 WEND
180 END
1000 LOCATE 1,1:PRINT CHR$(11)
1010 RETURN




The aim of this simple game was to write something similar in Assembly and thought it would make a good demonstration of coding in Assembly and make use of some Collision Detection code I recently wrote.


Though when I tried to do the same thing with my Rocket in Assembly, it looked as if the Rocket didn't have time to display itself, so I ended up with this, so it looks like there's 2 Rockets onscreen. It appears the Scroll routine I'm using here is very slow too, which makes use of SCR SW ROLL. My BASIC version seems to be kicking the Assembly versions butt.






   org &8000


   ld a,0
   call &bc0e


   call genseed


   ld a,1
   call &bb90


   ld b,24


.drawobstacles
   push bc
   call rand
   call scalenum
   ld a,(result)
   ld h,a
   ld l,1
   call &bb75
   ld a,225
   call &bb5a
   call scroll
   pop bc
   djnz drawobstacles


   call printrocket


.maingame


   call scroll


   ld hl,(ypos2)
   call &bb75
   ld a,32
   call &bb5a


   call printrocket


   call updateobstacle


   call collision


   ld a,(dead)
   cp 0
   jr z,skip


   ld a,1
   call &bb1e
   jr z,checkleft


   ld a,(xpos)
   cp 16
   jr z,checkleft
   inc a
   ld (xpos),a
   ld (xpos2),a


   call removerocket


   call printrocket


   ld a,(xpos)
   ld (ox),a


   ld hl,(ex)
   ld de,32
   add hl,de
   ld (ex),hl


.checkleft
   ld a,8
   call &bb1e
   jr z,skip


   ld a,(xpos)
   cp 1
   jr z,skip
   dec a
   ld (xpos),a
   ld (xpos2),a


   call removerocket
   
   call printrocket


   ld a,(xpos)
   ld (ox),a


   ld hl,(ex)
   ld de,32
   and a
   sbc hl,de
   ld (ex),hl


.skip   ld a,(dead)
   and a
   jr nz,maingame


   ld a,(dead)
   inc a
   ld (dead),a


   ret         ;; Return to BASIC


.removerocket
   ld hl,(oy)
   call &bb75
   ld a,32
   call &bb5a
   ret
.printrocket
   ld hl,(ypos)
   call &bb75
   ld a,3
   call &bb90
   ld a,239
   call &bb5a
   ret   


.updaterocket
   ld hl,(ypos)
   call &bb75
   ld a,32
   call &bb5a
   call scroll
   ld hl,(ypos)
   call &bb75
   ld a,3
   call &bb90
   ld a,239
   call &bb5a
   call updateobstacle
   ret


.updateobstacle
   call rand
   call scalenum
   ld a,(result)
   ld h,a
   ld l,1
   call &bb75
   ld a,1
   call &bb90
   ld a,225
   call &bb5a
   ret


.collision
   ld hl,(ex)
   ex hl,de
   ld hl,(ey)
   call &bbf0
   cp 1
   jr nz,endcoll
   ld a,(dead)
   dec a
   ld (dead),a
.endcoll
   ret


.genseed
   ld a,r
   ld (seed),a
   ret


.rand   ld a,(seed)
   ld b,a
   add a,a
   add a,a
   add a,b
   inc a
   ld (seed),a
   ret


.scroll
   ld b,0
   ld a,0
   ld h,0
   ld d,19
   ld l,0
   ld e,24
   call &bc50
   ret


.scalenum
   ld a,(seed)
   srl a
   srl a
   srl a
   srl a
   inc a
   ld (result),a
   ret
   
.ypos   defb 12
.xpos   defb 10
.oy   defb 12
.ox   defb 10
.ypos2   defb 13
.xpos2   defb 10
.dead   defb 1
.seed   defb 0
.result defb 0
.ex   defw 292
.ey   defw 238


* 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

ervin

I notice that .updaterocket is never called, but that doesn't really matter.

SCR_SOFTWARE_ROLL is indeed the culprit, regarding the speed.
Try SCR_HARDWARE_ROLL &BC4D instead. The speed difference is phenomenal.

AMSDOS

Quote from: ervin on 14:05, 18 April 18
I notice that .updaterocket is never called, but that doesn't really matter.


I was using it initially to generate a PRINT rocket/Enter MainLoop/Delete Rocket/Scroll/PRINT Rocket scenario. At that stage, I hadn't added any controls and it was just checking for a collision and to exit the Loop if one had occurred. Unfortunately at that stage I couldn't see where the Rocket was until the Obstacle was either Deleted by it (which told me the collision failed), or the Program stopped and Rocket finally displayed.

QuoteSCR_SOFTWARE_ROLL is indeed the culprit, regarding the speed.


I'm guessing then it's not really meant for games, I used it in my introductory animated sequence for the game I coded a couple of years ago, which worked fine, but not strictly meant for during gameplay. Still, coding this simple assembly game and experimenting with different aspects is an interesting experience.


Last night I updated the scroll routine with a LDI scroll routine I made up a couple of years ago, though I thought the result was similar to the SCR_SW_ROLL, obviously substituting that code to the ".scroll" routine within my Dodging Obstacles code:




;; LDI Scroll - This shifts the screen down in rows at a time.
;; Top Row needs to be blank so contents don't push it all the way down the screen


org &4000

xor a ;; Position for Loop equals 0.
.loop
ld hl,(adr_hl) ;; This holds the address pointer and is place into HL
ld e,(hl) ;; Though the Contents from that address goes into DE
inc hl ;; Cause it's 16bit data this is the only way I know
ld d,(hl) ;; How to do it, there maybe other ways. I dunno.

ex de,hl ;; The data above needs to go into HL and not DE


push hl ;; I need to protect my data in HL


ld hl,(adr_de) ;; This holds the address pointer and is place into HL
ld e,(hl) ;; Though the Contents from that address goes into DE
inc hl ;; Cause it's 16bit data this is the only way I know
ld d,(hl) ;; How to do it, there maybe other ways. I dunno.


pop hl ;; But restore it again for this routine


repeat 80
ldi ;; Moves things along.
rend


ld hl,(adr_hl) ;; Increment Start Position to the next spot
inc hl
inc hl
ld (adr_hl),hl ;; And store it in that pointer variable.


ld hl,(adr_de) ;; Increment Destination to the next position
inc hl
inc hl
ld (adr_de),hl ;; And store it in that pointer variable


inc a ;; Increment Loop


cp 192 ;; Check if this equals 192.


jp nz,loop ;; returns if not equal to 192, otherwise exit


ld hl,begin ;; Restores pointer to the beginning
ld (adr_hl),hl ;; should the user want to continue calling routine


ld hl,dest ;; Restores pointer to the Destination
ld (adr_de),hl ;; should the user want to continue calling routine


ret ;; exit routine


.adr_hl defw begin ;; pointer position to where the start position is for HL register
.adr_de defw dest ;; pointer position to where the start position is for DE register


;; Below these are Screen co-ordinate positions for DE, move from bottom to top of the screen


.dest defw &C780,&CF80,&D780,&DF80,&E780,&EF80,&F780,&FF80
.begin defw &C730,&CF30,&D730,&DF30,&E730,&EF30,&F730,&FF30
defw &C6E0,&CEE0,&D6E0,&DEE0,&E6E0,&EEE0,&F6E0,&FEE0
defw &C690,&CE90,&D690,&DE90,&E690,&EE90,&F690,&FE90
defw &C640,&CE40,&D640,&DE40,&E640,&EE40,&F640,&FE40
defw &C5F0,&CDF0,&D5F0,&DDF0,&E5F0,&EDF0,&F5F0,&FDF0
defw &C5A0,&CDA0,&D5A0,&DDA0,&E5A0,&EDA0,&F5A0,&FDA0
defw &C550,&CD50,&D550,&DD50,&E550,&ED50,&F550,&FD50
defw &C500,&CD00,&D500,&DD00,&E500,&ED00,&F500,&FD00
defw &C4B0,&CCB0,&D4B0,&DCB0,&E4B0,&ECB0,&F4B0,&FCB0
defw &C460,&CC60,&D460,&DC60,&E460,&EC60,&F460,&FC60
defw &C410,&CC10,&D410,&DC10,&E410,&EC10,&F410,&FC10
defw &C3C0,&CBC0,&D3C0,&DBC0,&E3C0,&EBC0,&F3C0,&FBC0
defw &C370,&CB70,&D370,&DB70,&E370,&EB70,&F370,&FB70
defw &C320,&CB20,&D320,&DB20,&E320,&EB20,&F320,&FB20
defw &C2D0,&CAD0,&D2D0,&DAD0,&E2D0,&EAD0,&F2D0,&FAD0
defw &C280,&CA80,&D280,&DA80,&E280,&EA80,&F280,&FA80
defw &C230,&CA30,&D230,&DA30,&E230,&EA30,&F230,&FA30
defw &C1E0,&C9E0,&D1E0,&D9E0,&E1E0,&E9E0,&F1E0,&F9E0
defw &C190,&C990,&D190,&D990,&E190,&E990,&F190,&F990
defw &C140,&C940,&D140,&D940,&E140,&E940,&F140,&F940
defw &C0F0,&C8F0,&D0F0,&D8F0,&E0F0,&E8F0,&F0F0,&F8F0
defw &C0A0,&C8A0,&D0A0,&D8A0,&E0A0,&E8A0,&F0A0,&F8A0
defw &C050,&C850,&D050,&D850,&E050,&E850,&F050,&F850
defw &c000,&c800,&d000,&d800,&e000,&e800,&f000,&f800





Quote
Try SCR_HARDWARE_ROLL &BC4D instead. The speed difference is phenomenal.


Yep, so I replaced the SCR_SW_ROLL with SCR_HW_ROLL, and braced for impact. To give my rocket a chance I placed it lower down the screen (line 24). I've brought ".updaterocket" back into play too (I can now see a blinking Red Rocket), and the HW ROLL Scrolls twice, to prevent the vast number of obstacles which were onscreen. I still had to put a couple of MC_FRAME_WAIT (&BD19s) after that, I had some after the Obstacles were drawn too, but I've since removed. So this is what I've currently done:




org &8000


ld a,0
call &bc0e


call genseed


ld a,1
call &bb90


ld b,24


.drawobstacles
push bc
call rand
call scalenum
ld a,(result)
ld h,a
ld l,1
call &bb75
ld a,225
call &bb5a
call scroll
call scroll
pop bc
djnz drawobstacles


call printrocket


.maingame


call updaterocket


call collision


ld a,(dead)
cp 0
jr z,skip


ld a,1
call &bb1e
jr z,checkleft


ld a,(xpos)
cp 16
jr z,checkleft
inc a
ld (xpos),a


call removerocket


call printrocket


ld a,(xpos)
ld (ox),a


ld hl,(ex)
ld de,32
add hl,de
ld (ex),hl


.checkleft
ld a,8
call &bb1e
jr z,skip


ld a,(xpos)
cp 1
jr z,skip
dec a
ld (xpos),a


call removerocket

call printrocket


ld a,(xpos)
ld (ox),a


ld hl,(ex)
ld de,32
and a
sbc hl,de
ld (ex),hl


.skip ld a,(dead)
and a
jr nz,maingame


ld a,(dead)
inc a
ld (dead),a


ret ;; Return to BASIC


.removerocket
ld hl,(oy)
call &bb75
ld a,32
call &bb5a
ret
.printrocket
ld hl,(ypos)
call &bb75
ld a,3
call &bb90
ld a,239
call &bb5a
ret


.updaterocket
call removerocket
call scroll
call scroll
call printrocket
call &bd19
call &bd19
call updateobstacle
ret


.updateobstacle
call rand
call scalenum
ld a,(result)
ld h,a
ld l,1
call &bb75
ld a,1
call &bb90
ld a,225
call &bb5a
ret


.collision
ld hl,(ex)
ex hl,de
ld hl,(ey)
call &bbf0
cp 1
jr nz,endcoll
ld a,(dead)
dec a
ld (dead),a
.endcoll
ret


.genseed
ld a,r
ld (seed),a
ret


.rand ld a,(seed)
ld b,a
add a,a
add a,a
add a,b
inc a
ld (seed),a
ret


.scroll
ld b,0
ld a,0
call &bc4d
ret


.scalenum
ld a,(seed)
srl a
srl a
srl a
srl a
inc a
ld (result),a
ret

.ypos defb 24
.xpos defb 10
.oy defb 24
.ox defb 10
.dead defb 1
.seed defb 0
.result defb 0
.ex defw 292
.ey defw 46


* 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

ervin

Nice one.
Much more playable that way!


SRS

Nice :)

roundabout 8 bytes smaller and lets say ... a few ... T-states faster:



org &8000


    xor a
    call &bc0e


    call genseed


    ld a,1
    call &bb90


    ld b,24


.drawobstacles
    push bc
    call rand
    call scalenum
    ld a,(result)
    ld h,a
    ld l,1
    call &bb75
    ld a,225
    call &bb5a
    call scroll
    call scroll
    pop bc
    djnz drawobstacles


    call printrocket


.maingame


    call updaterocket


    call collision


    ld a,(dead)
    or a
    jr z,skip


    ld a,1
    call &bb1e
    jr z,checkleft


    ld a,(xpos)
    cp 16
    jr z,checkleft
    inc a
    ld (xpos),a


    call removerocket


    call printrocket


    ld a,(xpos)
    ld (ox),a


    ld hl,(ex)
    ld de,32
    add hl,de
    ld (ex),hl


.checkleft
    ld a,8
    call &bb1e
    jr z,skip


    ld a,(xpos)
    dec a
    jr z,skip
    ld (xpos),a


    call removerocket
   
    call printrocket


    ld a,(xpos)
    ld (ox),a


    ld hl,(ex)
    ld de,32
    and a
    sbc hl,de
    ld (ex),hl


.skip    ld a,(dead)
    and a
    jr nz,maingame


    ld a,(dead)
    inc a
    ld (dead),a


    ret            ;; Return to BASIC


.removerocket
    ld hl,(oy)
    call &bb75
    ld a,32
    jp &bb5a
   
.printrocket
    ld hl,(ypos)
    call &bb75
    ld a,3
    call &bb90
    ld a,239
    jp &bb5a

.updaterocket
    call removerocket
    call scroll
    call scroll
    call printrocket
    call &bd19
    call &bd19
    jp updateobstacle

.updateobstacle
    call rand
    call scalenum
    ld a,(result)
    ld h,a
    ld l,1
    call &bb75
    ld a,1
    call &bb90
    ld a,225
    jp &bb5a

.collision
    ld hl,(ex)
    ex hl,de
    ld hl,(ey)
    call &bbf0
    dec a
    jr nz,endcoll
    ld a,(dead)
    dec a
    ld (dead),a
.endcoll
    ret


.genseed
    ld a,r
    ld (seed),a
    ret


.rand    ld a,(seed)
    ld b,a
    add a,a
    add a,a
    add a,b
    inc a
    ld (seed),a
    ret


.scroll
    xor a
    ld b,a
    jp &bc4d


.scalenum
    ld a,(seed)
    srl a
    srl a
    srl a
    srl a
    inc a
    ld (result),a
    ret
   
.ypos    defb 24
.xpos    defb 10
.oy    defb 24
.ox    defb 10
.dead    defb 1
.seed    defb 0
.result defb 0
.ex    defw 292
.ey    defw 46



AMSDOS

Quote from: SRS on 20:31, 19 April 18
Nice :)

roundabout 8 bytes smaller and lets say ... a few ... T-states faster:



Appreciate the improvements. Was keeping the update & collision routines separate, so I could work on adding additional code to it. The collision for example isn't perfect and thought I could make the game check if a collision with an obstacle has occurred when you move your rocket left or right.
I can also remove some code to remove the Rocket from the screen by simply moving the rocket to the bottom of the screen too, which will reduce the flicker I hope.  :)
* 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 made some more updates to my assembly code using a modified version David Hall's Ariom Sprites to work in with my assembly code. Unfortunately I encountered a problem when I tried to use it with SCR HW ROLL. Not only does SCR HW ROLL roll the screen, it shifts the screens offset, so the Sprite Driver didn't know where to draw the sprites, I tried to rectify this with a variable to store a new base address, so I could do the SCR HW ROLL, followed by SCR CHAR POSITION (&BC1A), to get the new offset position, subtract &54 to it to get my new base address, which initially worked, but then the game crashed (obviously because of some sensitive area was being poked). Aaarrrrruggghhh!


So I replaced that Scroll routine with my own, which appears to be running at the same pace as the SCR SW ROLL routine I was using earlier. So it looks like for this game to work I'll need to go back to SCR HW ROLL and use some of my other firmware routines to Draw the characters.


I'll be posting an updated DSK in my top post, the program is in Binary Format, so



MEMORY &7FFF
LOAD"obacles3.bin"
CALL &8000



or



MEMORY &7FFF
LOAD"obacles5.bin"
CALL &8000



To load either of those programs.




org &8000


xor a
call &bc0e ;; Mode 0


ld hl,colours
call setinks


call genseed ;; Randomize Seed


ld a,1
call &bb90 ;; Pen 1


ld b,24


.drawobstacles
push bc
call rand
call scalenum
ld a,(result)
ld (xpos1),a
ld a,2
ld (ypos1),a
ld a,3
ld (spr_num),a
call ariom_spr
call scroll
pop bc
djnz drawobstacles


call printrocket


.maingame


ld a,(dead)
or a
jr z,skip


ld a,1
call &bb1e ;; KM Test Key
jr z,checkleft


ld a,(xpos)
cp 16
jr z,checkleft


call clearrocket

ld a,(xpos)
inc a
ld (xpos),a


call printrocket


ld a,(xpos)
ld (ox),a


ld hl,(ex)
ld de,32
add hl,de
ld (ex),hl


.checkleft
ld a,8
call &bb1e ;; KM Test Key
jr z,skip


ld a,(xpos)
cp 1
jr z,skip


call clearrocket


ld a,(xpos)
dec a
ld (xpos),a


call printrocket


ld a,(xpos)
ld (ox),a


ld hl,(ex)
ld de,32
and a
sbc hl,de
ld (ex),hl


.skip call collision
call updaterocket
call updateobstacle


ld a,(dead)
and a
jr nz,maingame


call printexplosion


ld a,(dead)
inc a
ld (dead),a


ret ;; Return to BASIC


.printrocket
ld hl,(ypos)
ld (ypos1),hl
ld a,1
ld (spr_num),a
call ariom_spr
ret


.updaterocket
call clearrocket
call scroll
call printrocket
call &bd19 ;; FRAME
call &bd19
call &bd19
call &bd19
ret


.clearrocket
ld hl,(ypos)
ld (ypos1),hl
ld a,0
ld (spr_num),a
call ariom_spr
ret


.printexplosion
ld hl,(ypos)
ld (ypos1),hl
ld a,2
ld (spr_num),a
call ariom_spr
ret


.updateobstacle
call rand
call scalenum
ld a,(result)
ld (xpos1),a
ld a,2
ld (ypos1),a
ld a,3
ld (spr_num),a
call ariom_spr
ret


.collision
ld hl,(ex)
ex hl,de
ld hl,(ey)
call &bbf0 ;; TEST(ex,ey)
cp 0 ;; PEN:=0
jr z,endcoll ;; IF yes endcoll
ld a,(dead) ;; 
dec a ;; You're Dead
ld (dead),a ;;
.endcoll
ret


.genseed
ld a,r
ld (seed),a
ret


.rand ld a,(seed)
ld b,a
add a,a
add a,a
add a,b
inc a
ld (seed),a
ret


.setinks
ld c,(hl)
ld b,c
push af
push hl
call &bc32
pop hl
pop af
inc hl
inc a
cp 16
jr c,setinks
ret


.scroll
ld b,192 ;; This is how many lines to scroll down.
.loop
push bc ;; This protects the Loop Counter (not required at this stage)

ld hl,(adr_hl) ;; This holds the address pointer and is place into HL
ld e,(hl) ;; Though the Contents from that address goes into DE
inc hl ;; Cause it's 16bit data this is the only way I know
ld d,(hl) ;; How to do it, there maybe other ways. I dunno.

ex de,hl ;; The data above needs to go into HL and not DE


push hl ;; I need to protect my data in HL


ld hl,(adr_de) ;; This holds the address pointer and is place into HL
ld e,(hl) ;; Though the Contents from that address goes into DE
inc hl ;; Cause it's 16bit data this is the only way I know
ld d,(hl) ;; How to do it, there maybe other ways. I dunno.


pop hl ;; But restore it again for this routine


ld bc,&40 ;; BC is used here to address the length of the data on screen upto &40.
ldir ;; This instruction shifts the screen.
pop bc ;; Restores Loop Counter value so loop can address it.


ld hl,(adr_hl) ;; Increment Start Position to the next spot
inc hl
inc hl
ld (adr_hl),hl ;; And store it in that pointer variable.


ld hl,(adr_de) ;; Increment Destination to the next position
inc hl
inc hl
ld (adr_de),hl ;; And store it in that pointer variable


djnz loop ;; returns to loop if any remaining lines, otherwise proceed to exit


ld hl,begin ;; Restores pointer to the beginning
ld (adr_hl),hl ;; should the user want to continue calling routine


ld hl,dest ;; Restores pointer to the Destination
ld (adr_de),hl ;; should the user want to continue calling routine


ret ;; exit routine


.scalenum
ld a,(seed)
srl a
srl a
srl a
srl a
inc a
ld (result),a
ret


;; Ariom Sprites by David Hall


.ariom_spr
ld a,(spr_num)
ld b,a ;; Sprite Number
ld de,&0020 ;; Incrementer for 8x8 sprite (4 x 8 = 32 or 20h)
ld hl,Rocket-&20
;; address of sprites - &20 = &7d18
.spr_table
add hl,de ;; add &20 to &7d18 to obtain start of sprite table
djnz spr_table ;; loop until spr_num = 0, each loop adds &20 to obtain the correct sprite data
push hl ;; preserve sprite detail
ld a,(xpos1)
ld b,a ;; xpos details
ld hl,&bfac ;; this address serves as a base
ld e,&04 ;; 4 is incremented as each byte holds 4 colours
.x_scr_pos
add hl,de ;;
djnz x_scr_pos ;; loop until b reaches zero
ld e,&50 ;; &50 is added to place sprite in screen memory
ld a,(ypos1)
ld b,a ;; ypos details
.y_scr_pos
add hl,de ;;
djnz y_scr_pos ;; loop until b reaches zero, by this stage hl holds an address somewhere on-screen
pop de ;; restore sprite detail in de
ld c,&08 ;; c = height of image
.nxt_line
push hl ;; preserve screen address in hl
ld b,&04 ;; b = width of image
.drw_spr
ld a,(de) ;; a = byte contents
ld (hl),a ;; draw byte contents to screen
inc hl ;; increase screen address
inc de ;; increase to next position of sprite
djnz drw_spr ;; loop until b = 0
pop hl ;; restore original screen address
ld a,&08 ;; with a = 8
add h ;; add to h to position to a new line
ld h,a ;; and placed into h
dec c ;; decrement the height of the image
jr nz,nxt_line ;; if this doesn't equal 0 proceed to next line
ret ;; return to BASIC or M/C routine

.ypos defb 10
.xpos defb 10
.ypos1 defb 2
.xpos1 defb 5
.ox defb 10
.dead defb 1
.seed defb 0
.result defb 0
.ex defw 296
.ey defw 270
.spr_num
defb 3
.colours
defb 0,24,20,6,26,0,2,8,10,12,14,16,18,22,13,3
.adr_hl defw begin ;; pointer position to where the start position is for HL register
.adr_de defw dest ;; pointer position to where the start position is for DE register




;; Sprites


.Rocket
defb &00,&15,&00,&00; line 0
defb &00,&3A,&2A,&00; line 1
defb &15,&64,&35,&00; line 2
defb &15,&30,&35,&00; line 3
defb &00,&3A,&2A,&00; line 4
defb &15,&3A,&3F,&00; line 5
defb &44,&44,&44,&00; line 6
defb &00,&00,&00,&00; line 7


.Explosion
defb &00,&FF,&00,&00; line 0
defb &55,&CC,&AA,&00; line 1
defb &EE,&60,&DD,&00; line 2
defb &EE,&C0,&DD,&00; line 3
defb &EE,&C0,&DD,&00; line 4
defb &55,&CC,&AA,&00; line 5
defb &00,&FF,&00,&00; line 6
defb &00,&00,&00,&00; line 7


.Bolder
defb &00,&FF,&00,&00; line 0
defb &00,&FF,&AA,&00; line 1
defb &55,&FF,&FF,&AA; line 2
defb &FF,&FF,&FF,&FF; line 3
defb &55,&FF,&FF,&FF; line 4
defb &7F,&FF,&FF,&BF; line 5
defb &15,&7F,&7F,&2A; line 6
defb &00,&15,&15,&00; line 7


.dest defw &C780,&CF80,&D780,&DF80,&E780,&EF80,&F780,&FF80
.begin defw &C730,&CF30,&D730,&DF30,&E730,&EF30,&F730,&FF30
defw &C6E0,&CEE0,&D6E0,&DEE0,&E6E0,&EEE0,&F6E0,&FEE0
defw &C690,&CE90,&D690,&DE90,&E690,&EE90,&F690,&FE90
defw &C640,&CE40,&D640,&DE40,&E640,&EE40,&F640,&FE40
defw &C5F0,&CDF0,&D5F0,&DDF0,&E5F0,&EDF0,&F5F0,&FDF0
defw &C5A0,&CDA0,&D5A0,&DDA0,&E5A0,&EDA0,&F5A0,&FDA0
defw &C550,&CD50,&D550,&DD50,&E550,&ED50,&F550,&FD50
defw &C500,&CD00,&D500,&DD00,&E500,&ED00,&F500,&FD00
defw &C4B0,&CCB0,&D4B0,&DCB0,&E4B0,&ECB0,&F4B0,&FCB0
defw &C460,&CC60,&D460,&DC60,&E460,&EC60,&F460,&FC60
defw &C410,&CC10,&D410,&DC10,&E410,&EC10,&F410,&FC10
defw &C3C0,&CBC0,&D3C0,&DBC0,&E3C0,&EBC0,&F3C0,&FBC0
defw &C370,&CB70,&D370,&DB70,&E370,&EB70,&F370,&FB70
defw &C320,&CB20,&D320,&DB20,&E320,&EB20,&F320,&FB20
defw &C2D0,&CAD0,&D2D0,&DAD0,&E2D0,&EAD0,&F2D0,&FAD0
defw &C280,&CA80,&D280,&DA80,&E280,&EA80,&F280,&FA80
defw &C230,&CA30,&D230,&DA30,&E230,&EA30,&F230,&FA30
defw &C1E0,&C9E0,&D1E0,&D9E0,&E1E0,&E9E0,&F1E0,&F9E0
defw &C190,&C990,&D190,&D990,&E190,&E990,&F190,&F990
defw &C140,&C940,&D140,&D940,&E140,&E940,&F140,&F940
defw &C0F0,&C8F0,&D0F0,&D8F0,&E0F0,&E8F0,&F0F0,&F8F0
defw &C0A0,&C8A0,&D0A0,&D8A0,&E0A0,&E8A0,&F0A0,&F8A0
defw &C050,&C850,&D050,&D850,&E050,&E850,&F050,&F850
defw &c000,&c800,&d000,&d800,&e000,&e800,&f000,&f800


.theend
defb 0







* 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