;*************************************************************** ; ; Astronomer 2018 ; ; A game by Coolcrab. ; ;*************************************************************** ;*************************************************************** ; ; Kernel options for this game. ; set kernel_options no_blank_lines readpaddle ;*************************************************************** ; ; Variable aliases go here (DIMs). ; ; If you think you'll ever want anyone to help with your code, ; be sure to have an alias for every variable that is used in ; your program. Your aliases should be near the beginning of ; your code (so they will be easy to find) and the list should ; be in alphabetical order (so it will be easy to see how many ; variables are free to use). Example: ; ; dim _Broomstick = a ; dim _Flying_Monkey = b ; dim _Auntie_Em = c ; dim _Scarecrow_Dance = d ; ; When every variable has an alias and all aliases are near ; the beginning of your program in an alphabetical list, you ; (and anyone else that might have to read your code) will be ; able to easily see the variables you are using and which ; variables are free to use. Please do not sprinkle DIMs ; throughout your code. Keep them all together in an ; alphabetical list near the beginning of your program. ; ; I put one underscore in front of variable aliases and two ; underscores in front of labels. Then I don't have to worry ; if I'm using a bB keyword by mistake and I'll never have to ; worry if a label has the same name as a variable alias. ; ; You can have more than one alias for each variable. ; If you use different aliases for bit operations, ; it's easier to understand and remember what they do. ; ; Use bit operations any time you need a simple off/on ; variable. One variable essentially becomes 8 smaller ; variables when you use bit operations. ; ; I start my bit aliases with "_Bit" then follow that ; with the bit number from 0 to 7, then another underscore ; and the name. Example: _Bit0_Reset_Restrainer ; ;``````````````````````````````````````````````````````````````` dim _error_accumulator = a ;``````````````````````````````````````````````````````````````` ; Title screen color variable (reused variables). ; dim _TS_P0_Luminosity = a.b dim _delta_y = b dim _delta_x = c ;``````````````````````````````````````````````````````````````` ; Title screen sprite display order (reused variable). ; dim _TS_Sprite_Display_Order = c dim _octant = d ;``````````````````````````````````````````````````````````````` ; Title screen 2 second timer (reused variable). ; dim _TS_Timer = d dim _Star_Cloud_Slowdown = e ;``````````````````````````````````````````````````````````````` ; Title screen highest brightness (reused variable). ; dim _TS_Hue_Brightness_High = e dim _Star_Integrate = f dim _xpos = g ;``````````````````````````````````````````````````````````````` ; Title screen lowest brightness (reused variable). ; dim _TS_Hue_Brightness_Low = g dim _ypos = h ;``````````````````````````````````````````````````````````````` ; Title screen color hold counter (reused variable). ; dim _TS_Color_Hold = h dim _Cloud_Integrate = i dim _Cloud_Type = j dim _Cloud_Velocity = k dim _Jump_Pointer = l dim _Mem_x1 = m dim _Mem_y1 = n dim _Telelescope_Point_Horiz = o dim _Telelescope_Point_Vert = p dim _Ch0_Sound = q dim _Satellite = q dim _Ch0_Duration = r dim _V0 = s dim _Ch1_Sound = t dim _Ch1_Duration = u dim _V1 = v ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;``````````````````````````````````````````````````````````````` ; Bits for various jobs. ; dim _BitOp_01 = w ;``````````````````````````````````````````````````````````````` ; This bit restrains the reset switch. ; dim _Bit0_Reset_Restrainer = w ;``````````````````````````````````````````````````````````````` ; This bit restrains the fire button. ; dim _Bit1_FireB_Restrainer = w ;``````````````````````````````````````````````````````````````` ; This bit restrains the select switch. ; dim _Bit2_Select_Restrainer = w ;``````````````````````````````````````````````````````````````` ; This bit is used to flip the score on the title screen. ; dim _Bit3_TS_Swap_Scores = w ;``````````````````````````````````````````````````````````````` ; This bit is used for color cycling on the title screen. ; dim _Bit4_TS_Sequence_Switch = w ;``````````````````````````````````````````````````````````````` ; Game lost! Tells the title screen to play a sound. ; dim _Bit6_Game_Lost = w ;``````````````````````````````````````````````````````````````` ; Mode bit (changed using select switch on title screen). ; this bit is used in the title screen loop and the main loop, ; so don't clear it. ; dim _Bit7_Mode = w dim _Level = x dim _Highest_Level = y dim rand16 = z dim _sc1 = score dim _sc2 = score+1 dim _sc3 = score+2 dim _x1 = temp1 dim _x0 = temp2 dim _y1 = temp3 dim _ep = temp3 dim _y0 = temp4 dim xinc = temp4 dim yinc = temp5 ;*************************************************************** ; ; Enables pfscore bars. ; const pfscore = 1 ;*************************************************************** ;*************************************************************** ; ; PROGRAM START/RESTART ; ; __Start_Restart ;*************************************************************** ; ; Mutes volume of both sound channels. ; AUDV0 = 0 : AUDV1 = 0 ;*************************************************************** ; ; Clears most normal variables (fastest way using asm). ; gosub __Clear_Variables ;*************************************************************** ;*************************************************************** ; ; TITLE SCREEN SETUP ; ; __Title_Screen_Setup ;*************************************************************** ; ; Gets rid of score bar. ; pfscore1 = 0 ;*************************************************************** ; ; Defines the highest brightness. ; _TS_Hue_Brightness_High = $0C ;*************************************************************** ; ; Defines the lowest brightness. ; _TS_Hue_Brightness_Low = $04 ;*************************************************************** ; ; Sets the luminosity variable. ; _TS_P0_Luminosity = $02 ;*************************************************************** ; ; Restrains the reset switch. ; ; This bit fixes it so the reset switch becomes inactive if ; it hasn't been released after entering a different segment ; of the program. It also does double duty by restraining the ; fire button in the title screen loop. ; _Bit0_Reset_Restrainer{0} = 1 ;*************************************************************** ; ; Turns on sound if player ran out of time. ; if _Bit6_Game_Lost{6} then _Ch0_Sound = 2 : _Ch0_Duration = 30 : _V0 = 12 ;*************************************************************** ; ; Sets up title screen playfield. ; playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XX............................XX XX............................XX XX............................XX XX............................XX XX............................XX XX............................XX XX............................XX XX............................XX XX............................XX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end ;*************************************************************** ;*************************************************************** ; ; TITLE SCREEN LOOP ; ; __Title_Screen_Loop ;*************************************************************** ; ; Color cycling. ; ;``````````````````````````````````````````````````````````````` ; Brightness increase section. (When switch bit is off.) ; Skips to brightness decrease section if switch bit is on. ; if _Bit4_TS_Sequence_Switch{4} then goto __Switch_Bit_On ;``````````````````````````````````````````````````````````````` ; Increases the luminosity variable if it's not time to hold. ; if !_TS_Color_Hold then _TS_P0_Luminosity = _TS_P0_Luminosity + 0.22 ;``````````````````````````````````````````````````````````````` ; If luminosity variable reaches highest defined brightness, ; the hold counter is activated. ; if !_TS_Color_Hold && _TS_P0_Luminosity >= _TS_Hue_Brightness_High then _TS_Color_Hold = 30 ;``````````````````````````````````````````````````````````````` ; The switch bit is turned on and the hue is changed for the ; next loop around if luminosity variable reaches highest ; defined brightness when the hold is over. ; if _TS_Color_Hold then _TS_Color_Hold = _TS_Color_Hold - 1 : if !_TS_Color_Hold then _Bit4_TS_Sequence_Switch{4} = 1 : _TS_Hue_Brightness_High = _TS_Hue_Brightness_High + $10 goto __Skip_Hue_Change ;``````````````````````````````````````````````````````````````` ; Brightness decrease section. (When switch bit is on.) ; __Switch_Bit_On ;``````````````````````````````````````````````````````````````` ; Decreases the luminosity variable if it's not time to hold. ; if !_TS_Color_Hold then _TS_P0_Luminosity = _TS_P0_Luminosity - 0.22 ;``````````````````````````````````````````````````````````````` ; If luminosity variable reaches lowest defined brightness, ; the hold counter is activated. ; if !_TS_Color_Hold && _TS_P0_Luminosity <= _TS_Hue_Brightness_Low then _TS_Color_Hold = 8 ;``````````````````````````````````````````````````````````````` ; The switch bit is turned off, the hue is changed, and the ; luminosity variable is updated if luminosity variable ; reaches lowest defined brightness when the hold is over. ; if _TS_Color_Hold then _TS_Color_Hold = _TS_Color_Hold - 1 : if !_TS_Color_Hold then _Bit4_TS_Sequence_Switch{4} = 0 : _TS_Hue_Brightness_Low = _TS_Hue_Brightness_Low + $10 : _TS_P0_Luminosity = _TS_Hue_Brightness_Low __Skip_Hue_Change ;*************************************************************** ; ; Flips between highest level and current level in the score. ; ;``````````````````````````````````````````````````````````````` ; Skips section if 2 seconds hasn't gone by. ; if _TS_Timer > 1 then _TS_Timer = _TS_Timer - 1 : goto __Skip_Score_Switch ;``````````````````````````````````````````````````````````````` ; Resets 2 second timer. ; _TS_Timer = 120 ;``````````````````````````````````````````````````````````````` ; Displays current level if swap bit is off. ; if !_Bit3_TS_Swap_Scores{3} then temp4 = _Level : scorecolor = $6C : _Bit3_TS_Swap_Scores{3} = 1 : goto __TS_Skip_HiScore_Swap ;``````````````````````````````````````````````````````````````` ; Displays highest level if swap bit is on. ; temp4 = _Highest_Level : scorecolor = $38 : _Bit3_TS_Swap_Scores{3} = 0 __TS_Skip_HiScore_Swap ;``````````````````````````````````````````````````````````````` ; Puts the current level or highest level in the score. ; _sc1 = 0 : _sc2 = _sc2 & 15 _sc2 = _sc2 & 240 : _sc3 = 0 if temp4 >= 100 then _sc2 = _sc2 + 1 : temp4 = temp4 - 100 if temp4 >= 100 then _sc2 = _sc2 + 1 : temp4 = temp4 - 100 if temp4 >= 50 then _sc3 = _sc3 + 80 : temp4 = temp4 - 50 if temp4 >= 30 then _sc3 = _sc3 + 48 : temp4 = temp4 - 30 if temp4 >= 20 then _sc3 = _sc3 + 32 : temp4 = temp4 - 20 if temp4 >= 10 then _sc3 = _sc3 + 16 : temp4 = temp4 - 10 _sc3 = _sc3 | temp4 __Skip_Score_Switch ;*************************************************************** ; ; Sets playfield and sprite colors. ; COLUPF = _TS_P0_Luminosity : COLUP0 = _TS_P0_Luminosity : COLUP1 = _TS_P0_Luminosity ;*************************************************************** ; ; Displays the screen. ; drawscreen ;*************************************************************** ; ; Displays the first part of title. ; if _TS_Sprite_Display_Order then goto __Skip_Set_0 player0: %00000000 %10101100 %10100100 %11101100 %10101000 %11101101 %00000000 %00000000 end player1: %00000000 %00000000 %00000000 %00000011 %00000010 %00000010 %00000001 %00000011 %00000000 %10010101 %10010101 %10011001 %10010101 %11011001 %00000000 %00000000 end player0x = 60 : player0y = 45 : player1x = 68 : player1y = 53 : _TS_Sprite_Display_Order = 1 goto __Skip_Title_Sprites __Skip_Set_0 ;*************************************************************** ; ; Displays the second part of title. ; if _TS_Sprite_Display_Order > 1 then goto __Skip_Set_1 player0: %00000000 %00000000 %00000000 %01110101 %01010101 %01010101 %01010101 %01110101 %00000000 %11010101 %01010101 %01010101 %01010101 %11011101 %00000000 %00000000 end player1: %00000000 %00000000 %00000000 %11000000 %01000000 %11000000 %01000000 %11000000 %00000000 %11010001 %01010001 %01010001 %01010101 %11011111 %00000000 %00000000 end player0x = 76 : player0y = 53 : player1x = 84 : player1y = 53 : _TS_Sprite_Display_Order = 2 goto __Skip_Title_Sprites __Skip_Set_1 ;*************************************************************** ; ; Displays the third part of title. ; if _TS_Sprite_Display_Order <> 2 then goto __Skip_Title_Sprites player0: %00000000 %01101010 %01001010 %01101100 %01001010 %01101100 %00000000 %00000000 end player0x = 92 : player0y = 45 : player1x = 76 : player1y = 65 : _TS_Sprite_Display_Order = 0 __Skip_Set_2 ;*************************************************************** ; ; Displays mode number 1. ; if _Bit7_Mode{7} then goto __Skip_Mode_01 player1: %00000000 %00000000 %00111000 %00010000 %00010000 %00110000 %00010000 %00000000 end goto __Skip_Title_Sprites __Skip_Mode_01 ;*************************************************************** ; ; Displays mode number 2. ; player1: %00000000 %00000000 %00111100 %00010000 %00001000 %00100100 %00011000 %00000000 end __Skip_Title_Sprites ;*************************************************************** ; ; Select switch section. ; if !switchselect then _Bit2_Select_Restrainer{2} = 0 : goto __Skip_Title_Select ;``````````````````````````````````````````````````````````````` ; Skips this section if restrainer bit is on. ; if _Bit2_Select_Restrainer{2} then goto __Skip_Title_Select ;``````````````````````````````````````````````````````````````` ; Flips the mode bit and turns on restrainer bit. ; _Bit7_Mode{7} = !_Bit7_Mode{7} : _Bit2_Select_Restrainer{2} = 1 ;``````````````````````````````````````````````````````````````` ; Turns on sound effect. ; _Ch0_Sound = 1 : _Ch0_Duration = 20 : _V0 = 8 __Skip_Title_Select ;*************************************************************** ; ; Channel 0 sound effect check. ; ;``````````````````````````````````````````````````````````````` ; Skips all channel 0 sounds if sounds are off. ; if !_Ch0_Sound then goto __TS_Skip_Ch_0 ;``````````````````````````````````````````````````````````````` ; Decreases the channel 0 duration counter. ; _Ch0_Duration = _Ch0_Duration - 1 ;``````````````````````````````````````````````````````````````` ; Turns off sound if channel 0 duration counter is zero. ; if !_Ch0_Duration then goto __TS_Clear_Ch_0 ;*************************************************************** ; ; Channel 0 title screen sound effect 001. ; ; Mode change. ; ;``````````````````````````````````````````````````````````````` ; Skips this section if sound 001 isn't on. ; if _Ch0_Sound <> 1 then goto __TS_Skip_Ch0_Sound_001 ;``````````````````````````````````````````````````````````````` ; Sets the tone, volume and frequency. ; AUDC0 = 2 : AUDV0 = _V0 : AUDF0 = 2 ;``````````````````````````````````````````````````````````````` ; Only looks at the even/odd bit. ; temp5 = _Ch0_Duration & %00000001 ;``````````````````````````````````````````````````````````````` ; Changes AUDF0 only when _Ch0_Duration is an odd number. ; if temp5 then AUDF0 = 3 ;``````````````````````````````````````````````````````````````` ; Decreases volume only when _Ch1_Duration is an odd number. ; if temp5 && _V0 then _V0 = _V0 - 1 ;``````````````````````````````````````````````````````````````` ; Jumps to end of channel 0 area. ; goto __TS_Skip_Ch_0 __TS_Skip_Ch0_Sound_001 ;*************************************************************** ; ; Channel 0 sound effect 002. ; ; Lose Star. ; ;``````````````````````````````````````````````````````````````` ; Skips this section if sound 003 isn't on. ; if _Ch0_Sound <> 2 then goto __TS_Skip_Ch0_Sound_002 ;``````````````````````````````````````````````````````````````` ; Sets the tone, volume and frequency. ; AUDC0 = 1 : AUDV0 = _V0 : AUDF0 = 11 : COLUPF = $40 ;``````````````````````````````````````````````````````````````` ; Only looks at the even/odd bit. ; temp5 = _Ch0_Duration & %00000001 ;``````````````````````````````````````````````````````````````` ; Changes AUDF0 only when _Ch0_Duration is an odd number. ; if temp5 then AUDF0 = 23 ;``````````````````````````````````````````````````````````````` ; Decreases volume only when _Ch0_Duration is an odd number. ; if temp5 && _V0 > 2 then _V0 = _V0 - 1 ;``````````````````````````````````````````````````````````````` ; Jumps to end of channel 0 area. ; goto __TS_Skip_Ch_0 __TS_Skip_Ch0_Sound_002 ;*************************************************************** ; ; Clears channel 0. ; __TS_Clear_Ch_0 _Ch0_Sound = 0 : AUDV0 = 0 ;*************************************************************** ; ; End of channel 0 area. ; __TS_Skip_Ch_0 ;*************************************************************** ; ; Reset/fire button check and end of title screen loop. ; ; Starts the game if the reset switch or the fire button ; is pressed appropriately. ; ;``````````````````````````````````````````````````````````````` ; Clears the restrainer bit and jumps to beginning of title ; screen loop if fire button or reset switch is not pressed. ; if !switchreset && !joy0fire && !joy0right then _Bit0_Reset_Restrainer{0} = 0 : goto __Title_Screen_Loop ;``````````````````````````````````````````````````````````````` ; Jumps to beginning of title screen loop if reset or fire ; hasn't been released since starting title screen loop. ; if _Bit0_Reset_Restrainer{0} then goto __Title_Screen_Loop ;``````````````````````````````````````````````````````````````` ; Starts the game if reset switch or fire button is pressed. ; goto __Main_Loop_Setup ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;``````````````````````````````````````````````````````````````` ; ; END OF TITLE SCREEN LOOP ; ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;``````````````````````````````````````````````````````````````` ;*************************************************************** ;*************************************************************** ; ; MAIN LOOP SETUP ; ; __Main_Loop_Setup ;*************************************************************** ; ; Clears most normal variables (fastest way using asm). ; Also clears 7 of the 8 bits of _BitOp_01 and clears _Level. ; _BitOp_01 = _BitOp_01 & %10000000 : _Level = 0 : gosub __Clear_Variables ;*************************************************************** ; ; Restrains the reset switch for the main loop. ; ; This bit fixes it so the reset switch becomes inactive if ; it hasn't been released after being pressed once. ; _Bit0_Reset_Restrainer{0} = 1 ;*************************************************************** ; ; Restrains the fire button for the main loop. ; ; This bit fixes it so the fire button becomes inactive if it ; hasn't been released after being pressed in the title ; screen section. If the fire button isn't being held down, ; this bit will be cleared in the main loop. ; _Bit1_FireB_Restrainer{1} = 1 ;*************************************************************** ; ; Sets length of score bar. ; pfscore1 = %00000001 ;*************************************************************** ; ; Sets starting score. ; score = 130 if switchrightb then score = 150 ;*************************************************************** ; ; Slows down movement of star & cloud by this number of frames. ; _Star_Cloud_Slowdown = 30 ;*************************************************************** ; ; Tells the program which label to jump to. ; _Jump_Pointer = 1 ;*************************************************************** ; ; Sets number of points needed to go up one block in healthbar. ; _Star_Integrate = 100 ;*************************************************************** ; ; Sets number of points needed to go back one healthbar blip. ; _Cloud_Integrate = 10 ;*************************************************************** ; ; Sets starting position of player0. ; player0x = 0 : player0y = 80 ;*************************************************************** ; ; Sets starting position of player1. ; player1x = 80 : player1y = 50 ;*************************************************************** ; ; Defines shape of player0 sprite. ; player0: %00000000 %00000000 %00011000 %00111100 %00111100 %00011000 %00000000 %00000000 end ;*************************************************************** ; ; Defines shape of player1 sprite. ; player1: %00011110 %01111111 %11111111 %01111110 %00111100 %00000000 %00000000 %00000000 end ;*************************************************************** ; ; Randomizes game if mode 2 was selected. ; if _Bit7_Mode{7} then player1x = (rand&127) : player1y = (rand&31) + 25 : _Cloud_Type = (rand&7) : _Cloud_Velocity = (rand&3) : gosub __Reset_Star ;*************************************************************** ; ; Next level sound effect plays at start. Remove this if you ; don't want the sound to play at the beginning. ; _Ch1_Sound = 2 : _Ch1_Duration = 30 : _V1 = 12 ;*************************************************************** ;*************************************************************** ; ; MAIN LOOP (MAKES THE GAME GO) ; ; __Main_Loop if switchbw then gosub __pause ;*************************************************************** ; ; Paddle 0 will be read. ; currentpaddle = 0 ;*************************************************************** ; ; Sets default playfield color. ; COLUPF = $02 ;*************************************************************** ; ; Sets the size and/or other properties of player1. ; NUSIZ1 = _Cloud_Type ;*************************************************************** ; ; Joystick/Paddle fire button section. ; ;``````````````````````````````````````````````````````````````` ; Skips section if left difficulty switch is set to advanced. ; if !switchleftb then goto __Skip_Joystick_Check ;``````````````````````````````````````````````````````````````` ; Turns off restrainer bit and skips section when not shooting. ; if !joy0fire then _Bit1_FireB_Restrainer{1} = 0 : goto __Skip_Shoot ;``````````````````````````````````````````````````````````````` ; Skips this section if fire button hasn't been released since ; the title screen. ; if _Bit1_FireB_Restrainer{1} then goto __Skip_Shoot goto __Shoot_Beam __Skip_Joystick_Check ;``````````````````````````````````````````````````````````````` ; Skips section if left difficulty switch is set to beginner. ; if switchleftb then goto __Skip_Shoot ;``````````````````````````````````````````````````````````````` ; Skips section when not shooting. ; if !joy0right then _Bit1_FireB_Restrainer{1} = 0 : goto __Skip_Shoot ;``````````````````````````````````````````````````````````````` ; Skips this section if fire button hasn't been released since ; the title screen. ; if _Bit1_FireB_Restrainer{1} then goto __Skip_Shoot __Shoot_Beam ;``````````````````````````````````````````````````````````````` ; Changes playfield color. ; COLUPF = $4E ;``````````````````````````````````````````````````````````````` ; Hit mechanics for cloud. If beam hits cloud, do something ; bad and turn on sound effect. ; if collision(player1,playfield) then _Cloud_Integrate = _Cloud_Integrate - 1 : _Ch0_Sound = 2 : _Ch0_Duration = 8 : _V0 = 5 : goto __Skip_Shoot ;``````````````````````````````````````````````````````````````` ; Hit mechanics for star. If beam hits star and not cloud, do ; something good and turn on sound effect. ; if !collision(player0,playfield) then goto __Skip_Shoot _Star_Integrate = _Star_Integrate - 1 _Ch0_Sound = 1 : _Ch0_Duration = 8 : _V0 = 5 __Skip_Shoot ;*************************************************************** ; ; Raises healthbar blip if _Star_Integrate = 0, resets it to ; 100 and plays sound. If healthbar full then plays sound and ; advances to next level. ; if _Star_Integrate then goto __Skip_Star _Star_Integrate = 100 : pfscore1=pfscore1*2|1 ;``````````````````````````````````````````````````````````````` ; Turns on pfscore1 increase sound effect. ; _Ch1_Sound = 1 : _Ch1_Duration = 8 : _V1 = 6 if pfscore1 < %11111111 then goto __Skip_Star pfscore1 = %00000001 : _Level = _Level + 1 score = score + 30 if _Bit7_Mode{7} then _Cloud_Velocity = (rand&7) : _Cloud_Type = (rand&7) _Cloud_Type = _Cloud_Type + 1 : player1x = (rand&127) : player1y = (rand&31) + 25 if _Cloud_Type >= 8 then _Cloud_Type = 0 if _Cloud_Velocity < 8 then _Cloud_Velocity = _Cloud_Velocity + 1 ;if _Level & 5 = 0 then _Cloud_Velocity = _Cloud_Velocity + 1 gosub __Reset_Star ;``````````````````````````````````````````````````````````````` ; Turns on next level sound effect. ; _Ch1_Sound = 2 : _Ch1_Duration = 30 : _V1 = 12 __Skip_Star ;*************************************************************** ; ; Lowers healthbar blip if _Cloud_Integrate = 0 and plays sound. ; if !_Cloud_Integrate then _Cloud_Integrate = 30 : if pfscore1 then pfscore1 = 0 : _Ch1_Sound = 3 : _Ch1_Duration = 30 : _V1 = 0 ;*************************************************************** ; ; Game over if score countdown reaches 0. ; if !_sc1 && !_sc2 && !_sc3 then _Bit6_Game_Lost{6} = 1 : goto __Game_Over_Setup ;*************************************************************** ; ; Sets various colors. ; COLUP0 = $2E COLUP1 = $0E scorecolor = $2E pfscorecolor = $50 ;*************************************************************** ; ; Channel 0 sound effect check. ; ;``````````````````````````````````````````````````````````````` ; Skips all channel 0 sounds if sounds are off. ; if !_Ch0_Sound then goto __Skip_Ch_0 ;``````````````````````````````````````````````````````````````` ; Decreases the channel 0 duration counter. ; _Ch0_Duration = _Ch0_Duration - 1 ;``````````````````````````````````````````````````````````````` ; Turns off sound if channel 0 duration counter is zero. ; if !_Ch0_Duration then goto __Clear_Ch_0 ;*************************************************************** ; ; Channel 0 sound effect 001. ; ; Beam hitting star. ; ;``````````````````````````````````````````````````````````````` ; Skips this section if sound 001 isn't on. ; if _Ch0_Sound <> 1 then goto __Skip_Ch0_Sound_001 ;``````````````````````````````````````````````````````````````` ; Sets the tone, volume and frequency. ; AUDC0 = 3 : AUDV0 = _V0 : AUDF0 = 12 ;``````````````````````````````````````````````````````````````` ; Decreases volume. ; if _V0 > 3 then _V0 = _V0 - 1 ;``````````````````````````````````````````````````````````````` ; Jumps to end of channel 0 area. ; goto __Skip_Ch_0 __Skip_Ch0_Sound_001 ;*************************************************************** ; ; Channel 0 sound effect 002. ; ; Beam hitting cloud. ; ;``````````````````````````````````````````````````````````````` ; Skips this section if sound 002 isn't on. ; if _Ch0_Sound <> 2 then goto __Skip_Ch0_Sound_002 ;``````````````````````````````````````````````````````````````` ; Sets the tone, volume and frequency. ; AUDC0 = 1 : AUDV0 = _V0 : AUDF0 = 12 ;``````````````````````````````````````````````````````````````` ; Decreases volume. ; if _V0 > 2 then _V0 = _V0 - 1 ;``````````````````````````````````````````````````````````````` ; Jumps to end of channel 0 area. ; goto __Skip_Ch_0 __Skip_Ch0_Sound_002 ;*************************************************************** ; ; Channel 0 sound effect 003. ; ; Lose Star. ; ;``````````````````````````````````````````````````````````````` ; Skips this section if sound 003 isn't on. ; if _Ch0_Sound <> 3 then goto __Skip_Ch0_Sound_003 ;``````````````````````````````````````````````````````````````` ; Sets the tone, volume and frequency. ; AUDC0 = 1 : AUDV0 = _V0 : AUDF0 = 11 : COLUPF = $40 ;``````````````````````````````````````````````````````````````` ; Only looks at the even/odd bit. ; temp5 = _Ch0_Duration & %00000001 ;``````````````````````````````````````````````````````````````` ; Changes AUDF0 only when _Ch0_Duration is an odd number. ; if temp5 then AUDF0 = 23 ;``````````````````````````````````````````````````````````````` ; Decreases volume only when _Ch0_Duration is an odd number. ; if temp5 && _V0 > 2 then _V0 = _V0 - 1 ;``````````````````````````````````````````````````````````````` ; Jumps to end of channel 0 area. ; goto __Skip_Ch_0 __Skip_Ch0_Sound_003 ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;``````````````````````````````````````````````````````````````` ; ; Other channel 0 sound effects go here. ; ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;``````````````````````````````````````````````````````````````` ;*************************************************************** ; ; Clears channel 0. ; __Clear_Ch_0 _Ch0_Sound = 0 : AUDV0 = 0 ;*************************************************************** ; ; End of channel 0 area. ; __Skip_Ch_0 ;*************************************************************** ; ; Channel 1 sound effect check. ; ;``````````````````````````````````````````````````````````````` ; Skips all channel 1 sounds if sounds are off. ; if !_Ch1_Sound then goto __Skip_Ch_1 ;``````````````````````````````````````````````````````````````` ; Decreases the channel 1 duration counter. ; _Ch1_Duration = _Ch1_Duration - 1 ;``````````````````````````````````````````````````````````````` ; Turns off sound if channel 1 duration counter is zero. ; if !_Ch1_Duration then goto __Clear_Ch_1 ;*************************************************************** ; ; Channel 1 sound effect 001. ; ; pfscore1 increase. ; ;``````````````````````````````````````````````````````````````` ; Skips this section if sound 001 isn't on. ; if _Ch1_Sound <> 1 then goto __Skip_Ch1_Sound_001 ;``````````````````````````````````````````````````````````````` ; Sets the tone, volume and frequency. ; AUDC1 = 12 : AUDV1 = _V1 : AUDF1 = 14 ;``````````````````````````````````````````````````````````````` ; Decreases volume. ; if _V1 then _V1 = _V1 - 1 ;``````````````````````````````````````````````````````````````` ; Jumps to end of channel 1 area. ; goto __Skip_Ch_1 __Skip_Ch1_Sound_001 ;*************************************************************** ; ; Channel 1 sound effect 002. ; ; Next level reached. ; ;``````````````````````````````````````````````````````````````` ; Skips this section if sound 001 isn't on. ; if _Ch1_Sound <> 2 then goto __Skip_Ch1_Sound_002 ;``````````````````````````````````````````````````````````````` ; Sets the tone, volume and frequency. ; AUDC1 = 4 : AUDV1 = _V1 : AUDF1 = 23 ;``````````````````````````````````````````````````````````````` ; Only looks at the even/odd bit. ; temp5 = _Ch1_Duration & %00000001 ;``````````````````````````````````````````````````````````````` ; Changes AUDF1 only when _Ch1_Duration is an odd number. ; if temp5 then AUDF1 = 17 ;``````````````````````````````````````````````````````````````` ; Decreases volume only when _Ch1_Duration is an odd number. ; if temp5 && _V1 > 2 then _V1 = _V1 - 1 ;``````````````````````````````````````````````````````````````` ; Jumps to end of channel 1 area. ; goto __Skip_Ch_1 __Skip_Ch1_Sound_002 ;*************************************************************** ; ; Channel 1 sound effect 003. ; ; pfscore1 decrease. ; ;``````````````````````````````````````````````````````````````` ; Skips this section if sound 001 isn't on. ; if _Ch1_Sound <> 3 then goto __Skip_Ch1_Sound_003 ;``````````````````````````````````````````````````````````````` ; Sets the tone, volume and frequency. ; AUDC1 = 7 : AUDV1 = _V1 : AUDF1 = 25 ;``````````````````````````````````````````````````````````````` ; Only looks at the even/odd bit. ; temp5 = _Ch1_Duration & %00000001 ;``````````````````````````````````````````````````````````````` ; Changes AUDF1 only when _Ch1_Duration is an odd number. ; if temp5 then AUDF1 = 30 ;``````````````````````````````````````````````````````````````` ; Increases volume. ; if _V1 < 8 then _V1 = _V1 + 1 ;``````````````````````````````````````````````````````````````` ; Jumps to end of channel 1 area. ; goto __Skip_Ch_1 __Skip_Ch1_Sound_003 ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;``````````````````````````````````````````````````````````````` ; ; Other channel 1 sound effects go here. ; ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;``````````````````````````````````````````````````````````````` ;*************************************************************** ; ; Clears channel 1. ; __Clear_Ch_1 _Ch1_Sound = 0 : AUDV1 = 0 ;*************************************************************** ; ; End of channel 1 area. ; __Skip_Ch_1 ;*************************************************************** ; ; Displays the screen. ; drawscreen ;*************************************************************** ; ; Cloud movement. ; ;``````````````````````````````````````````````````````````````` ; Decrements the slowdown counter. ; _Star_Cloud_Slowdown = _Star_Cloud_Slowdown - 1 ;*************************************************************** ; ; Skips all movements unless countdown is done. ; if _Star_Cloud_Slowdown then goto __Skip_Move ;``````````````````````````````````````````````````````````````` ; Moves cloud. ; player1x = player1x + _Cloud_Velocity ;``````````````````````````````````````````````````````````````` ; Moves cloud to other side of screen if too far to the right. ; if player1x > 160 then player1x = 0 ;``````````````````````````````````````````````````````````````` ; Subtracts 1 from the score (ticks the timer). ; score = score - 1 ;`````````````````````````````````````````````````````1`````````` ; Moves player0 sprite one pixel to the right. ; player0x = player0x + 1 ;``````````````````````````````````````````````````````````````` ; Sets _Star_Cloud_Slowdown based on right difficulty switch position. ; if switchrightb then _Star_Cloud_Slowdown = 30 else _Star_Cloud_Slowdown = 25 if player0y > 95 then gosub __Star_Left_room : goto __Back_to_Main_Loop if player0x < 25 && player0y > 8 then player0y = player0y - 2 : goto __Skip_Move if player0x < 50 && player0y > 8 then player0y = player0y - 1 : goto __Skip_Move if player0x < 80 then goto __Skip_Move if player0x < 130 then player0y = player0y + 1 : goto __Skip_Move if player0x < 160 then player0y = player0y + 2 else gosub __Star_Left_room : goto __Back_to_Main_Loop rem Add small punishment if player loses star on the right __Skip_Move ;``````````````````````````````````````````````````````````````` ; Drawing the line just about takes all of one frames worth of ; program time. ; on _Jump_Pointer goto __Read_Joy_Paddles __Drawline __Do_Score __Back_to_Main_Loop ;*************************************************************** ; ; Reset switch check and end of main loop. ; ; Any Atari 2600 program should restart when the reset ; switch is pressed. It is part of the usual standards ; and procedures. ; ;``````````````````````````````````````````````````````````````` ; Turns off reset restrainer bit and jumps to beginning of ; main loop if the reset switch is not pressed. ; if !switchreset then _Bit0_Reset_Restrainer{0} = 0 : goto __Main_Loop ;``````````````````````````````````````````````````````````````` ; Jumps to beginning of main loop if the reset switch hasn't ; been released after being pressed. ; if _Bit0_Reset_Restrainer{0} then goto __Main_Loop ;``````````````````````````````````````````````````````````````` ; Restarts the program. ; goto __Game_Over_Setup ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;``````````````````````````````````````````````````````````````` ; ; END OF MAIN LOOP ; ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;``````````````````````````````````````````````````````````````` __pause drawscreen if switchbw then goto __pause return ;*************************************************************** ;*************************************************************** ; ; JOYSTICK AND PADDLES ; __Read_Joy_Paddles ;*************************************************************** ; ; Reads the joystick and simulates paddles. ; ;``````````````````````````````````````````````````````````````` ; Skips section if left difficulty switch is set to advanced. ; if !switchleftb then goto __Skip_SWCHA_Joy temp1 = (SWCHA ^ $FF) & $F0 ; tests for joy0 RLDU active if !temp1 then goto __Back_to_Main_Loop ; predicate true iff temp1 = 0 goto not needed if we're within 128 bytes (and it's the only statement) if joy0left && _Telelescope_Point_Horiz > 2 && _Telelescope_Point_Vert = 0 then _Telelescope_Point_Horiz = _Telelescope_Point_Horiz - 3 ; _Telelescope_Point_Horiz is meant to emulate a paddle (sort of) increments by 3 for speed of movement if joy0right && _Telelescope_Point_Horiz < 75 && _Telelescope_Point_Vert = 0 then _Telelescope_Point_Horiz = _Telelescope_Point_Horiz + 3 ; which with the scaling makes the movement a little jerky if joy0left && _Telelescope_Point_Vert < 17 && _Telelescope_Point_Horiz < 3 then _Telelescope_Point_Vert = _Telelescope_Point_Vert + 1 ; when at the edge you can move up && down if joy0right && _Telelescope_Point_Vert > 0 && _Telelescope_Point_Horiz < 3 then _Telelescope_Point_Vert = _Telelescope_Point_Vert - 1 if joy0right && _Telelescope_Point_Horiz > 74 && _Telelescope_Point_Vert < 17 then _Telelescope_Point_Vert = _Telelescope_Point_Vert + 1 if joy0left && _Telelescope_Point_Horiz > 74 && _Telelescope_Point_Vert > 0 then _Telelescope_Point_Vert = _Telelescope_Point_Vert - 1 _x1 = (((_Telelescope_Point_Horiz/4 + _Telelescope_Point_Horiz)/4 + _Telelescope_Point_Horiz)/2 + _Telelescope_Point_Horiz)/4 ; scales _Telelescope_Point_Horiz by 13/32 to get 0..31 _y1 = _Telelescope_Point_Vert/2 ; and has the effect of slowing the movement ie 2 frames/_Telelescope_Point_Vert's to change _y1 by one if _x1 = _Mem_x1 && _y1 = _Mem_y1 then goto __Back_to_Main_Loop ; no need to draw the line if x and y haven't changed _Mem_x1 = _x1 : _Mem_y1 = _y1 __Skip_SWCHA_Joy ;*************************************************************** ; ; Reads the paddles. ; ;``````````````````````````````````````````````````````````````` ; Skips section if left difficulty switch is set to beginner. ; if switchleftb then goto __Skip_Paddles if paddle <9 then _y1 = 8 - paddle : _x1 = 0 : goto __Pad_Go if paddle < 39 then _x1 = paddle - 8 : _y1 = 0 : goto __Pad_Go if paddle < 47 then _x1 = 31 : _y1 = paddle - 39 : goto __Pad_Go if paddle > 46 then _x1 = 31 : _y1 = 8 __Pad_Go _Mem_x1 = _x1 : _Mem_y1 = _y1 __Skip_Paddles _Jump_Pointer = 1 goto __Back_to_Main_Loop __Do_Score _Jump_Pointer = 0 goto __Back_to_Main_Loop ;******************** ; if star leaves room then take off 20 points or die. __Star_Left_room pfscore1 = %00000001 : _Ch0_Sound = 3 : _Ch0_Duration = 30 : _V0 = 12 if !_sc1 && !_sc2 && _sc3 < 21 then goto __Game_Over_Setup player0x=0 : player0y = (rand & 15) + 70 score = score - 10 return ;*************************************************************** ;*************************************************************** ; ; STAR RESET ; __Reset_Star player0x = (rand&63) player0y = (rand&31) + 60 return ;*************************************************************** ;*************************************************************** ; ; BEAM DRAWING SECTION ; __Drawline _x0 = 14 : _y0 = 10 : _x1 = _Mem_x1 : _y1 = _Mem_y1 ;*************************************************************** ; ; Clears playfield variables (fastest way using asm). ; asm LDA #0 STA var0 STA var1 STA var2 STA var3 STA var4 STA var5 STA var6 STA var7 STA var8 STA var9 STA var10 STA var11 STA var12 STA var13 STA var14 STA var15 STA var16 STA var17 STA var18 STA var19 STA var20 STA var21 STA var22 STA var23 STA var24 STA var25 STA var26 STA var27 STA var28 STA var29 STA var30 STA var31 STA var32 STA var33 STA var34 STA var35 STA var36 STA var37 STA var38 STA var39 STA var40 STA var41 STA var42 STA var43 end __Setup_Line if _x0 < _x1 then _octant{2} = 1 : _delta_x = _x1 - _x0 else _octant{2} = 0 : _delta_x = _x0 - _x1 if _y0 < _y1 then _octant{1} = 1 : _delta_y = _y1 - _y0 else _octant{1} = 0 : _delta_y = _y0 - _y1 _xpos = _x0 : _ypos = _y0 if _delta_x > _delta_y then goto __xmajor ;``````````````````````````````````````````````````````````````` ; initializes _error_acc. to 1/2 for better accuracy, symmetry. ; _octant{0} = 0 : xinc = _Data_xinc[_octant] : yinc = _Data_yinc[_octant] : _error_accumulator = _delta_y/2 : _ep = _y1 goto __yentry __YLoop _ypos = _ypos + yinc temp1 = _error_accumulator _error_accumulator = _error_accumulator - _delta_x if temp1 < _error_accumulator then _error_accumulator = _error_accumulator + _delta_y : _xpos = _xpos + xinc __yentry ;``````````````````````````````````````````````````````````````` ; Plots a pf pixel. ; temp1 = _xpos/8 temp1 = _ypos * 4 | temp1 temp2 = _xpos & $0F ;``````````````````````````````````````````````````````````````` ; Setbyte is the kernel table for setting playfield bits. ; var0[temp1] = var0[temp1] | setbyte[temp2] ;``````````````````````````````````````````````````````````````` ; Loops if not at end in major direction in this case y, but ; not sure it wont miss its x. ; if _ypos <> _ep then goto __YLoop _Jump_Pointer = 2 : goto __Back_to_Main_Loop __xmajor _octant{0} = 1 : xinc = _Data_xinc[_octant] : yinc = _Data_yinc[_octant] : _error_accumulator = _delta_x/2 : _ep = _x1 goto __xentry __xloop _xpos = _xpos + xinc temp1 = _error_accumulator _error_accumulator = _error_accumulator - _delta_y if temp1 < _error_accumulator then _error_accumulator = _error_accumulator + _delta_x : _ypos = _ypos + yinc __xentry ; plots a pf pixel temp1 = _xpos/8 temp1 = _ypos * 4 | temp1 temp2 = _xpos & $0F var0[temp1] = var0[temp1] | setbyte[temp2] if _xpos <> _ep then goto __xloop _Jump_Pointer = 2 : goto __Back_to_Main_Loop ;*************************************************************** ;*************************************************************** ; ; CLEAR VARIABLES ; ; Clears most normal variables (fastest way using asm). ; __Clear_Variables asm LDA #0 STA a STA b STA c STA d STA e STA f STA g STA h STA i STA j STA k STA l STA m STA n STA o STA p STA q STA r STA s STA t STA u STA v end return ;*************************************************************** ;*************************************************************** ; ; GAME OVER SETUP ; __Game_Over_Setup if _Level > _Highest_Level then _Highest_Level = _Level goto __Start_Restart ;*************************************************************** ;*************************************************************** ; ; DATA ; data _Data_yinc $FF, $FF, $01, $01, $FF, $FF,$01, $01 end data _Data_xinc $FF, $FF, $FF, $FF, $01, $01, $01, $01 end