X Tutup
;*************************************************************** ; ; Save High Score ; ; Example program by Duane Alan Hahn (Random Terrain) using ; 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. ; ; High score code provided by supercat and polished up ; by Nukey Shay. ; ;``````````````````````````````````````````````````````````````` ; ; Instructions: ; ; Move the joystick to increase the score. Press the fire ; button to end the fake game and the score will flip ; between the current score and the high score every 2 ; seconds on the game over screen. Press the fire button or ; reset switch to go back to the fake game. ; ;``````````````````````````````````````````````````````````````` ; ; 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 ; ;*************************************************************** ;*************************************************************** ; ; Variable aliases go here (DIMs). ; ; 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. ; ; I start variable aliases with one underscore so I won't ; have to worry that I might be using bB keywords by mistake. ; I also start labels with two underscores for the same ; reason. The second underscore also makes labels stand out ; so I can tell at a glance that they are labels and not ; variables. ; ; 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 ; ;``````````````````````````````````````````````````````````````` ; _Master_Counter can be used for many things, but it is ; really useful for animating sprite frames when used ; with _Frame_Counter. ; dim _Master_Counter = a dim _Frame_Counter = b ;``````````````````````````````````````````````````````````````` ; Temporary variable used for auto-play in the main loop. ; This variable can be reused if you're sure it won't ; interfere with auto-play. ; dim _AP_2_Sec_Score_Flip = k ;``````````````````````````````````````````````````````````````` ; These can be used for other things using different aliases, ; but for the game over loop and auto-play in the main loop, ; they are used to temporarily remember the score for the 2 ; second score/high score flip. ; dim _Score1_Mem = s dim _Score2_Mem = t dim _Score3_Mem = u ;``````````````````````````````````````````````````````````````` ; Remembers the high score until the game is turned off. ; dim _High_Score1 = v dim _High_Score2 = w dim _High_Score3 = x ;``````````````````````````````````````````````````````````````` ; All-purpose bits for various jobs. ; dim _BitOp_01 = y dim _Bit0_Reset_Restrainer = y dim _Bit1_FireB_Restrainer = y dim _Bit2_Game_Control = y dim _Bit3_Auto_Play = y dim _Bit6_Swap_Scores = y ;``````````````````````````````````````````````````````````````` ; Makes better random numbers. ; dim rand16 = z ;``````````````````````````````````````````````````````````````` ; Converts 6 digit score to 3 sets of two digits. ; ; The 100 thousands and 10 thousands digits are held by _sc1. ; The thousands and hundreds digits are held by _sc2. ; The tens and ones digits are held by _sc3. ; dim _sc1 = score dim _sc2 = score+1 dim _sc3 = score+2 ;*************************************************************** ;*************************************************************** ; ; PROGRAM START/RESTART ; ; __Start_Restart ;*************************************************************** ; ; Mutes volume of both sound channels. ; AUDV0 = 0 : AUDV1 = 0 ;*************************************************************** ; ; Clears 21 of the normal 26 variables (fastest way using asm). ; Do not clear v, w, x, y, or z in this program. The variables ; v through x remember the high score. The variable y holds a ; bit that should not be cleared. The variable z is used for ; random numbers in this program and clearing it would mess ; up those random numbers. ; 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 end ;*************************************************************** ; ; Clears 7 of the 8 bits. ; ; Bit 2 is not cleared because _Bit2_Game_Control{2} is used ; to control how the program is reset. ; _BitOp_01 = _BitOp_01 & %00000100 ;*************************************************************** ; ; Game control bit tells program where to go. ; ; 0 = Go to title screen. ; 1 = Skip title screen and play game. ; if _Bit2_Game_Control{2} then goto __Main_Loop_Setup ;*************************************************************** ;*************************************************************** ; ; TITLE SCREEN SETUP ; ; __Setup_Title_Screen ;*************************************************************** ; ; Sets score color for title screen. ; scorecolor = 0 ;*************************************************************** ; ; Sets title screen background color. ; COLUBK = 0 ;*************************************************************** ; ; 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 ;*************************************************************** ; ; Sets up title screen playfield. ; playfield: .XXXXXX.XXXXXX.XXXXXXXXXX.XXXXX. .XX.....XX..XX.XX..XX..XX.XX.... .XX.XXX.XXXXXX.XX..XX..XX.XXXX.. .XX..XX.XX..XX.XX..XX..XX.XX.... .XXXXXX.XX..XX.XX..XX..XX.XXXXX. ................................ ..XXXXXX.XX.XXXXXX.XX....XXXXX.. ....XX...XX...XX...XX....XX..... ....XX...XX...XX...XX....XXXX... ....XX...XX...XX...XX....XX..... ....XX...XX...XX...XXXXX.XXXXX.. end ;*************************************************************** ;*************************************************************** ; ; TITLE SCREEN LOOP ; ; __Title_Screen_Loop ;*************************************************************** ; ; Sets title screen playfield pixel color. ; COLUPF = $2C ;*************************************************************** ; ; Auto-play check. ; ; Switches to auto-play after 10 seconds if player doesn't ; start the game. ; ;``````````````````````````````````````````````````````````````` ; Increment _Master_Counter. ; _Master_Counter = _Master_Counter + 1 ;``````````````````````````````````````````````````````````````` ; Skips this section if counter is less than one second. ; if _Master_Counter < 60 then goto __TS_AP_Skip ;``````````````````````````````````````````````````````````````` ; Increments _Frame_Counter and clears _Master_Counter. ; _Frame_Counter = _Frame_Counter + 1 : _Master_Counter = 0 ;``````````````````````````````````````````````````````````````` ; Auto-play check. ; ; Turns on auto-play and jumps to main loop setup if 10 ; seconds have gone by. ; if _Frame_Counter > 9 then _Bit3_Auto_Play{3} = 1 : goto __Main_Loop_Setup __TS_AP_Skip ;*************************************************************** ; ; Displays the screen. ; drawscreen ;*************************************************************** ; ; 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 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 ;``````````````````````````````````````````````````````````````` ; Sets control bit so program will jump to main loop setup. ; _Bit2_Game_Control{2} = 1 ;``````````````````````````````````````````````````````````````` ; Restarts game and program jumps to main loop setup. ; goto __Start_Restart ;*************************************************************** ;*************************************************************** ; ; MAIN LOOP SETUP ; ; __Main_Loop_Setup ;*************************************************************** ; ; In the main loop, _Bit2_Game_Control{2} controls when the ; game ends. ; ; 0 = Game not over. ; 1 = Game over. ; _Bit2_Game_Control{2} = 0 ;*************************************************************** ; ; 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 in the title ; screen section or the game over section. If the reset ; switch isn't being held down, this bit will be cleared ; in the main loop. ; _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 or the game over 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 background color. ; COLUBK = $80 ;*************************************************************** ; ; Sets score color. ; scorecolor = $AE ;*************************************************************** ; ; Sets up the main loop playfield. ; playfield: ................................ ................................ ................................ .XXXXXX.XXXXXX.XXXXXXXXXX.XXXXX. .XX.....XX..XX.XX..XX..XX.XX.... .XX.XXX.XXXXXX.XX..XX..XX.XXXX.. .XX..XX.XX..XX.XX..XX..XX.XX.... .XXXXXX.XX..XX.XX..XX..XX.XXXXX. ................................ ................................ ................................ end ;*************************************************************** ; ; Auto-play score swap setup. ; ;``````````````````````````````````````````````````````````````` ; Clears score and skips section if auto-play is off. ; if !_Bit3_Auto_Play{3} then score = 0 : goto __AP_Skip_AP_Setup ;``````````````````````````````````````````````````````````````` ; Clears variables. ; _Master_Counter = 0 : _Frame_Counter = 0 ;``````````````````````````````````````````````````````````````` ; Sets up the score swap, clears the swap bit, sets background ; color, and draws auto-play screen. ; _Score1_Mem = _sc1 : _Score2_Mem = _sc2 : _Score3_Mem = _sc3 _Bit6_Swap_Scores{6} = 0 : COLUBK = $30 playfield: ..XXXXXX.XX..XX.XXXXXX.XXXXXX... ..XX..XX.XX..XX...XX...XX..XX... ..XXXXXX.XX..XX...XX...XX..XX... ..XX..XX.XX..XX...XX...XX..XX... ..XX..XX.XXXXXX...XX...XXXXXX... ................................ ..XXXXXX.XX.....XXXXXX.XX..XX... ..XX..XX.XX.....XX..XX.XX..XX... ..XXXXXX.XX.....XXXXXX.XXXXXX... ..XX.....XX.....XX..XX...XX..... ..XX.....XXXXXX.XX..XX...XX..... end __AP_Skip_AP_Setup ;*************************************************************** ;*************************************************************** ; ; MAIN LOOP (MAKES THE GAME GO) ; ; __Main_Loop ;*************************************************************** ; ; Sets playfield pixel color. ; COLUPF = $9A ;*************************************************************** ; ; Auto-play playfield pixel color. ; if _Bit3_Auto_Play{3} then COLUPF = $3A ;*************************************************************** ; ; Slows down the joystick and adds 10 to the score if the ; joystick is moved. ; ;``````````````````````````````````````````````````````````````` ; Increments the counter. ; _Master_Counter = _Master_Counter + 1 ;``````````````````````````````````````````````````````````````` ; Skips ahead if auto-play is off. ; if !_Bit3_Auto_Play{3} then goto __AP_Skip_Counter ;``````````````````````````````````````````````````````````````` ; Skips section if master counter is less than 2 seconds. ; The master counter resets every 2 seconds (60 + 60 = 120). ; if _Master_Counter < 120 then goto __Skip_Joystick_Check ;``````````````````````````````````````````````````````````````` ; Increments frame counter and clears master counter. ; (One increment = 2 seconds.) ; _Frame_Counter = _Frame_Counter + 1 : _Master_Counter = 0 ;``````````````````````````````````````````````````````````````` ; Ends auto-play if 10 seconds have gone by. ; if _Frame_Counter > 4 then _Bit2_Game_Control{2} = 1 goto __Skip_Joystick_Check __AP_Skip_Counter ;``````````````````````````````````````````````````````````````` ; Skip this section if the counter is less than 8. ; if _Master_Counter < 8 then goto __Skip_Joystick_Check ;``````````````````````````````````````````````````````````````` ; Clears the counter. ; _Master_Counter = 0 ;``````````````````````````````````````````````````````````````` ; Adds 10 points to the score if joystick is moved. ; if !joy0up && !joy0down && !joy0left && !joy0right then goto __Skip_Joystick_Check score = score + 10 __Skip_Joystick_Check ;*************************************************************** ; ; Fire button section. ; ;``````````````````````````````````````````````````````````````` ; Clears the restrainer bit and skips this section if the fire ; button is not pressed. ; if !joy0fire then _Bit1_FireB_Restrainer{1} = 0 : goto __Done_Fire ;``````````````````````````````````````````````````````````````` ; Skips this section if the fire button hasn't been released ; since starting. ; if _Bit1_FireB_Restrainer{1} then goto __Done_Fire ;``````````````````````````````````````````````````````````````` ; For this example, the fire button ends the program. ; _Bit2_Game_Control{2} = 1 __Done_Fire ;*************************************************************** ; ; Auto-play score flipper. ; ; Flips between high score and current score. ; ;``````````````````````````````````````````````````````````````` ; Skips this section if auto-play bit is not on. ; if !_Bit3_Auto_Play{3} then goto __AP_Skip_Flip ;``````````````````````````````````````````````````````````````` ; Increments the auto play 2-second counter. ; _AP_2_Sec_Score_Flip = _AP_2_Sec_Score_Flip + 1 ;``````````````````````````````````````````````````````````````` ; Skips this section if auto play 2-second counter is less ; than 2 seconds (120 = 2 seconds). ; if _AP_2_Sec_Score_Flip < 120 then goto __AP_Skip_Flip ;``````````````````````````````````````````````````````````````` ; Clears the 2-second counter and flips the score swapping bit. ; _AP_2_Sec_Score_Flip = 0 : _Bit6_Swap_Scores{6} = !_Bit6_Swap_Scores{6} ;``````````````````````````````````````````````````````````````` ; Skips high score swap if swap bit is off. ; if !_Bit6_Swap_Scores{6} then goto __AP_Skip_HiScore_Swap ;``````````````````````````````````````````````````````````````` ; Displays high score (yellow) and skips rest of section. ; scorecolor = $1C _sc1 = _High_Score1 : _sc2 = _High_Score2 : _sc3 = _High_Score3 goto __AP_Skip_Flip __AP_Skip_HiScore_Swap ;``````````````````````````````````````````````````````````````` ; Displays current score (blue). ; scorecolor = $AE _sc1 = _Score1_Mem : _sc2 = _Score2_Mem : _sc3 = _Score3_Mem __AP_Skip_Flip ;*************************************************************** ; ; Displays the screen. ; drawscreen ;*************************************************************** ; ; Game Over Check ; ; _Bit2_Game_Control{2} controls when the game ends. ; ; 0 = Game not over. ; 1 = Game over. ; ;``````````````````````````````````````````````````````````````` ; Skips this section if game control bit is off. ; if !_Bit2_Game_Control{2} then goto __Skip_Check_G_Over ;``````````````````````````````````````````````````````````````` ; Auto-play check. Puts score back to current score and jumps ; back to the title screen if auto-play bit is on. ; if _Bit3_Auto_Play{3} then _Bit2_Game_Control{2} = 0 : _sc1 = _Score1_Mem : _sc2 = _Score2_Mem : _sc3 = _Score3_Mem : goto __Start_Restart ;``````````````````````````````````````````````````````````````` ; Jumps to game over set up. ; goto __Game_Over_Setup __Skip_Check_G_Over ;*************************************************************** ; ; 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. ; ;``````````````````````````````````````````````````````````````` ; Auto-play check. ; if !_Bit3_Auto_Play{3} then goto __AP_Skip_Reset ;``````````````````````````````````````````````````````````````` ; Starts game during auto-play if reset switch or fire button ; is pressed. Also clears auto-play bit and sets game control ; bit so game will start instead of going to title screen. ; if switchreset || joy0fire then _Bit3_Auto_Play{3} = 0 : _Bit2_Game_Control{2} = 1 : goto __Start_Restart __AP_Skip_Reset ;``````````````````````````````````````````````````````````````` ; 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 ;``````````````````````````````````````````````````````````````` ; Clears the game over bit so the title screen will appear. ; _Bit2_Game_Control{2} = 0 ;``````````````````````````````````````````````````````````````` ; Jumps to the game over setup section and checks for a high ; score, then jumps to the title screen. ; goto __Game_Over_Setup ;*************************************************************** ;*************************************************************** ; ; GAME OVER SETUP ; ; __Game_Over_Setup ;*************************************************************** ; ; High score check using asm. ; ; The original supercat code was adapted by Karl G with input ; from bogax. ; asm sed ; Set the Decimal Mode Flag lda _High_Score3 ; Load the Accumulator cmp _sc3 ; Compare Memory and the Accumulator lda _High_Score2 ; Load the Accumulator sbc _sc2 ; Subtract With Carry lda _High_Score1 ; Load the Accumulator sbc _sc1 ; Subtract With Carry cld ; Clear the Decimal Flag bcs .__Skip_High_Score ; Branch if Carry Set ; (goto label if carry is set) end ;``````````````````````````````````````````````````````````````` ; New high score! ; _High_Score1 = _sc1 : _High_Score2 = _sc2 : _High_Score3 = _sc3 __Skip_High_Score ;``````````````````````````````````````````````````````````````` ; Restarts the game if the reset switch was pressed. Continues ; in the game over setup section if the game ended naturally. ; if !_Bit2_Game_Control{2} then goto __Start_Restart ;*************************************************************** ; ; Saves the latest score for the high score flip. ; _Score1_Mem = _sc1 : _Score2_Mem = _sc2 : _Score3_Mem = _sc3 ;*************************************************************** ; ; Clears the counters. ; _Master_Counter = 0 : _Frame_Counter = 0 ;*************************************************************** ; ; Restrains reset switch and fire button for GAME OVER loop. ; ; 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 does double duty by restraining the ; fire button too in the GAME OVER loop. ; _Bit0_Reset_Restrainer{0} = 1 ;*************************************************************** ; ; Sets up GAME OVER playfield. ; playfield: .XXXXXX.XXXXXX.XXXXXXXXXX.XXXXX. .XX.....XX..XX.XX..XX..XX.XX.... .XX.XXX.XXXXXX.XX..XX..XX.XXXX.. .XX..XX.XX..XX.XX..XX..XX.XX.... .XXXXXX.XX..XX.XX..XX..XX.XXXXX. ................................ ...XXXXXX.XX..XX.XXXXX.XXXXXX... ...XX..XX.XX..XX.XX....XX..XX... ...XX..XX.XX..XX.XXXX..XXXXX.... ...XX..XX.XX..XX.XX....XX..XX... ...XXXXXX...XX...XXXXX.XX..XX... end ;*************************************************************** ;*************************************************************** ; ; GAME OVER LOOP ; ; __Game_Over_Loop ;*************************************************************** ; ; 20 second counter. ; ; This includes a 2 second countdown timer. Any Atari 2600 ; game should disable the fire button for 2 seconds when ; the game is over to keep the player from restarting by ; mistake. It is part of the usual standards and procedures. ; ; This section also flips between the current score and the ; high score every 2 seconds. It jumps to the title screen ; after 20 seconds if the player does nothing. ; ;``````````````````````````````````````````````````````````````` ; Increments master counter every frame (60 frames = 1 second). ; _Master_Counter = _Master_Counter + 1 ;``````````````````````````````````````````````````````````````` ; Skips this section if master counter is less than 2 seconds. ; The master counter resets every 2 seconds (60 + 60 = 120). ; if _Master_Counter < 120 then goto __Skip_20_Second_Counter ;``````````````````````````````````````````````````````````````` ; Increments frame counter and clears master counter. ; (One increment = 2 seconds.) ; _Frame_Counter = _Frame_Counter + 1 : _Master_Counter = 0 ;``````````````````````````````````````````````````````````````` ; Restores the current score, resets the game, and goes to the ; title screen if 20 seconds have gone by. ; ; 0 = Go to title screen. ; 1 = Skip title screen and play game. ; if _Frame_Counter > 9 then _Bit2_Game_Control{2} = 0 : _sc1=_Score1_Mem : _sc2=_Score2_Mem : _sc3=_Score3_Mem: goto __Start_Restart ;``````````````````````````````````````````````````````````````` ; Flips the score swapping bit. ; _Bit6_Swap_Scores{6} = !_Bit6_Swap_Scores{6} ;``````````````````````````````````````````````````````````````` ; Jumps to current score if swap bit is off. ; if !_Bit6_Swap_Scores{6} then goto __GO_Current_Score ;``````````````````````````````````````````````````````````````` ; Displays high score (yellow) and skips rest of section. ; scorecolor = $1C _sc1 = _High_Score1 : _sc2 = _High_Score2 : _sc3 = _High_Score3 goto __Skip_20_Second_Counter ;``````````````````````````````````````````````````````````````` ; Displays current score (blue). ; __GO_Current_Score scorecolor = $AE _sc1 = _Score1_Mem : _sc2 = _Score2_Mem : _sc3 = _Score3_Mem __Skip_20_Second_Counter ;*************************************************************** ; ; Sets background color and playfield color. ; COLUBK = $44 : COLUPF = $2C ;``````````````````````````````````````````````````````````````` ; Changes colors after 2 seconds. This is only done to let ; you, the programmer, know when 2 seconds have gone by. The ; color change doesn't need to happen in a real game. ; if _Frame_Counter > 0 then COLUBK = $D2 : COLUPF = $DA ;*************************************************************** ; ; Displays the screen. ; drawscreen ;*************************************************************** ; ; Reset/fire button check and end of game over loop. ; ; Restarts the program if the reset switch or the fire ; button is pressed appropriately. ; ;``````````````````````````````````````````````````````````````` ; Jumps to beginning of the game over loop if the initial ; 2 second freeze is not over. ; if _Frame_Counter = 0 then goto __Game_Over_Loop ;``````````````````````````````````````````````````````````````` ; Clears the restrainer bit and jumps to beginning of game ; over loop if fire button or reset switch is not pressed. ; if !switchreset && !joy0fire then _Bit0_Reset_Restrainer{0} = 0 : goto __Game_Over_Loop ;``````````````````````````````````````````````````````````````` ; Jumps to beginning of the game over loop if fire button ; hasn't been released since leaving the main loop. ; if _Bit0_Reset_Restrainer{0} then goto __Game_Over_Loop ;``````````````````````````````````````````````````````````````` ; The program is restarted. ; goto __Start_Restart
X Tutup