Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- rem SPACE TANKS for the Atari VCS
- rem Geek Basic Computers 2013 www.geekbasic.com
- rem programmed by: Gemino Michael Smothers
- set tv ntsc
- set romsize 4k
- rem data statements go where you
- rem put them and the compiler adds jump
- rem around them so the code doesn't run
- rem into them
- rem using the noinlinedata optimization
- rem eliminates the jumps but you have to
- rem put the data statements out of the way
- set optimization noinlinedata
- dim mapx=a
- dim mapy=b
- dim area=c
- dim object=d
- dim shield=e
- dim ammo=f
- dim anim=g
- dim dir=h
- dim aimx=i
- dim aimy=j
- dim delay=k
- dim shoot=l
- dim key=m
- dim kills=n
- dim temp=o
- dim tempx=p
- dim tempy=q
- dim sfx=r
- dim slen=s
- dim explode=t
- dim flag=u
- dim npcshield=v
- dim autolock=w
- dim bigmissile=x
- const p0_0 = $63
- const p0_1 = p0_0 + 8
- const p0_2 = p0_0 + 16
- const p1_0 = $13
- const p1_1 = p1_0 + 8
- const p1_2 = p1_0 + 16
- const p1_3 = p1_0 + 24
- const p1_4 = p1_0 + 32
- const p1_5 = p1_0 + 40
- const p1_6 = p1_0 + 48
- const p1_7 = p1_0 + 56
- const p1_8 = p1_0 + 64
- const p1_9 = p1_0 + 72
- const p1_A = p1_0 + 80
- rem moved the data statement out
- rem of the way of the code
- rem data areas
- rem 3,7,11,11,11,8,7,11,11,8
- rem 10,10,7,11,11,9,10,7,8,10
- rem 6,5,9,2,11,11,4,10,6,9
- rem 7,9,7,4,7,11,8,6,11,8
- rem 10,7,9,2,5,8,6,11,11,9
- rem 10,6,8,7,5,5,4,7,11,8
- rem 6,8,10,10,10,6,4,6,4,10
- rem 2,5,5,9,6,8,7,11,11,9
- rem 7,5,5,8,7,9,6,11,11,8
- rem 6,9,1,1,6,11,11,11,11,9
- rem end
- gosub titlecols
- rem initialize flag is not critical
- rem so you could save a few bytes
- rem by leaving it out
- flag=0
- titleloop
- rem flag will roll over at 255
- rem so the test are 0 and 128
- rem which will make the time about
- rem 1 / 3 longer
- rem and you leave out the counter reset
- rem !flag is cheaper and equivalent
- rem to if flag = 0
- rem if flag=100 then playfield:
- if !flag then playfield:
- ......XXX..X...XX...XX...X.....
- .....X....X.X.X..X.X....X......
- ......XX..XX..XXXX.X....XX.....
- ........X.X...X..X.X....X......
- .....XXX..X...X..X..XX...X.....
- ...............................
- .....XXX..XX..X..X.X.X..XXX....
- ......X..X..X.XX.X.X.X.X.......
- ......X..XXXX.X.XX.XX...XX.....
- ......X..X..X.X..X.X.X....X....
- ......X..X..X.X..X.X.X.XXX.....
- end
- if flag=128 then playfield:
- .........XXX..X..X.X.X.........
- ........X....X..X..X.X.........
- ........X.XX.XX.XX.XX..........
- ........X..X.X..X..X.X.........
- .........XX...X..X.X.X.........
- ...............................
- ......XX...XX...XXX.XXX..XX....
- .....X..X.X..X.X.....X..X......
- .....X.XX.XXXX..XX...X..X......
- .....X..X.X..X....X..X..X......
- .....XXX..X..X.XXX..XXX..XX....
- end
- rem leave out the counter reset
- rem if flag=200 then flag=0
- rem reverse the sense of the if predicate
- rem saves a goto but have to move the drawscreen
- drawscreen
- flag=flag+1
- if !joy0fire && !joy1fire then goto titleloop
- ammo=60:shield=60:player0x=45:player0y=45:missile0x=55:missile0y=45
- rem drawscreen
- rem goto titleloop
- rem you don't need to rewrite the
- rem playfield if you just adjust
- rem for the differences between
- rem old and the new
- rem so moved stuff around so that
- rem the playfield statement is
- rem outside the loop
- rem this is less flexible if
- rem doing things by differences
- rem is not good enough
- rem loadroom
- rem flag=mapx+(mapy*10)
- rem area=areas[flag]
- rem the playfield is only 31 pixels
- rem wide instead of the full 32
- playfield:
- .XXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
- XXXXXX...................XXXXXX
- XXX.........................XXX
- XX...........................XX
- X.............................X
- X.............................X
- X.............................X
- XX...........................XX
- XXX.........................XXX
- XXXXXX...................XXXXXX
- .XXXXXXXXXXXX.....XXXXXXXXXXXX.
- end
- gosub setup_P1
- rem var4 = player0pointerlo
- rem var4 = player1pointerlo
- area = 4
- loadroom
- rem rearranging the expression
- rem saves stashing mapx on the stack
- rem saved 35 bytes so far
- rem flag=mapx+(mapy*10)
- flag=mapy*10 + mapx
- rem I changed the areas data
- rem to represent where the openings
- rem are and then rearranged the code to
- rem flip openings that are different
- rem between the old and the new screen
- rem that way you only need one if statement
- rem and one call to the the line routines
- rem for each possible opening
- rem and you don't draw lines if you don't
- rem need to
- rem area needs initializing and the initial
- rem playfield definition is different
- rem this saves about 240 bytes all by it's self
- rem 280 or so total so far
- rem if area=1 then pfhline 13 0 17 off
- rem if area=2 then pfvline 30 3 7 off
- rem if area=3 then pfhline 13 10 17 off
- rem if area=4 then pfvline 0 3 7 off
- rem if area=5 then pfhline 13 0 17 off:pfvline 30 3 7 off:pfhline 13 10 17 off:pfvline 0 3 7 off
- rem if area=6 then pfhline 13 0 17 off:pfvline 30 3 7 off
- rem if area=7 then pfvline 30 3 7 off:pfhline 13 10 17 off
- rem if area=8 then pfhline 13 10 17 off:pfvline 0 3 7 off
- rem if area=9 then pfhline 13 0 17 off:pfvline 0 3 7 off
- rem if area=10 then pfhline 13 0 17 off:pfhline 13 10 17 off
- rem if area=11 then pfvline 30 3 7 off:pfvline 0 3 7 off
- area = area ^ areas[flag]
- if area{0} then pfhline 13 0 17 flip
- if area{1} then pfvline 30 3 7 flip
- if area{2} then pfhline 13 10 17 flip
- if area{3} then pfvline 0 3 7 flip
- area = areas[flag] : flag = 0
- if mapx=6&&mapy=6 then object=9:goto gameloop else object=(rand&7)+1
- if object=4 then object=0
- if !mapx&&!mapy then object=0
- if switchleftb&&object>6&&rand<40 then object=0
- npcshield=object*2
- rem each of these gives you 4 possibilities
- rem for a total of 16 possibile positions
- player1x=(rand&80)+40
- player1y=(rand&40)+35
- gameloop
- COLUPF=$00
- COLUBK=$64
- COLUP0=$04
- if anim=11 then anim=0
- if anim<6 then player0:
- %10101011
- %01010101
- %11111111
- %11111111
- %01111110
- %00011000
- %01111000
- %00000000
- end
- if anim>5 then player0:
- %11010101
- %10101010
- %11111111
- %11111111
- %01111110
- %00011000
- %01111000
- %00000000
- end
- rem if mapy is equivalent to if mapy > 0
- rem but is faster and uses fewer bytes
- rem if player0y<10&&mapy>0 then mapy=mapy-1:player0y=85:goto loadroom
- if player0y<10&&mapy then mapy=mapy-1:player0y=85:goto loadroom
- if player0x>135&&mapx<9 then mapx=mapx+1:player0x=20:goto loadroom
- if player0y>85&&mapy<10 then mapy=mapy+1:player0y=20:goto loadroom
- rem if player0x<15&&mapx>0 then mapx=mapx-1:player0x=130:goto loadroom
- if player0x<15&&mapx then mapx=mapx-1:player0x=130:goto loadroom
- rem dir is set from a look up table indexed by
- rem the joy0 part of SWCHA and then used to index
- rem position increments this reduces the code and makes
- rem the timing less variable and saves about 64 bytes
- rem tables are arbitrary and more flexible
- rem the way the if statements are set up prioritizes
- rem directions and doesn't allow for diagonal movement
- rem the way the tables are set up mimics that
- rem but it would be easy to change
- rem if collision(player0,playfield)&&dir=1 then player0y=player0y+1:goto skipmove
- rem if collision(player0,playfield)&&dir=2 then player0x=player0x-1:goto skipmove
- rem if collision(player0,playfield)&&dir=3 then player0y=player0y-1:goto skipmove
- rem if collision(player0,playfield)&&dir=4 then player0x=player0x+1:goto skipmove
- if collision(player0,playfield) && dir then player0x = player0x + dx[dir] : player0y = player0y + dy[dir] : goto skipmove
- if !explode&&flag{0} then flag{0}=0
- rem skipmove is close enough that you
- rem don't need the goto
- rem if flag{0} then goto skipmove
- if flag{0} then skipmove
- temp1 = (SWCHA ^ $F0) / 16
- if temp1 && !collision(player0,playfield) then dir = dirt[temp1] : player0x = player0x - dx[dir] : player0y = player0y - dy[dir] : flag{1} = 1 : anim = anim + 1
- rem if joy0up&&!collision(player0,playfield) then player0y=player0y-1:dir=1:anim=anim+1:flag{1}=1:goto skipmove
- rem if joy0right&&!collision(player0,playfield) then player0x=player0x+1:dir=2:anim=anim+1:flag{1}=1:goto skipmove
- rem if joy0down&&!collision(player0,playfield) then player0y=player0y+1:dir=3:anim=anim+1:flag{1}=1:goto skipmove
- rem if joy0left&&!collision(player0,playfield) then player0x=player0x-1:dir=4:anim=anim+1:flag{1}=1:goto skipmove
- skipmove
- if joy1up&&missile0y>8 then missile0y=missile0y-1
- if joy1right&&missile0x<155 then missile0x=missile0x+1
- if joy1down&&missile0y<80 then missile0y=missile0y+1
- if joy1left&&missile0x>5 then missile0x=missile0x-1
- if !joy1fire&&flag{3} then flag{3}=0
- if autolock then missile0x=player1x+3:missile0y=player1y-3
- rem these could save a few bytes but are probably
- rem not worth it with more than 8 objects and having
- rem to select flag bytes
- rem temp1 = object / 8 : temp2 = setb[object]
- rem if cP1f[temp1] & temp2 then COLUP1 = cP1[object]
- rem if NS1f[temp1] & temp2 then NUSIZ1 = NS1[object]
- rem if P1f[temp1] & temp2 then P1plo = P1[object]
- rem using on gosub gets rid of some if statements
- rem and uses returns instead of goto's
- rem with the miscellaneous tweaks in the subroutines
- rem saves about 85 bytes
- on object gosub o0 o1 o2 o3 o4 o5 o6 o7 o8 o9
- skipo
- if joy0fire then tempx=player1x:tempy=player1y:goto huddisplay
- dead
- if switchreset then reboot
- drawscreen
- AUDV0=0
- if flag{1} then AUDV0=4:AUDC0=2:AUDF0=3:flag{1}=0
- if slen then AUDV0=10:AUDC0=4:AUDF0=sfx:sfx=sfx-1
- if slen&&!sfx then sfx=6:slen=slen-1
- if sfx>0&&!slen then AUDV0=10:AUDC0=8:AUDF0=5:sfx=sfx-1
- if shield>250 then goto dead
- goto gameloop
- huddisplay
- gosub shieldsprite
- player1x=60
- player1y=80
- missile1x=70
- missile1y=80
- missile1height=shield
- drawscreen
- gosub ammosprite
- player1x=80
- player1y=80
- missile1x=90
- missile1y=80
- missile1height=ammo
- drawscreen
- if joy0fire then goto huddisplay
- player1x=tempx
- player1y=tempy
- gosub hidemissile
- goto gameloop
- data areas
- 4, 6, 10, 10, 10, 12, 6, 10, 10, 12
- 5, 5, 6, 10, 10, 9, 5, 6, 12, 5
- 3, 15, 9, 2, 10, 10, 8, 5, 3, 9
- 6, 9, 6, 8, 6, 10, 12, 3, 10, 12
- 5, 6, 9, 2, 15, 12, 3, 10, 10, 9
- 5, 3, 12, 6, 15, 15, 8, 6, 10, 12
- 3, 12, 5, 5, 5, 3, 8, 3, 8, 5
- 2, 15, 15, 9, 3, 12, 6, 10, 10, 9
- 6, 15, 15, 12, 6, 9, 3, 10, 10, 12
- 6, 9, 1, 1, 6, 11, 11, 11, 11, 9
- end
- data dirt
- 0, 1, 3, 1, 4, 1, 3, 1, 2, 1
- end
- const dx = dy + 1
- data dy
- 0, 1, 0, -1, 0, 1
- end
- rem selection is done with on gosub so the
- rem if statement is not needed
- rem if object>0 then goto o1
- o0
- player1pointerlo = p1_A
- rem player1:
- rem %00000000
- rem %00000000
- rem %00000000
- rem %00000000
- rem %00000000
- rem %00000000
- rem %00000000
- rem %00000000
- rem end
- if explode then explode=explode-1:COLUP1=$48:player1pointerlo = p1_0
- rem %00000100
- rem %01111110
- rem %11111100
- rem %01111110
- rem %00111110
- rem %11111110
- rem %00111100
- rem %01011110
- rem end
- if explode=0&&flag{0} then object=4:flag{0}=0
- gosub hidemissile
- rem goto skipo
- return
- o1
- rem done with on gosub
- rem if object>2 then goto o3
- if object=1 then COLUP1=$44:NUSIZ1=$00 : player1pointerlo = p1_1
- rem player1:
- rem %01100110
- rem %00100100
- rem %00011000
- rem %00011000
- rem %01111110
- rem %11011000
- rem %00111100
- rem %00111100
- rem end
- o2
- if object=2 then COLUP1=$0E:NUSIZ1=$07 : player1pointerlo = p1_2
- rem player1:
- rem %00101000
- rem %01000010
- rem %00100101
- rem %10011000
- rem %00011001
- rem %10100100
- rem %01000010
- rem %00010100
- rem end
- if object=2 then shoot=0:gosub hidemissile
- shoot=0:gosub hidemissile
- delay=delay+1
- rem removed the gotos
- rem if object=1&&delay<3 then goto skipmove2
- rem if shoot then goto skipmove2
- if object=1&&delay<3 then skipmove2
- if shoot then skipmove2
- delay=0
- if switchrightb then temp=1 else temp=0
- if aimy=0 then player1y=player1y-1:player1y=player1y-temp
- if aimx=1 then player1x=player1x+1:player1x=player1x+temp
- if aimy=1 then player1y=player1y+1:player1y=player1y+temp
- if aimx=0 then player1x=player1x-1:player1x=player1x-temp
- skipmove2
- if player1y<20 then aimy=1
- if player1x>120 then aimx=0
- if player1y>80 then aimy=0
- if player1x<20 then aimx=1
- if joy1fire then gosub checkfire
- if collision(player0,player1) then shield=shield-1:sfx=2
- rem goto skipo changed to return
- rem if object=2 then goto skipo
- if object=2 then return
- rem removed goto's
- rem temp=player1y-1:if player0y<temp then goto skipshoot
- rem temp=player1y+1:if player0y>temp then goto skipshoot
- temp=player1y-1:if player0y<temp then skipshoot
- temp=player1y+1:if player0y>temp then skipshoot
- if player0x<player1x&&shoot=0 then missile1x=player1x+4:missile1y=player1y-3:shoot=1
- if player0x>player1x&&shoot=0 then missile1x=player1x+4:missile1y=player1y-3:shoot=2
- skipshoot
- if shoot=1 then missile1x=missile1x-2
- if shoot=2 then missile1x=missile1x+2
- if missile1x<20||missile1x>135 then shoot=0:gosub hidemissile
- if collision(player0,missile1) then shield=shield-15:shoot=0:sfx=7:gosub hidemissile
- rem goto skipo
- return
- o3
- rem on gosub .. not needed .. yadda, yadda, yadda
- rem if object>3 then goto o4
- COLUP1=$12
- NUSIZ1=$07
- player1pointerlo = p1_3
- rem player1:
- rem %11100111
- rem %11100111
- rem %01000010
- rem %11111111
- rem %01111111
- rem %00111111
- rem %00011111
- rem %00000000
- rem end
- delay=delay+1
- rem you know the drill by now
- rem if delay<3 then goto skipmove3
- if delay<3 then skipmove3
- delay=0
- if switchrightb then temp=1 else temp=0
- if player0y<player1y then player1y=player1y-1:player1y=player1y-temp
- if player0x>player1x then player1x=player1x+1:player1x=player1x+temp
- if player0y>player1y then player1y=player1y+1:player1y=player1y+temp
- if player0x<player1x then player1x=player1x-1:player1x=player1x-temp
- skipmove3
- if joy1fire then gosub checkfire
- if collision(player0,player1) then shield=shield-1:sfx=2
- rem goto skipo
- return
- o4
- rem if object>4 then goto o5
- COLUP1=$B8
- player1pointerlo = p1_4
- rem player1:
- rem %00000000
- rem %01111110
- rem %01000010
- rem %01111110
- rem %01000010
- rem %01111110
- rem %00100010
- rem %00011110
- rem end
- if collision(player0,player1) then object=0:key=key+1:score=score+100:slen=3:sfx=6
- rem goto skipo
- return
- o5
- rem if object>5 then goto o6
- gosub hidemissile
- gosub shieldsprite
- if collision(player0,player1) then object=0:shield=shield+15:slen=3:sfx=6
- if shield>200 then shield=200
- rem goto skipo
- return
- o6
- rem if object>6 then goto o7
- gosub hidemissile
- gosub ammosprite
- if collision(player0,player1) then object=0:ammo=ammo+10:slen=3:sfx=6
- if ammo>200 then ammo=200
- rem goto skipo
- return
- o7
- rem if object>7 then goto o8
- COLUP1=$C6
- player1pointerlo = p1_5
- rem player1:
- rem %00010000
- rem %00010000
- rem %00000000
- rem %11010110
- rem %00000000
- rem %00010000
- rem %00010000
- rem %00000000
- rem end
- if collision(player0,player1) then object=0:autolock=3:slen=3:sfx=6
- rem goto skipo
- return
- o8
- rem if object>8 then goto o9
- COLUP1=$0A
- player1pointerlo = p1_6
- rem player1:
- rem %01010100
- rem %01111100
- rem %00111000
- rem %00111000
- rem %00111000
- rem %00111000
- rem %00111000
- rem %00010000
- rem end
- if collision(player0,player1) then object=0:bigmissile=3:slen=3:sfx=6
- rem goto skipo
- return
- o9
- COLUP1=$04
- NUSIZ1=$07
- player1x=45
- player1y=30
- player1pointerlo = p1_7
- rem player1:
- rem %11111111
- rem %10100101
- rem %10110101
- rem %10100101
- rem %10101101
- rem %10100101
- rem %10110101
- rem %11111111
- rem end
- rem rigged it to fall through to win
- rem not sure thats such a good idea
- rem stack needs popped if we don't return
- if !collision(player0,player1) || key<>3 then return
- pop
- win
- gosub titlecols
- AUDV0=0
- player0y=0
- player1y=0
- missile0y=0
- playfield:
- ..X.X..X..XXX..XXX.X..XX..X..X.
- .X.X.X.X.X....X....X.X..X.XX.X.
- .X.X.X.X..XXX..XX..X.X..X.X.XX.
- .X.X.X.X....X....X.X.X..X.X..X.
- .X.X.X.X.XXX..XXX..X..XX..X..X.
- ...............................
- .XX..XX...X.X...X..X...X.XXX..X
- X...X..X.X.X.X.X.X.X..X...X..X.
- X...X..X.X.X.X.XX..X..XX..X..XX
- X...X..X.X.X.X.X...X..X...X..X.
- .XX..XX..X.X.X.X...XX..X..X...X
- end
- if switchreset then reboot
- drawscreen
- goto win
- titlecols
- COLUPF=$46
- COLUBK=$00
- scorecolor=$0E
- return
- shieldsprite
- COLUP1=$86
- player1pointerlo = p1_8
- rem player1:
- rem %00000000
- rem %00111000
- rem %01000100
- rem %00000100
- rem %00111000
- rem %01000000
- rem %01000100
- rem %00111000
- rem end
- return
- ammosprite
- COLUP1=$44
- player1pointerlo = p1_9
- rem player1:
- rem %00000000
- rem %01000100
- rem %01000100
- rem %01000100
- rem %01111100
- rem %01000100
- rem %00101000
- rem %00010000
- rem end
- return
- hidemissile
- missile0height=2
- missile1height=1
- missile1x=0
- missile1y=0
- return
- checkfire
- if flag{3} then goto skipfire
- if ammo>0 then ammo=ammo-1:flag{3}=1:sfx=10 else goto skipfire
- if !collision(missile0,player1) then goto skipfire
- if npcshield&&!bigmissile then npcshield=npcshield-1:goto skipfire
- if npcshield&&bigmissile then npcshield=0
- if npcshield then goto skipfire
- if key<3 then kills=kills+object
- if kills>30 then flag{0}=1:kills=0
- if autolock then autolock=autolock-1
- if bigmissile then bigmissile=bigmissile-1
- score=score+100
- explode=25
- object=0
- skipfire
- return
- rem consolidating the player1
- rem definitions saves about 70 bytes
- setup_P1
- player1:
- %00000100
- %01111110
- %11111100
- %01111110
- %00111110
- %11111110
- %00111100
- %01011110
- %01100110
- %00100100
- %00011000
- %00011000
- %01111110
- %11011000
- %00111100
- %00111100
- %00101000
- %01000010
- %00100101
- %10011000
- %00011001
- %10100100
- %01000010
- %00010100
- %11100111
- %11100111
- %01000010
- %11111111
- %01111111
- %00111111
- %00011111
- %00000000
- %00000000
- %01111110
- %01000010
- %01111110
- %01000010
- %01111110
- %00100010
- %00011110
- %00010000
- %00010000
- %00000000
- %11010110
- %00000000
- %00010000
- %00010000
- %00000000
- %01010100
- %01111100
- %00111000
- %00111000
- %00111000
- %00111000
- %00111000
- %00010000
- %11111111
- %10100101
- %10110101
- %10100101
- %10101101
- %10100101
- %10110101
- %11111111
- %00000000
- %00111000
- %01000100
- %00000100
- %00111000
- %01000000
- %01000100
- %00111000
- %00000000
- %01000100
- %01000100
- %01000100
- %01111100
- %01000100
- %00101000
- %00010000
- %00000000
- %00000000
- %00000000
- %00000000
- %00000000
- %00000000
- %00000000
- %00000000
- end
- player1height = 7
- return
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement