rem 9/12/2021 05:44:00 PM batari Basic 1.5 rem ************************************** rem *App type * rem *Name * rem *Author * rem *Hardware <2600> * rem *Contact via Atariage.com forums * rem *Forum = Atari 2600 Programming * rem *Topic = Looking for a few people * rem * to make a game with! * rem * = free to modify for * rem * non-commercial use * rem * Please do not use the name Guard * rem * or title screen for your program * rem * * rem *Includes content from: * rem * by * rem ************************************** rem Known functions of variables: rem Note - this list produced after original stripped of animations rem a rem b{0} flag 0,1 used to keep character in horizontal lanes = can't move left/right until flag is set rem b{1} flag 0,1 used to keep character in vertical lanes = can't move up/down unless flag is set rem b{2} flag 0,1 used as flip flop to slow player movement rem b{3} used with REFP0 and REFP1 to flip sprites horrizontally but in this game rem b{3} somehow makes each dot register only once else score climbs rapidly and crashes. rem b{4} flag 0,1 if set to 1 indicates level is completed (70 dots collected) rem b{5} flag 0,1 if set to 1 indicates collided with playfield (eat dot) rem b{6} flag 0,1 if set to 1 causes pacman death sound to play rem b{7} appears be a flag 0,1 for if sound output is active or not rem c 0,1,2,3,4,5 tied to joystick directions/status for player 0 rem c directions 1=left, 2=right, 3=up, 4=down rem d 0,1,2,3,4,5 tied to joystick directions/status for player 1 rem d directions 1=left, 2=right, 3=up, 4=down rem e = x positon of pfpixel to be turned off when player contacts it rem f = y postion of pfpixel to be turned off when player contacts it rem g = number of dots collected this level rem h only one instance of h. Function unknown. removed with no apparent effect rem i is incrimented after j reaches 20 cycles. Incrimented until reaches 5 which is number of color flashes for playfield after a level is completed rem j when level is complete, j is incrimented. If j<11 then playfield shows one color and > show another color. (flashes playfield) rem k has something to do with audio such as when player collides with playfield rem m unknown used in nuka break rem n unknown used in nuka break rem o unknown used in nuka break rem p unknown used in nuka break rem q 0,1,2,3,4,5 tied to joystick directions/status for player 1b (virtual) rem q directions 1=left, 2=right, 3=up, 4=down rem r = direction of player1 inside the movement routine only (temp) rem s = a counter used to index a target point for virtual sprite rem the target for player1 is the x,y of player0. This makes player1 rem the follower. By describing a list of target points player1b can rem follow a pattern incrementing this s index each time it reaches rem a particular target point. rem t = temporarily holds player0 x value so can load player0x with target value rem u = temporarily holds player0 y value so can load player0y with target value rem rem Standard kernel only has two sprites so we will create a virtual sprite rem by displaying player1 in different locations every other frame rem Nuka Break already had a flip flop in b{2} so we add variables to store rem the x,y values we will need to swap each frame rem v=temporary stored location of player1x for creating virtual sprite rem w=temporary stored location of player1y for creating virtual sprite rem x=alternate location of player1x rem y=alternate location of player1y rem score set romsize 4k rem setting playercolors and player1colors gives 2 multicolor sprites but missiles are lost when using this option set kernel_options playercolors player1colors pfcolors re_start score=0 ;*************************************************************** ; ; Clears the playfield. ; pfclear ;*************************************************************** ; ; Mutes volume of both sound channels. ; AUDV0 = 0 : AUDV1 = 0 ;*************************************************************** ; ; Clears all normal variables and the extra 9. ; a = 0 : b = 0 : c = 0 : d = 0 : e = 0 : f = 0 : g = 0 : h = 0 : i = 0 j = 0 : k = 0 : l = 0 : m = 0 : n = 0 : o = 0 : p = 0 : q = 0 : r = 0 s = 0 : t = 0 : u = 0 : v = 0 : w = 0 : x = 0 : y = 0 : z = 0 var0 = 0 : var1 = 0 : var2 = 0 : var3 = 0 : var4 = 0 var5 = 0 : var6 = 0 : var7 = 0 : var8 = 0 b{7}=1 playfield: ................................ ................................ ................................ ....XXX..X...X..XX..XXX..XXX.... ...X.....X...X.X..X.X..X.X..X... ...X..XX.X...X.XXXX.XXX..X..X... ...X...X.X...X.X..X.X..X.X..X... ....XXX...XXX..X..X.X..X.XXX.... ................................ ................................ ................................ end ;*************************************************************** ; ; Sets color of player0 sprite. (seems to be inverted top to bottom) ; Note: have to sacrifice a missile for each player color - so no missiles player0color: $F6 $44 $46 $46 $1A $1A $1A $1A end ;*************************************************************** ; ; Sets color of player1 sprite. ; player1color: $94 $96 $98 $9A $9C $1C $1C $1C end pfcolors: 212 212 212 212 212 212 212 212 212 212 212 end COLUBK = $00 COLUPF = 212 rem Loop the screen until the spacebar is pressed title drawscreen if joy0fire || joy1fire then goto beginning goto title beginning playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..X.X.X.X.X.X.X..X.X.X.X.X.X.X.. ..XXXXXXXXXXXXX..XXXXXXXXXXXXX.. ..X.X.X.X.X.X.X..X.X.X.X.X.X.X.. ..XXXXXXXXXXXXX..XXXXXXXXXXXXX.. ..X.X.X.X.X.X.X..X.X.X.X.X.X.X.. ..XXXXXXXXXXXXX..XXXXXXXXXXXXX.. ..X.X.X.X.X.X.X..X.X.X.X.X.X.X.. ..XXXXXXXXXXXXX..XXXXXXXXXXXXX.. ..X.X.X.X.X.X.X..X.X.X.X.X.X.X.. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end pfcolors: $1A $42 $1A $42 $1A $42 $1A $42 $1A $42 $1A end COLUBK = 0 COLUPF=$1A : COLUP0=$1A : COLUP1=$2A : scorecolor=$1A rem player 0 is the guard rem x is the horizontal location rem y is the vertical location player0x=77 : player0y=48 v=137 : w=80 : x=17 : y=80 player1x = 17 : player1y = 80 :d=3 s=1 if b{7} then AUDV0=8 : AUDV1=8 : AUDC0=4 : AUDC1=4 b{6}=0 drawscreen player0: %00110110 %00011100 %01011101 %00111110 %00011100 %00111110 %00101010 %00111110 end player1: %00110110 %00011100 %01011101 %00111110 %00011100 %00111110 %00101010 %00111110 end noise if b{7} then a=a+1 if !b{7} then c=0 : goto main if a>16 then a=0 : c=c+1 if c=1 then AUDF0=4 : AUDF1=18 if c=2 then AUDF0=12 : AUDF1=14 if c=3 then AUDF0=4 : AUDF1=18 if c=4 then AUDF0=8 : AUDF1=14 if c=5 then k=0 : c=0 : goto main goto beginning main b{7}=0 AUDV0=k : AUDV1=0 if collision(player0,playfield) && g<70 then k=9 : b{5}=1 : score=score+1 : g=g+1 : pfpixel e f off if b{5} then k=k-1 : AUDC0=9 : AUDF0=9 if b{5} && k<1 then k=0 : b{5}=0 if collision(player0,playfield) && g=70 then g=0 : b{5}=0 : k=0 : b{4}=1 : c=0 : a=0 : AUDV0=0 : b{3}=0 if b{4} then j=j+1 if collision(player0,player1) then b{6}=1:goto game_over if b{6} then AUDV0=k : AUDF0=m : AUDC0=4 : n=n+1 if n=4 then k=k-1 : n=0 : o=o+1 : p=p+1 if n=3 then m=m-1 if o>5 then k=0 if o>6 then o=0 : k=15 if b{6} && m=2 then o=0 : p=0 : k=0 if b{6} && m=2 then b{6}=0 : n=0 : c=0 rem Position of Horizontal and Vertical lanes/passages describe and flag set rem Player can only move into a lane if the appropriate flag is set b{0}=0 : b{1}=0 if player0x=17 then b{1}=1 if player0x=77 then b{1}=1 if player0x=137 then b{1}=1 if player0y=16 then b{0}=1 if player0y=32 then b{0}=1 if player0y=48 then b{0}=1 if player0y=64 then b{0}=1 if player0y=80 then b{0}=1 COLUP0=$1A : COLUP1=$2A : scorecolor=$1A drawscreen if !b{4} then a=a+1 if a>20 then a=0 if b{4} && j=20 then j=0 : i=i+1 if b{4} && i=5 then i=0 : b{4}=0 : AUDV0=0 : goto beginning if b{4} && j>10 then pfcolors: 14 14 14 14 14 14 14 14 14 14 14 end if b{4} && j<11 then pfcolors: 130 130 130 130 130 130 130 130 130 130 130 end if b{4} then goto main rem human player movement routine rem if joy0fire && !b{6} && !b{5} then k=15 : m=31 : b{6}=1 : c=0 if joy0left && b{0} then c=1 if joy0right && b{0} then c=2 if joy0up && b{1} then c=3 if joy0down && b{1} then c=4 rem the next line below is a flip flop used in Nuka Break to rem slow the players motion to half speed. If b{2} <> 1 then player doesn't move. rem Could also be used to change turns between players (one cycle to each) if b{2} then b{2}=0 else b{2}=1 if !b{2} then goto not_move_0 rem next lines bound the player so the sprite doesn't leave playfield if c=1 && player0x>17 then player0x=player0x-1 : b{3}=1 if c=2 && player0x<137 then player0x=player0x+1 : b{3}=0 if c=3 && player0y>16 then player0y=player0y-1 if c=4 && player0y<80 then player0y=player0y+1 not_move_0 if b{3} then REFP0=8 else REFP0=0 rem e,f are x,y postion of playfield pixel to be erased if b{3} then e=(player0x-17)/4 if !b{3} then e=(player0x-10)/4 f=(player0y-1)/8 ;*************************************************************** ; ; automated player1 movement routine ; ; In order to save bytes the one routine runs two sprites ; One sprite targets player0's x,y location directly ; The other sprite targets a list of intersections ; which results in the sprite running a loop pattern. ; x and y coordinates are swapped in and stored back to their owners ; as needed. Both sprites being moved are player1 since the ; standard kernel only allows for two sprites and the other is the ; human player. ; The list of intersections that make the pattern can be edited ; or extended. Just set if s> to the appropriate value. if !b{2} then player1x=x : player1y=y : r=d : t=player0x : u=player0y : goto check_column_1 if b{2} then player1x=v : player1y=w : r=q :rem swaps between player1 instances (virtual sprite) rem set target for player1b rem here is where s index table will go if s=1 then t=137 : u=64 if s=2 then t=17 : u=64 if s=3 then t=17 : u=32 if s=4 then t=77 : u=32 if s=5 then t=77 : u=48 if s=6 then t=137 : u=48 if s=7 then t=137 : u=16 if s=8 then t=17 : u=16 if s=9 then t=17 : u=48 if s=10 then t=77 : u=48 if s=11 then t=77 : u=64 if s=12 then t=17 : u=64 if s=13 then t=17 : u=80 if s=14 then t=137 : u=80 rem is player1 at intersection point? then choose valid direction rem by column then by row check_column_1 if player1x<>17 then goto check_column_2 if player1y<>16 then goto check_c1r32 if u>player1y then r=4: goto exit_choosedir if t>player1x then r=2: goto exit_choosedir check_c1r32 if player1y<>32 then goto check_c1r48 if u>player1y then r=4: goto exit_choosedir if uplayer1x then r=2: goto exit_choosedir check_c1r48 if player1y<>48 then goto check_c1r64 if u>player1y then r=4: goto exit_choosedir if uplayer1x then r=2: goto exit_choosedir check_c1r64 if player1y<>64 then goto check_c1r80 if u>player1y then r=4: goto exit_choosedir if uplayer1x then r=2: goto exit_choosedir check_c1r80 if player1y<>80 then goto exit_choosedir if uplayer1x then r=2: goto exit_choosedir goto exit_choosedir check_column_2 if player1x<>77 then goto check_column_3 if player1y<>16 then goto check_c2r32 if u>player1y then r=4: goto exit_choosedir if tplayer1x then r=2: goto exit_choosedir check_c2r32 if player1y<>32 then goto check_c2r48 if u>player1y then r=4: goto exit_choosedir if uplayer1x then r=2: goto exit_choosedir check_c2r48 if player1y<>48 then goto check_c2r64 if u>player1y then r=4: goto exit_choosedir if uplayer1x then r=2: goto exit_choosedir check_c2r64 if player1y<>64 then goto check_c2r80 if u>player1y then r=4: goto exit_choosedir if uplayer1x then r=2: goto exit_choosedir check_c2r80 if player1y<>80 then goto exit_choosedir if uplayer1x then r=2: goto exit_choosedir goto exit_choosedir check_column_3 if player1x<>137 then goto exit_choosedir if player1y<>16 then goto check_c3r32 if u>player1y then r=4: goto exit_choosedir if t32 then goto check_c3r48 if u>player1y then r=4: goto exit_choosedir if u48 then goto check_c3r64 if u>player1y then r=4: goto exit_choosedir if u64 then goto check_c3r80 if u>player1y then r=4: goto exit_choosedir if u80 then goto exit_choosedir if u137 then player1x=137 if player1y<16 then player1y=16 if player1y>80 then player1y=80 rem store values for virtual sprites if !b{2} then x=player1x : y=player1y : d=r : goto main if b{2} then v=player1x : w=player1y : q=r if player1x=t && player1y=u then s=s+1 : rem arrived at waypoint if s>14 then s=1 goto main game_over ;*************************************************************** ; ; Clears the playfield. ; pfclear ;*************************************************************** ; ; Mutes volume of both sound channels. ; AUDV0 = 0 : AUDV1 = 0 ;*************************************************************** ; ; Clears all normal variables and the extra 9. ; a = 0 : b = 0 : c = 0 : d = 0 : e = 0 : f = 0 : g = 0 : h = 0 : i = 0 j = 0 : k = 0 : l = 0 : m = 0 : n = 0 : o = 0 : p = 0 : q = 0 : r = 0 s = 0 : t = 0 : u = 0 : v = 0 : w = 0 : x = 0 : y = 0 : z = 0 var0 = 0 : var1 = 0 : var2 = 0 : var3 = 0 : var4 = 0 var5 = 0 : var6 = 0 : var7 = 0 : var8 = 0 player0x=0:player0y=0 player1x=0:player1y=0 pfcolors: 212 212 212 212 212 212 212 212 212 212 $1A end playfield: ................................ ................................ ................................ ......XXX..X...X.XXXX.XXX....... .....X...X.X...X.X....X..X...... .....X...X.X...X.XXX..XXX....... .....X...X.X...X.X....X..X...... ......XXX...XXX..XXXX.X..X...... ................................ ................................ ................................ end rem Loop the screen until the spacebar is pressed go_loop drawscreen if joy0fire then goto re_start goto go_loop