Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- includesfile heartincludes.inc
- rem **********************************
- rem * Heartbreak *
- rem * A re-imagning of breakout with a lonely heart trapped in a void... *
- rem * Cybearg (aka Nic) *
- rem * cybearg.plays@gmail.com *
- rem * HUGE thanks to bogax, RandomTerrain, theloon, Omegamatrix, Andrew Davie, and all others at AtariAge.com for making this possible! *
- rem **********************************
- const COL_NTSC = 1
- asm
- include colors.h
- end
- rem ==============
- rem INITIALIZATION
- rem ==============
- rem set up settings/optimization
- include fixed_point_math.asm
- set tv ntsc
- set optimization size
- set optimization inlinerand
- set smartbranching on
- const AVoxSafetyOff=1
- const LIFEMAX = 3
- const startlevel = 0
- const START_VEL = 128
- rem COLORS
- rem NOTE: BLACK isn't $00 because $00 counts a block as destroyed, rather than invisible
- asm
- IF COL_NTSC
- RED = COL_40
- YELLOW = COL_1E
- BLUE = COL_96
- ORANGE = COL_22
- GREEN = COL_D4
- PURPLE = COL_62
- WHITE = COL_0E
- BLACK = COL_01
- ELSE
- RED = $60
- YELLOW = $2A
- BLUE = $B6
- ORANGE = $42
- GREEN = $52
- PURPLE = $A2
- WHITE = COL_0E
- BLACK = COL_01
- ENDIF
- end
- data _BlockColor
- RED, YELLOW, BLUE, ORANGE, GREEN, PURPLE, WHITE, BLACK
- end
- rem set up my variables
- dim block = a
- dim selection = q
- dim blkcount = r
- dim level = s
- dim soundtimer=t
- dim anglevar=u
- dim pulse=v
- dim lastblock = w
- dim offset=x
- dim ballcolor=y
- dim heartcolor=z
- rem cxBlock reports the index of a block's collision from the kernel, informing of which block was hit
- dim cxBlock = $A4
- rem the types of possible basic gameplay modes
- dim bits = $A8
- def atarivox = bits{0}
- def resetlock = bits{1}
- def hardmode = bits{2}
- def firelock = bits{3}
- rem when bounce is enabled, score based on how many bounces can be kept up.
- dim bouncecount = $AD
- rem remembers the maximum streak one had for a level
- dim maxbounce = $AE
- rem counter for heartbeat audio
- dim lubdub = $AF
- rem memory locations for remembering the last high score
- dim save1 = $B0
- dim save2 = $B1
- dim save3 = $B2
- dim floatx = $B3
- dim floaty = $B4
- dim velfloati = $B5
- dim velfloatd = $B6
- dim rand16 = $B7
- dim _ballx = player1x.floatx
- dim _bally = player1y.floaty
- dim _my88 = temp4.temp5
- dim _velocity = velfloati.velfloatd
- rem set up score bytes for reading/writing
- dim sc1=score
- dim sc2=score+1
- dim sc3=score+2
- rem set player 0's location
- player0x=80:player0y=48
- rem ================
- rem ATARIVOX START
- rem ================
- rem try to write to AtariVox
- temp2=AVoxWriteByte($30,$01,temp3)
- if temp1 then goto resetpoint
- drawscreen
- atarivox = 1
- rem initial read loop
- AvoxRead
- read1
- save1=AVoxReadByte($06,$80)
- rem sc1 = save1
- drawscreen
- read2
- save2=AVoxReadByte($06,$81)
- rem sc2 = save
- drawscreen
- read3
- save3=AVoxReadByte($06,$82)
- rem sc3 = save3
- drawscreen
- rem ** if the score is $ff, we need to initialize the eeprom
- rem ** if we don't do this, the high score will be $FFFFFF
- temp2=save1&save2&save3
- if temp2=$ff then save1=0:save2=0:save3=0
- resetpoint
- gosub avoxSave
- if switchleftb then hardmode = 0 else hardmode = 1
- level = startlevel
- score = 0: AUDV0 = 0: AUDV1 = 0
- gosub setstage
- rem ==========
- rem MAIN LOOP
- rem ==========
- main
- gosub sounds
- gosub heartbeat
- if lives then gosub colormove
- if joy0fire && !firelock then gosub playerfire
- if player1x then gosub ballmove: gosub collisiondetect
- if !blkcount then gosub stageend: gosub setstage
- rem ==================
- rem MAIN DRAWSCREEN
- rem ==================
- maindraw
- const SCORERED = COL_40
- const SCOREWHITE = COL_0E
- if lives = 1 then scorecolor = SCORERED else scorecolor = SCOREWHITE
- if pulse < 40 then temp1 = lives else temp1 = lives - 1
- if !lives then temp1 = 0
- asm
- LDX temp1
- LDA spriteslo,x
- STA player0pointerlo
- LDA spriteshi,x
- STA player0pointerhi
- LDX #4
- LDA spriteslo,x
- STA player1pointerlo
- LDA spriteshi,x
- STA player1pointerhi
- LDA #7
- STA player0height
- STA player1height
- end
- if switchreset && !resetlock then resetlock = 1: goto resetpoint
- if !switchreset then resetlock = 0
- if !joy0fire then firelock = 0
- drawscreen
- if switchselect && switchreset then gosub avoxSave: T1024T=rand: goto bank_menu
- if switchbw then AUDV0 = 0: AUDV1 = 0: goto maindraw
- goto main
- rem ===============
- rem SOUNDS
- rem ===============
- sounds
- if soundtimer then soundtimer = soundtimer - 1: AUDV1 = 8 else AUDV1 = 0
- return thisbank
- rem ===============
- rem BEATING HEART
- rem ===============
- heartbeat
- pulse = pulse +1
- if pulse = 38 then AUDC0 = 12: AUDF0 = 31: AUDV0 = 1
- if pulse = 45 then pulse = 0: AUDV0 = 0: heartcolor = heartcolor + 1
- rem ensure heartcolor doesn't go too high
- data heartcolors
- 0, 1, 2, 1, 2
- end
- if level < 4 && heartcolor > heartcolors[level] then heartcolor = 0
- if heartcolor = 3 then heartcolor = 0
- COLUP0 = _BlockColor[heartcolor]
- if !lives then AUDV0 = 0
- return thisbank
- rem =================
- rem COLOR MOVEMENT
- rem =================
- colormove
- if !tempJoy{6} then offset = offset + 1
- if !tempJoy{7} then offset = offset - 1
- if offset >= 53 then goto left
- if offset <= 47 then goto right
- return thisbank
- rem move all block values to the left (counter clockwise)
- left temp3 = a[0]
- for temp1 = 0 to 14
- temp2 = temp1 + 1
- a[temp1] = a[temp2]
- next
- a[15] = temp3
- goto resetoffset
- rem move all blocks to the right (clockwise)
- right temp3 = a[15]
- for temp1 = 15 to 0 step -1
- temp2 = temp1 - 1
- a[temp1] = a[temp2]
- next
- a[0] = temp3
- rem reset the offset
- resetoffset
- offset = 50
- return thisbank
- rem ============
- rem PLAYER FIRE
- rem ============
- playerfire
- if !lives then pop: goto resetpoint
- ballcolor = heartcolor
- if !player1x then player1x=80: player1y=48 else return thisbank
- anglevar = (rand/64) * 2 + 1
- return thisbank
- rem =========
- rem THE BALL
- rem =========
- ballmove
- COLUP1 = _BlockColor[ballcolor]
- rem x motion table
- data xmtbl
- 0, 1, 1, 1, 0, -1, -1, -1
- end
- rem y motion table
- data ymtbl
- -1, -1, 0, 1, 1, 1, 0, -1
- end
- ballMove
- if xmtbl[anglevar] = 1 then _ballx = _ballx + _velocity
- if xmtbl[anglevar] = 255 then _ballx = _ballx - _velocity
- if ymtbl[anglevar] = 1 then _bally = _bally + _velocity
- if ymtbl[anglevar] = 255 then _bally = _bally - _velocity
- return thisbank
- rem ====================
- rem COLLISION DETECTION
- rem ====================
- collisiondetect
- rem check to see if player 1 is out of bounds
- if player1x > 25 && player1x < 133 && player1y && player1y < 88 then goto ballinplay
- if hardmode then temp1 = 0 else temp1 = 1
- AUDC1 = 6: AUDF1 = 16: soundtimer = 8
- player1x = 0: player1y = 0: bouncecount = 0
- lastblock = 16: velfloati = 0: velfloatd = START_VEL
- repeatpenalty
- if !sc1 && !sc2 && sc3 < 50 then score = 0 else score = score - 50
- if temp1 then return thisbank else temp1 = 1: goto repeatpenalty
- ballinplay
- if !collision(playfield,player1) || cxBlock = lastblock then return thisbank
- if !block[cxBlock] then return thisbank
- rem ====================
- rem COLOR CHECKING
- rem ====================
- rem note, index 0 of primaryarray is never used
- data primaryarray
- 7, 3, 5, 4
- end
- data secondaryarray
- 1, 0, 6, 6, 2, 1, 2, 6, 0
- end
- data whitearray
- 4, 5, 3
- end
- rem find the color index of the current block
- for temp1 = 0 to 6
- if block[cxBlock] = _BlockColor[temp1] then goto colorcheck
- next
- colorcheck
- if temp1 <= 2 then goto primarycheck
- if temp1 > 5 then goto whiteblack
- goto secondarycheck
- primarycheck
- if ballcolor = temp1 then goto good_hit else goto bad_hit
- secondarycheck
- temp4 = temp1 - 3
- temp6 = temp4 + temp4 + temp4 + ballcolor
- temp5 = secondaryarray[temp6]
- rem normally, "6" represents an invalid hit, so it is bad
- if temp5 = 6 then goto bad_hit
- rem use the array to set the correct resulting color
- block[cxBlock] = _BlockColor[temp5]
- goto keep_going
- whiteblack
- white
- if temp1 = 7 then goto bad_hit
- temp2 = whitearray[ballcolor]
- block[cxBlock] = _BlockColor[temp2]: temp5 = temp2 - 3: goto white_hit
- rem ====================
- rem CONSEQUENCES
- rem ====================
- bad_hit
- lives = lives - 1
- velfloati = 0: velfloatd = START_VEL
- AUDC1 = 1: AUDF1 = 24: soundtimer = 8
- firelock = 1: player1x = 0: player1y = 0: bouncecount = 0: lastblock = 16: return thisbank
- good_hit
- block[cxBlock] = 0
- blkcount = blkcount - 1
- score = score + 25
- if hardmode then _velocity = _velocity + 0.025
- AUDC1 = 12: AUDF1 = 19: soundtimer = 8
- goto newbounce
- white_hit
- if lives < 3 then lives = lives + 1
- keep_going
- score = score + 25
- AUDC1 = 12: AUDF1 = 12: soundtimer = 8
- if hardmode then _velocity = _velocity + 0.005
- newbounce
- lastblock = cxBlock
- temp1 = rand
- temp2 = cxBlock / 2
- if temp1 <= 85 then anglevar = (temp2 + 3) & 7
- if temp1 > 85 && temp1 <= 170 then anglevar = (temp2 + 4) & 7
- if temp1 > 170 then anglevar = (temp2 + 5) & 7
- rem reset ball location to prevent wander
- data blockX
- 0, 112, 0, 112, 0, 48, 0, 48
- end
- data blockY
- 0, 18, 0, 78, 0, 78, 0, 18
- end
- temp2 = cxBlock / 2
- player1x = blockX[temp2]
- player1y = blockY[temp2]
- floatx = 0: floaty = 0
- bouncecount = bouncecount + 1
- if bouncecount > maxbounce then maxbounce = bouncecount
- return thisbank
- rem ==================
- rem STAGE ENDING
- rem ==================
- stageend
- if hardmode then temp1 = 0 else temp1 = 1
- pointsrepeat
- score = score + 50
- if lives > 1 then score = score + 50
- if lives > 2 then score = score + 50
- if maxbounce >= 12 then score = score + 50
- if maxbounce >= 16 then score = score + 50
- if maxbounce >= 24 then score = score + 50
- if !temp1 then temp1 = 1: goto pointsrepeat
- level = level + 1
- if level = 16 && hardmode then level = 8
- if level = 16 && !hardmode then level = 0: hardmode = 1
- return thisbank
- rem ==================
- rem STAGE GENERATION
- rem ==================
- setstage
- rem defines the odds of a color for each stage
- data colorodds
- 0, 0, 128, 0, 85, 170, 0, 42, 84, 126, 168, 210, 0, 70, 140, 210, 245, 0, 40, 80, 120, 160, 200, 240, 250, 0, 20, 40, 80, 120, 160, 200, 240, 0, 60, 120, 180, 240
- end
- rem saves space by indicating where the colorodds index should begin, per level
- data startindex
- 0, 1, 3, 0, 1, 3, 6, 1, 12, 12, 17, 17, 25, 25, 33, 33
- end
- rem defines which color checks are in a stage
- data levelcolors
- %00000001, %00000011, %00000111, %00001000, %00011000, %00111000, %00111111, %11000000, %11000111, %11111000, %11111111, %11111111, %11111111, %11111111, %11111000, %11111000
- end
- data levelcolorsrev
- %00010000, %00110000, %00111000, %00000100, %00000110, %00000111, %00111111, %11000000, %11111000, %11000111, %11111111, %11111111, %11111111, %11111111, %11000111, %11000111
- end
- rem defines the colors red through black
- data bitlist
- %00000001, %00000010, %00000100, %00001000, %00010000, %00100000, %01000000, %10000000
- end
- velfloati = 0: velfloatd = START_VEL
- blkcount = 16
- selection = 0: player1x = 0: player1y = 0
- generationloop
- temp3 = startindex[level]
- rem generate a random number
- temp2 = rand
- rem if a color is in a level and its number has been rolled, set a pfpixel to its color, then increment the index
- for temp5 = 0 to 7
- rem if the current color is not in the current level, temp 4 = 0
- temp4 = levelcolors[level] & bitlist[temp5]
- rem if the current color is in the current level and that color's number has been rolled, set the current block to that color
- if temp4 && temp2 >= colorodds[temp3] then block[selection] = _BlockColor[temp5]: temp3 = temp3 + 1
- next
- if block[selection] = BLACK then blkcount = blkcount - 1
- COLUP0 = 0: COLUP1 = 0
- gosub sounds
- drawscreen
- if selection < 15 then selection = selection + 1: goto generationloop
- lives=LIFEMAX:lastblock=16:AUDV0=0:bouncecount=0:maxbounce=0: pulse = 0: heartcolor = 0
- offset = 50
- return thisbank
- rem ================
- rem ATARIVOX SAVE
- rem ================
- avoxSave
- if !atarivox then return thisbank
- if sc1 > save1 then goto NewHigh
- if sc2 > save2 && sc1 = save1 then goto NewHigh
- if sc3 > save3 && sc1 = save1 && sc2 = save2 then goto NewHigh
- return thisbank
- NewHigh
- write1
- temp2=AVoxWriteByte($06,$80,sc1)
- drawscreen
- write2
- temp2=AVoxWriteByte($06,$81,sc2)
- drawscreen
- write3
- temp2=AVoxWriteByte($06,$82,sc3)
- save1 = sc1: save2 = sc2: save3 = sc3
- drawscreen
- return thisbank
- rem ** include the AtariVox wrapper and driver code...
- asm
- spriteslo
- .byte <heartnone
- .byte <heartsmall
- .byte <heartmed
- .byte <heartlarge
- .byte <playerball
- spriteshi
- .byte >heartnone
- .byte >heartsmall
- .byte >heartmed
- .byte >heartlarge
- .byte >playerball
- if (<*) > (<(*+7))
- repeat ($100-<*)
- .byte 0
- repend
- endif
- playerball
- .byte %11000000
- .byte %11000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- if (<*) > (<(*+7))
- repeat ($100-<*)
- .byte 0
- repend
- endif
- heartlarge
- .byte %00010000
- .byte %00111000
- .byte %01111100
- .byte %11111110
- .byte %11111110
- .byte %11111110
- .byte %01101100
- .byte %00000000
- if (<*) > (<(*+7))
- repeat ($100-<*)
- .byte 0
- repend
- endif
- heartmed
- .byte %00000000
- .byte %00010000
- .byte %00111000
- .byte %01111100
- .byte %01111100
- .byte %00101000
- .byte %00000000
- .byte %00000000
- if (<*) > (<(*+7))
- repeat ($100-<*)
- .byte 0
- repend
- endif
- heartsmall
- .byte %00000000
- .byte %00000000
- .byte %00010000
- .byte %00111000
- .byte %00101000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- if (<*) > (<(*+7))
- repeat ($100-<*)
- .byte 0
- repend
- endif
- heartnone
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- include "bbavox-eeprom-static.asm"
- echo "bswitch jump: ",start
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement