;``````````````````````````````````````````````````````````````` ; ; Special thanks below for the smaple codes on Batari Basic ; hints, tips, code snippets, and more from AtariAge members ; such as batari, SeaGtGruff, RevEng, Robert M, Nukey Shay, ; Atarius Maximus, jrok, supercat, GroovyBee, and bogax. ; code snippets from Atarius Maximus's "GTA style game" ; code snippets from Quad Runner's "move_around_rooms" ; code snippets from Stargunner's "Space dungeon" ; code snippets from Mountain King "GizzlewapG16" ; sprite codes from PAC-MAN-RED ; sprites codes from GoB! Fight for the Desert Patrick Jahn, Greg Kinsey, John Swisshelm ; code snippets from atari2600land's Batarti Man! ; Collision function for multi sprites By Xan, February 16 in batari Basic ; code below complied together by Lewis2907 to make Pac-Man Eat and Run "DPC" ; game concept based off the Pac Man Table Top version around 1981 ; YouTube Table Top PacMan Video https://www.youtube.com/watch?v=SuYGvCwL8hc ; ;``````````````````````````````````````````````````````````````` ;*************************************************************** ; ; If this program will not compile for you, get the latest ; version of batari Basic: ; ; http://www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#gettingstarted ; ;``````````````````````````````````````````````````````````````` ;*************************************************************** ; ; Kernel setup. ; includesfile multisprite_bankswitch.inc include fixed_point_math.asm set tv ntsc set kernel multisprite set romsize 32kSC set optimization speed set smartbranching on set optimization noinlinedata set optimization inlinerand ;**************************************************************** ; ; Player0-4 fixed point variables for more flexibility in ; gameplay mechanics. ; "c" is used in joy0 checks for last movement ; dim _P0_L_R = player0x.a dim _P0_U_D = player0y.b dim _P1_L_R = player1x.d dim _P1_U_D = player1y.e dim _P2_L_R = player2x.f dim _P2_U_D = player2y.g dim _P3_L_R = player3x.h dim _P3_U_D = player3y.i dim _P4_L_R = player4x.j dim _P4_U_D = player4y.k ;**************************************************************** ; ; Flips player0 sprite when necessary. ; dim _Bit6_Flip_P0 = l ;**************************************************************** ; ; Player0/player1 direction bits. ; dim _BitO_P0_Direction = m dim _Bit0_P0_Floor = n ;**************************************************************** ; ; Animation counters. ; dim _Master_Counter = o dim _Frame_Counter = p ;``````````````````````````````````````````````````````````````` ; Ghost AI ; Value "y" used for collision ; dim Red_Ghost = w dim Room = z ;**************************************************************** ; ; set screenheight and pixels ; pfheight=1 const screenheight = 80 ;**************************************************************** ; ; set playfield colors ; COLUPF = $86 : COLUBK = 00 : gosub rs0 bank7 ;**************************************************************** ; ; set players locations ; player0x = 77 : player0y = 46 player1x = 28 : player1y = 72 ; Red Ghost player2x = 141 : player2y = 30 ; Blue Ghost player3x = 28 : player3y = 16 ; Pink Ghost player4x = 141 : player4y = 16 ; Orange Ghost ;**************************************************************** ; ; Set up playfield and players ; gosub __Frame_LR_01 gosub __Red_Ghost_Left bank7 : gosub __Blue_Ghost_Left bank7 gosub __Pink_Ghost_Left bank7 : gosub __Orange_Ghost_Left bank7 ;**************************************************************** ; ; Set player positions (Test Screen Postions here) ; Center Floor is _Bit0_P0_Floor = 3 ; must use this for the calulations to work correctly ; _Bit0_P0_Floor = 3 ;*************************************************************** ;*************************************************************** ; ; PROGRAM START/RESTART ; __Start_Restart ;*************************************************************** ;*************************************************************** ; ; MAIN LOOP (MAKES THE PROGRAM GO) ; Also used for unpause the game ; __Main_Loop ;*************************************************************** ; ; Sets Player colors. Must always be within the "Main Loop" ; COLUP0 = $1C : COLUP1 = $44 : _COLUP1 = $44 COLUP2 = $82 : COLUP3 = $4E : COLUP4 = $3A ;*************************************************************** ; ; Controls animation speed. ; _Master_Counter = _Master_Counter + 1 if _Master_Counter < 4 then goto __Skip_Frame_Counter _Frame_Counter = _Frame_Counter + 1 : _Master_Counter = 0 if _Frame_Counter > 3 then _Frame_Counter = 0 __Skip_Frame_Counter ; ********************************** ; Ghost AI ; ; if Room = 0 then gosub __AI_Controls_Room_0 bank7 ;*************************************************************** ; ; Player0 Controls ; gosub __Pac_Man_Controls ;**************************************************************** ; ; Flips player0 sprite when necessary. ; if _Bit6_Flip_P0{6} then REFP0 = 8 ;``````````````````````````````````````````````````````````````` ; Sprite animation. ; if c{1} then on _Frame_Counter gosub __Frame_U_00 __Frame_U_01 __Frame_U_02 __Frame_U_01 if c{2} then on _Frame_Counter gosub __Frame_D_00 __Frame_D_01 __Frame_D_02 __Frame_D_01 if c{3} then on _Frame_Counter gosub __Frame_LR_00 __Frame_LR_01 __Frame_LR_02 __Frame_LR_01 if c{4} then on _Frame_Counter gosub __Frame_LR_00 __Frame_LR_01 __Frame_LR_02 __Frame_LR_01 ;*************************************************************** ; ; Collision of sprites and points ; Collision function for multi sprites By Xan, February 16 in batari Basic ; colidir ; y = colide(player0x, player1x, player0y, player1y) ; if y then player1x = (rand&127)+20 y = colide(player0x, player2x, player0y, player2y) if y then player2x = (rand&127)+20 y = colide(player0x, player3x, player0y, player3y) if y then player3x = (rand&127)+20 y = colide(player0x, player4x, player0y, player4y) if y then player4x = (rand&127)+20 y = colide(player0x, player5x, player0y, player5y) if y then player5x = (rand&127)+20 ;*************************************************************** ; ; Displays the screen. ; drawscreen ;*************************************************************** ; ; Return to the start of the "__Main_Loop" ; goto __Main_Loop ;*************************************************************** ; ; player0x = 76 : player0y = 54 : Center of screen ; player0x = 32 : player0y = 54 : Center far left ; player0x = 112 : player0y = 54 : Center far right ; Center Floor is _Bit0_P0_Floor = 3 ; __Pac_Man_Controls ;*************************************************************** ; ; Select the correct floor based on player0y positions ; ; Level 1 y axis = 73 ; Level 2 y axis = 60 ; Level 3 y axis = 46 ; Level 4 y axis = 32 ; Level 5 y axis = 18 ; ; Left Playfield X = 19 ; Right Playfield x = 132 ; ; player0x = 77 : player0y = 46 ; Pac Center of screen ; if _Bit0_P0_Floor = 1 then gosub __1F_L1 bank2 if _Bit0_P0_Floor = 2 then gosub __2F_L1 bank2 if _Bit0_P0_Floor = 3 then gosub __3F_L1 bank2 if _Bit0_P0_Floor = 4 then gosub __4F_L1 bank2 if _Bit0_P0_Floor = 5 then gosub __5F_L1 bank2 return ;*************************************************************** ; ; Collision of sprites and points ; Collision function for multi sprites By Xan, February 16 in batari Basic ; function colide y = temp1 + 9: x = temp2 - 7 if y > x && temp1 < temp2 then y = temp3 -13: x = temp4 -10: if temp3 > x && y < temp4 then return 1 return 0 rem p0 width 9, p0 height -13 rem px width -7, px height -10 ;**************************************************************** ; ; Left/right animation frames for player. ; __Frame_LR_00 player0: %01111100 %11111110 %11111110 %11111110 %11111110 %11011110 %11111110 %01111100 end return __Frame_LR_01 player0: %01111100 %11111110 %11111000 %11100000 %11111000 %11011110 %11111110 %01111100 end return __Frame_LR_02 player0: %01111100 %11111000 %11110000 %11100000 %11100000 %11010000 %11111000 %01111100 end return ;**************************************************************** ; ; Down animation frames for player. ; __Frame_D_00 player0: %01101100 %11101110 %11101110 %11111110 %11111110 %11111010 %11111110 %01111100 end return __Frame_D_01 player0: %01000100 %11000110 %11101110 %11101110 %11101110 %11111010 %11111110 %01111100 end return __Frame_D_02 player0: %00000000 %10000010 %11000110 %11101110 %11101110 %11111010 %11111110 %01111100 end return ;**************************************************************** ; ; Up animation frames for player. ; __Frame_U_00 player0: %01111100 %11111110 %11111010 %11111110 %11111110 %11101110 %11101110 %01101100 end return __Frame_U_01 player0: %01111100 %11111110 %11111010 %11101110 %11101110 %11101110 %11000110 %01000100 end return __Frame_U_02 player0: %01111100 %11111110 %11111010 %11101110 %11101110 %11000110 %10000010 %00000000 end return ; ****************************** ; ****End Bank 1 *************** ; ****************************** ; ****************************** ; ****Start Bank 2 ************* ; ****************************** bank 2 ; ****************************** ; ****End Bank 2 *************** ; ****************************** ; ****************************** ; ****Start Bank 3 ************* ; ****************************** __1F_L1 ;*************************************************************** ; ; Allows player0 to move down to a level 2 ; if player0x = 19 && player0y <= 73 then gosub __Down bank6 if player0x = 76 && player0y <= 73 then gosub __Down bank6 if player0x = 132 && player0y <= 73 then gosub __Down bank6 if player0y = 60 then _Bit0_P0_Floor = 2 : return otherbank if player0y < 73 then return otherbank ;*************************************************************** ; ; Sets player0 left side limits based off of playfiield ; gosub __Long_Floor bank6 return otherbank __2F_L1 ;*************************************************************** ; ; Allows player0 to move up to a level 1 ; if player0x = 19 && player0y >= 60 then gosub __Up bank6 if player0x = 76 && player0y >= 60 then gosub __Up bank6 if player0x = 132 && player0y >= 60 then gosub __Up bank6 if player0y = 73 then _Bit0_P0_Floor = 1 : return otherbank if player0y > 60 then return otherbank ;*************************************************************** ; ; Allows player0 to move down to a level 3 ; if player0x = 44 && player0y <= 60 then gosub __Down bank6 if player0x = 109 && player0y <= 60 then gosub __Down bank6 if player0y = 46 then _Bit0_P0_Floor = 3 : return otherbank if player0y < 60 then return otherbank ;*************************************************************** ; ; Sets player0 left side limits based off of playfiield ; gosub __Long_Floor bank6 return otherbank ;*************************************************************** ; ; 3rd Floor ***Always the starting point. Even after death** ; If the joystick isn't moved then skip this section and return ; __3F_L1 ;*************************************************************** ; ; Allows player0 to move up to a level 2 ; if player0x = 44 && player0y >=46 then gosub __Up bank6 if player0x = 109 && player0y >=46 then gosub __Up bank6 if player0y = 60 then _Bit0_P0_Floor = 2 : return otherbank if player0y > 46 then return otherbank ;*************************************************************** ; ; Allows player0 to move down to a level 4 ; if player0x = 44 && player0y <= 46 then gosub __Down bank6 if player0x = 109 && player0y <= 46 then gosub __Down bank6 if player0y = 32 then _Bit0_P0_Floor = 4 : return otherbank if player0y < 46 then return otherbank ;*************************************************************** ; ; Sets player0 left and rights limits based off of playfiield ; gosub __Long_Floor bank6 return otherbank ;*************************************************************** ; ; Sets player0 left and rights warp location "Middle of Screen" ; ;if player0x = 133 && joy0right then _Bit6_Flip_P0{6} = 0 : _BitO_P0_Direction = 5 : gosub __Right_Warp bank6 ;if _BitO_P0_Direction = 5 then gosub __Right_Warp bank6 ;if player0x = 19 && joy0left then _Bit6_Flip_P0{6} = 1 : _BitO_P0_Direction = 6 : gosub __Left_Warp bank6 ;if _BitO_P0_Direction = 6 then gosub __Left_Warp bank6 ;*************************************************************** ; ; Sets player0 left and rights correct direction after warp ; location "Middle of Screen" ; ;if c{3} && player0x = 133 then gosub __Static_Player bank6 ;if c{4} && player0x = 19 then gosub __Static_Player bank6 __4F_L1 ;*************************************************************** ; ; Allows player0 to move up to a level3 ; if player0x = 44 && player0y >= 32 then gosub __Up bank6 if player0x = 109 && player0y >= 32 then gosub __Up bank6 if player0y = 46 then _Bit0_P0_Floor = 3 : return otherbank if player0y > 32 then return otherbank ;*************************************************************** ; ; Allows player0 to move down to a level 5 ; if player0x = 19 && player0y <= 32 then gosub __Down bank6 if player0x = 77 && player0y <= 32 then gosub __Down bank6 if player0x = 132 && player0y <= 32 then gosub __Down bank6 if player0y = 18 then _Bit0_P0_Floor = 5 : return otherbank if player0y < 32 then return otherbank ;*************************************************************** ; ; Sets player0 left side limits based off of playfiield ; gosub __Long_Floor bank6 return otherbank __5F_L1 ;*************************************************************** ; ; Allows player0 to move up to a level4 ; if player0x = 19 && player0y >= 18 then gosub __Up bank6 if player0x = 77 && player0y >= 18 then gosub __Up bank6 if player0x = 132 && player0y >= 18 then gosub __Up bank6 if player0y = 32 then _Bit0_P0_Floor = 4 : return if player0y > 18 then return otherbank ;*************************************************************** ; ; Sets player0 left side limits based off of playfiield ; gosub __Long_Floor bank6 return otherbank bank 3 ; ****************************** ; ****End Bank 3 *************** ; ****************************** ; ****************************** ; ****Start Bank 4 ************* ; ****************************** bank 4 ; ****************************** ; ****End Bank 4 *************** ; ****************************** ; ****************************** ; ****Start Bank 5 ************* ; ****************************** bank 5 ; ****************************** ; ****End Bank 5 *************** ; ****************************** ; ****************************** ; ****Start Bank 6 ************* ; ****************************** bank 6 ;*************************************************************** ; ; Common Controls there are defined stopping points ; __Left if joy0left then c{1}=0:c{2}=0:c{3}=1:c{4}=0:c{5}=0:c{6}=0:c{7}=0:c{0}=0 : _BitO_P0_Direction = 2 if _BitO_P0_Direction = 2 then _P0_L_R = _P0_L_R - .5 if player0x = 19 && joy0left then c{1}=0:c{2}=0:c{3}=1:c{4}=0:c{5}=0:c{6}=0:c{7}=0:c{0}=0 : return if player0x = 133 && joy0right then c{1}=0:c{2}=0:c{3}=0:c{4}=1:c{5}=0:c{6}=0:c{7}=0:c{0}=0 : return return __Right if joy0right then c{1}=0:c{2}=0:c{3}=0:c{4}=1:c{5}=0:c{6}=0:c{7}=0:c{0}=0 : _BitO_P0_Direction = 1 if _BitO_P0_Direction = 1 then _P0_L_R = _P0_L_R + .5 if player0x = 19 && joy0left then c{1}=0:c{2}=0:c{3}=1:c{4}=0:c{5}=0:c{6}=0:c{7}=0:c{0}=0 : return if player0x = 133 && joy0right then c{1}=0:c{2}=0:c{3}=0:c{4}=1:c{5}=0:c{6}=0:c{7}=0:c{0}=0 : return return __Up if joy0up then c{1}=1:c{2}=0:c{3}=0:c{4}=0:c{5}=0:c{6}=0:c{7}=0:c{0}=0 : _BitO_P0_Direction = 3 if _BitO_P0_Direction = 3 then _P0_U_D = _P0_U_D + .5 return __Down if joy0down then c{1}=0:c{2}=1:c{3}=0:c{4}=0:c{5}=0:c{6}=0:c{7}=0:c{0}=0 : _BitO_P0_Direction = 4 if _BitO_P0_Direction = 4 then _P0_U_D = _P0_U_D - .5 return __Left_Right if player0x = 19 && joy0left then c{1}=0:c{2}=0:c{3}=1:c{4}=0:c{5}=0:c{6}=0:c{7}=0:c{0}=0 : return if player0x = 133 && joy0right then c{1}=0:c{2}=0:c{3}=0:c{4}=1:c{5}=0:c{6}=0:c{7}=0:c{0}=0 : return if joy0left then c{1}=0:c{2}=0:c{3}=1:c{4}=0:c{5}=0:c{6}=0:c{7}=0:c{0}=0 : _BitO_P0_Direction = 1 : _Bit6_Flip_P0{6} = 1 if joy0right then c{1}=0:c{2}=0:c{3}=0:c{4}=1:c{5}=0:c{6}=0:c{7}=0:c{0}=0 : _BitO_P0_Direction = 2 : _Bit6_Flip_P0{6} = 0 if _BitO_P0_Direction = 1 then _P0_L_R = _P0_L_R - .5 if _BitO_P0_Direction = 2 then _P0_L_R = _P0_L_R + .5 return ;*************************************************************** ; ; left / right warp / exit "Middle of Screen" ; __Right_Warp _P0_L_R = _P0_L_R + .2 if player0x = 140 then player0x = 14 if player0x = 19 then _BitO_P0_Direction = 2 return __Left_Warp _P0_L_R = _P0_L_R - .2 if player0x = 14 then player0x = 140 if player0x = 133 then _BitO_P0_Direction = 1 return __Static_Player return __Long_Floor ;*************************************************************** ; ; Sets player0 left and rights limits based off of playfiield ; if player0x > 18 && player0x < 133 then gosub __Left_Right if player0x = 18 then gosub __Right if player0x = 133 then gosub __Left return ; ****************************** ; ****End Bank 6 *************** ; ****************************** ; ****************************** ; ****Start Bank 7 ************* ; ****************************** bank 7 __AI_Controls_Room_0 ;*************************************************************** ; ; Allows players 1-4 to move up and down ; Use exact coordinates as they will be on "Auto Pilot" ; ; 1 = up 2 = down ; 3 = left 4 = right ; ; Notice that adding a number changes the minimum and maximum numbers. ; For example, a = (rand&7) + 8 would give you a random number between 8 and 15 (7 + 8 = 15) ; ;*************************************************************** ;*************************************************************** ; ; Floor 1 for AI ; if player1x = 28 && player1y = 72 then Red_Ghost = (rand&2)+2 : if Red_Ghost = 3 then return ; choose 2, 4 (D R) if player1x = 84 && player1y = 72 then Red_Ghost = (rand&3)+1 : if Red_Ghost = 1 then return ; choose 2, 3, 4 (D L R) if player1x = 141 && player1y = 72 then Red_Ghost = (rand&2)+2 : if Red_Ghost = 4 then return ; choose 2, 3 (D L) ;*************************************************************** ; ; Floor 2 for AI ; if player1x = 28 && player1y = 58 then Red_Ghost = (rand&1)+4 : if Red_Ghost = 5 then Red_Ghost = 1 ; choose 1, 4 (U R) if player1x = 53 && player1y = 58 then Red_Ghost = (rand&3)+1 : if Red_Ghost = 1 then return ; choose 2, 3, 4 (D L R) if player1x = 84 && player1y = 58 then Red_Ghost = (rand&3)+1 : if Red_Ghost = 2 then return ; choose 1, 3, 4 (U L R) if player1x = 117 && player1y = 58 then Red_Ghost = (rand&3)+1 : if Red_Ghost = 1 then return ; choose 2, 3, 4 (D L R) if player1x = 141 && player1y = 58 then Red_Ghost = (rand&2)+1 : if Red_Ghost = 1 then return ; choose 2, 3 (U L) ;*************************************************************** ; ; Floor 3 for AI ; if player1x = 28 && player1y = 44 then Red_Ghost = 4 ; choose 4 ( R ) if player1x = 53 && player1y = 44 then Red_Ghost = (rand&3)+1 ; choose 1, 2, 3, 4 (D L R) if player1x = 117 && player1y = 44 then Red_Ghost = (rand&3)+1 ; choose 1, 2, 3, 4 (D L R) if player1x = 141 && player1y = 44 then Red_Ghost = 3 ; choose 4 ( L ) ;*************************************************************** ; ; Floor 4 for AI ; if player1x = 28 && player1y = 30 then Red_Ghost = (rand&1)+4 : if Red_Ghost = 5 then Red_Ghost = 2 ; choose 2, 4 (D R) if player1x = 53 && player1y = 30 then Red_Ghost = (rand&3)+1 : if Red_Ghost = 2 then return ; choose 1, 3, 4 (U L R) if player1x = 84 && player1y = 30 then Red_Ghost = (rand&3)+1 : if Red_Ghost = 1 then return ; choose 2, 3, 4 (D L R) if player1x = 117 && player1y = 30 then Red_Ghost = (rand&3)+1 : if Red_Ghost = 2 then return ; choose 1, 3, 4 (U L R) if player1x = 141 && player1y = 30 then Red_Ghost = (rand&2)+2 : if Red_Ghost = 4 then return ; choose 2, 3 (D L) ;*************************************************************** ; ; Floor 5 for AI ; if player1x = 28 && player1y = 16 then Red_Ghost = (rand&1)+4 : if Red_Ghost = 5 then Red_Ghost = 1 ; choose 1, 4 (U R) if player1x = 84 && player1y = 16 then Red_Ghost = (rand&3)+1 : if Red_Ghost = 2 then return ; choose 1, 3, 4 (U L R) if player1x = 141 && player1y = 16 then Red_Ghost = (rand&2)+1 : if Red_Ghost = 1 then return ; choose 2, 3 (U L) ;*************************************************************** ; ; Move ghost on auto pilot ; if Red_Ghost = 1 then _P1_U_D = _P1_U_D + .75 ; go up if Red_Ghost = 2 then _P1_U_D = _P1_U_D - .75 ; go down if Red_Ghost = 3 then _P1_L_R = _P1_L_R - .75 ; go left if Red_Ghost = 4 then _P1_L_R = _P1_L_R + .75 ; go right return ;**************************************************************** ; ; Red Ghost / Player1 moves left ; __Red_Ghost_Left player1: %10101010 %11111110 %11111110 %10101110 %10101110 %11111110 %11111110 %01111100 end return ;**************************************************************** ; ; Blue Ghost / Player2 moves left ; __Blue_Ghost_Left player2: %10101010 %11111110 %11111110 %10101110 %10101110 %11111110 %11111110 %01111100 end return ;**************************************************************** ; ; Pink Ghost / Player3 moves left ; __Pink_Ghost_Left player3: %10101010 %11111110 %11111110 %10101110 %10101110 %11111110 %11111110 %01111100 end return ;**************************************************************** ; ; Blue Ghost / Player4 moves left ; __Orange_Ghost_Left player4: %10101010 %11111110 %11111110 %10101110 %10101110 %11111110 %11111110 %01111100 end return rs0 playfield: ........X....... ................ XXXXXXXXXXXXXXX. X............... X............... X............... X............... X............... X............... X..XXXXXXXXXXXX. X............... X............... X............... X............... X............... X............... XXXXXXX..XXXXXXX ................ ................ ................ ................ ................ ................ XXXXXXX..XXXXXXX X............... X............... X............... X............... X............... X............... X..XXXXXXXXXXXX. X............... X............... X............... X............... X............... X............... XXXXXXXXXXXXXXX. ................ ........X....... end return ; ****************************** ; ****End Bank 7 *************** ; ****************************** ; ****************************** ; ****Start Bank 8 ************* ; ****************************** bank 8 ;**************************************************************** ; If you are using the multisprite kernel, you can use a special pfread module, ; called pfread_msk.asm, made just for this kernel. It is not enabled by default. ; To enable it, you can use the include or inline command in a 2K or 4K game. For a bankswitched game, ; only the inline command will work, and the command must be placed in the last bank. ; inline pfread_msk.asm ; ****************************** ; ****End Bank 8 *************** ; ******************************