diff --git a/basic/code/games/invaders.bas b/basic/code/games/invaders.bas new file mode 100644 index 00000000..b91d439d Binary files /dev/null and b/basic/code/games/invaders.bas differ diff --git a/basic/code/games/invaders.bsc b/basic/code/games/invaders.bsc new file mode 100644 index 00000000..0fb6918c --- /dev/null +++ b/basic/code/games/invaders.bsc @@ -0,0 +1,251 @@ +' +' *** Space Invaders *** +' +cls:gload "invaders.gfx" +call Initialise() + +call ResetMap():call RedrawGame():call ResetBullets():call RepaintInvaders() +repeat + call PlayLevel() +until lives = 0 +end +' +' Play/Continue the current level +' +proc PlayLevel() + dead = false + tMoveInvaders = 0:tMovePlayer = 0:tMoveBullets = 0:tCheckFire = 0 + tFireCheckTime = 100 + repeat + if event(tMoveInvaders,moveRate) then call MoveInvaders():call RepaintInvaders():sprite 10 hide + if event(tMovePlayer,3) then call MovePlayer() + if event(tMoveBullets,3) + if yPBullet > -20 then call MovePlayerBullet() + call MoveInvaderBullets() + endif + if event(tCheckFire,tFireCheckTime) then tFireCheckTime = rand(70)+20:call CheckInvaderFire() + until dead|remaining = 0 + if remaining = 0 then call ResetMap() + if dead then lives = lives - 1 + + if lives > 0 + call Delay(200) + call RedrawGame():call ResetBullets():call RepaintInvaders() + endif + + endproc +' +' The invaders are actually a tilemap, so create it. +' +proc Initialise() + invBulletCount = 2 + invMap = alloc(13 * 5 + 3) + poke invMap,1:poke invMap+1,13:poke invMap+2,6 + tilemap invMap,8,0 + dim colAlive(11),xBullet(invBulletCount),yBullet(invBulletCount) + score = 0:highScore = 1000:lives = 3:level = 0 + xPlayer = 160 +endproc +' +' Redraw the score +' +proc DrawScore() + text right$("000000"+str$(score),6) ink 7 dim 1 solid to 62,10 + if score = 0 | score = highScore then text right$("000000"+str$(highScore),6) ink 7 dim 1 to 142,10 +endproc +' +' Initialise the invaders map and counts +' +proc ResetMap() + local a,c,i,x,y + for y = 0 to 4 + a = y * 13 + invMap + 3:c = (y+1) \ 2 + poke a,$F8:poke a+12,$F8 + for i = 1 to 11:poke a+i,c:next + next + xLeft = 160 - 13 * 8:yTop = 28+level*6:xDirection = 4 + for i = 1 to 11:colAlive(i) = $1F:next + remaining = 5*11:moveRate = 3+2*remaining + level = (level+1) % 10 + call ResetColumns() + call AnimationFlipCode() +endproc +' +' Redraw the main game screen +' +proc RedrawGame() + local i + cls:sprite clear:text "000000" solid ink 7 dim 1 to 222,10 + text "SCORE<1>" to 56,0:text "SCORE<2>" to 216,0:text "HI-SCORE" to 136,0 + call DrawScore():call DrawLives() + for i = 1 to 3:call DrawShield(i*80,180):next + sprite 0 image $85 to xPlayer,230 +endproc +' +' Move Player +' +proc MovePlayer() + local fire,dx,dy + fire = joypad(dx,dy) + xPlayer = max(0,min(319,xPlayer+dx*6)) + sprite 0 to xPlayer,230 + if yPBullet < 0 then if fire then xPBullet = xPlayer:yPBullet = 230-8:sfx 0,22 +endproc +' +' Draw lives +' +proc DrawLives() + local i + text str$(lives) solid dim 1 ink 2 to 8,230 + if lives > 1 then for i = 1 to lives-1:image $85 to i*16+4,228:next +endproc +' +' Draw the shield +' +proc DrawShield(x,y) + local i,w,h:w = 50:h = 30 + rect x-w\2,y ink 2 solid to x+w\2,y+h + ellipse ink 0 from x-h\3,y+h-h\3 to x+h\3,y+h+h\3 + for i = 0 to w\4 + line x-w\2+i,y-1 to x-w\2,y+i + line x+w\2-i,y-1 to x+w\2,y+i + next +endproc +' +' Move all the invaders +' +proc MoveInvaders() + sys Animate6502 + xLeft = xLeft + xDirection + if xLeft + rightColumn * 16 > 303 | xLeft < 16-16 * leftColumn + xDirection = -xDirection + xLeft = max(min(xLeft,303-rightColumn*16),0) + rect ink 0 solid from 0,yTop to 319,yTop+8 + yTop = yTop + 8:if yTop > 170 then dead = true + if sfxPitch = 100:sfxPitch = 200:else:sfxPitch = 100:endif + sound 0 clear:sound 0,sfxPitch,8 + endif +endproc +' +' Repaint the tile map +' +proc RepaintInvaders() + tiledraw from xLeft,yTop to xLeft+191,yTop+80 +endproc +' +' Reset Bullets +' +proc ResetBullets() + sprite 9 hide:xPBullet = 0:yPBullet = -99 + local i + for i = 1 to invBulletCount:yBullet(i) = -1:sprite i hide:next +endproc +' +' Move Player Bullet +' +proc MovePlayerBullet() + yPBullet = yPBullet - 4 + if yPBullet > 180 then if point(xPBullet,yPBullet) = 2 then call BreakShield(xPBullet,yPBullet+3):yPBullet = -99 + if yPBullet > xTop & yPBullet < yTop+80 + local row,col,pos + row = (yPBullet - yTop) >> 4 + col = (xPBullet - xLeft + 4) >> 4 + pos = (xPBullet - xLeft + 4) & 15 + if col >= 1 & col <= 11 & pos <= 12 + mask = 1 << (row) + if (colAlive(col) & mask) <> 0 + colAlive(col) = colAlive(col)-mask + if colAlive(col) = 0 then call ResetColumns() + sprite 10 image $86 to xLeft+col*16,yTop+row*16+8 + call DeleteAlien(col,row) + score = score + (6-row)\2*10:call DrawScore() + yPBullet = -99 + endif + endif + endif + sprite 9 image $80+((yPBullet >> 2) & 3) to xPBullet,yPBullet +endproc +' +' Hit shields +' +proc BreakShield(x,y) + ellipse from x-5,y-5 ink 0 solid to x+5,y+5 +endproc +' +' Delete Alien +' +proc DeleteAlien(x,y) + poke invMap+3+x+y*13,$F8 + remaining = remaining - 1 + call RepaintInvaders() + sfx 0,21 + endproc +' +' Delay n cs +' +proc Delay(n) + n = time()+n + repeat:until time() > n +endproc +' +' Check if invaders should fire. +' +proc CheckInvaderFire() + currentCheck = currentCheck + 1:if currentCheck > invBulletCount then currentCheck = 1 + if remaining > 0 & yBullet(currentCheck) < 0 + local col,row,n + repeat:col = rand(11)+1:until colAlive(col) <> 0 + n = colAlive(col) >> 1:row = 0 + while n <> 0:row = row + 1:n = n >> 1:wend + xBullet(currentCheck) = xLeft + col * 16 + yBullet(currentCheck) = yTop + row * 16 + sfx 0,23 + endif +endproc +' +' Move invader bullets +' +proc MoveInvaderBullets() + local i + for i = 1 to invBulletCount + if yBullet(i) >= 0 + yBullet(i) = yBullet(i)+4 + if point(xBullet(i),yBullet(i)) = 2 then call BreakShield(xBullet(i),yBullet(i)):yBullet(i) = -99 + if yBullet(i) > 235 then yBullet(i) = -99 + if yBullet(i) > 224 then if abs(xBullet(i)-xPlayer) < 6 then dead = true:sfx 0,19 + sprite i image ($80+(yBullet(i) >> 2) & 3) to xBullet(i),yBullet(i) + endif + next +endproc +' +' Reset left/right column +' +proc ResetColumns() + if remaining > 0 + leftColumn = 1:rightColumn = 11 + while colAlive(leftColumn) = 0:leftColumn = leftColumn+1:wend + while colAlive(rightColumn) = 0:rightColumn = rightColumn-1:wend + endif +endproc +' +' Animation flip +' +proc AnimationFlipCode() +Animate6502 = alloc(64) + for pass = 0 to 1 + p = Animate6502:o = pass * 3 + ldx #3 + .animloop + lda invMap,x + bmi animxskip + cmp #$F0 + bcs animxskip + eor #4 + sta invMap,x + .animxskip + inx + cpx #3+13*5 + bne animloop + rts + next +endproc \ No newline at end of file diff --git a/basic/code/games/invaders.gfx b/basic/code/games/invaders.gfx new file mode 100644 index 00000000..6710553f Binary files /dev/null and b/basic/code/games/invaders.gfx differ diff --git a/basic/storage/invaders.bas b/basic/storage/invaders.bas new file mode 100644 index 00000000..b91d439d Binary files /dev/null and b/basic/storage/invaders.bas differ diff --git a/basic/storage/invaders.bsc b/basic/storage/invaders.bsc new file mode 100644 index 00000000..0fb6918c --- /dev/null +++ b/basic/storage/invaders.bsc @@ -0,0 +1,251 @@ +' +' *** Space Invaders *** +' +cls:gload "invaders.gfx" +call Initialise() + +call ResetMap():call RedrawGame():call ResetBullets():call RepaintInvaders() +repeat + call PlayLevel() +until lives = 0 +end +' +' Play/Continue the current level +' +proc PlayLevel() + dead = false + tMoveInvaders = 0:tMovePlayer = 0:tMoveBullets = 0:tCheckFire = 0 + tFireCheckTime = 100 + repeat + if event(tMoveInvaders,moveRate) then call MoveInvaders():call RepaintInvaders():sprite 10 hide + if event(tMovePlayer,3) then call MovePlayer() + if event(tMoveBullets,3) + if yPBullet > -20 then call MovePlayerBullet() + call MoveInvaderBullets() + endif + if event(tCheckFire,tFireCheckTime) then tFireCheckTime = rand(70)+20:call CheckInvaderFire() + until dead|remaining = 0 + if remaining = 0 then call ResetMap() + if dead then lives = lives - 1 + + if lives > 0 + call Delay(200) + call RedrawGame():call ResetBullets():call RepaintInvaders() + endif + + endproc +' +' The invaders are actually a tilemap, so create it. +' +proc Initialise() + invBulletCount = 2 + invMap = alloc(13 * 5 + 3) + poke invMap,1:poke invMap+1,13:poke invMap+2,6 + tilemap invMap,8,0 + dim colAlive(11),xBullet(invBulletCount),yBullet(invBulletCount) + score = 0:highScore = 1000:lives = 3:level = 0 + xPlayer = 160 +endproc +' +' Redraw the score +' +proc DrawScore() + text right$("000000"+str$(score),6) ink 7 dim 1 solid to 62,10 + if score = 0 | score = highScore then text right$("000000"+str$(highScore),6) ink 7 dim 1 to 142,10 +endproc +' +' Initialise the invaders map and counts +' +proc ResetMap() + local a,c,i,x,y + for y = 0 to 4 + a = y * 13 + invMap + 3:c = (y+1) \ 2 + poke a,$F8:poke a+12,$F8 + for i = 1 to 11:poke a+i,c:next + next + xLeft = 160 - 13 * 8:yTop = 28+level*6:xDirection = 4 + for i = 1 to 11:colAlive(i) = $1F:next + remaining = 5*11:moveRate = 3+2*remaining + level = (level+1) % 10 + call ResetColumns() + call AnimationFlipCode() +endproc +' +' Redraw the main game screen +' +proc RedrawGame() + local i + cls:sprite clear:text "000000" solid ink 7 dim 1 to 222,10 + text "SCORE<1>" to 56,0:text "SCORE<2>" to 216,0:text "HI-SCORE" to 136,0 + call DrawScore():call DrawLives() + for i = 1 to 3:call DrawShield(i*80,180):next + sprite 0 image $85 to xPlayer,230 +endproc +' +' Move Player +' +proc MovePlayer() + local fire,dx,dy + fire = joypad(dx,dy) + xPlayer = max(0,min(319,xPlayer+dx*6)) + sprite 0 to xPlayer,230 + if yPBullet < 0 then if fire then xPBullet = xPlayer:yPBullet = 230-8:sfx 0,22 +endproc +' +' Draw lives +' +proc DrawLives() + local i + text str$(lives) solid dim 1 ink 2 to 8,230 + if lives > 1 then for i = 1 to lives-1:image $85 to i*16+4,228:next +endproc +' +' Draw the shield +' +proc DrawShield(x,y) + local i,w,h:w = 50:h = 30 + rect x-w\2,y ink 2 solid to x+w\2,y+h + ellipse ink 0 from x-h\3,y+h-h\3 to x+h\3,y+h+h\3 + for i = 0 to w\4 + line x-w\2+i,y-1 to x-w\2,y+i + line x+w\2-i,y-1 to x+w\2,y+i + next +endproc +' +' Move all the invaders +' +proc MoveInvaders() + sys Animate6502 + xLeft = xLeft + xDirection + if xLeft + rightColumn * 16 > 303 | xLeft < 16-16 * leftColumn + xDirection = -xDirection + xLeft = max(min(xLeft,303-rightColumn*16),0) + rect ink 0 solid from 0,yTop to 319,yTop+8 + yTop = yTop + 8:if yTop > 170 then dead = true + if sfxPitch = 100:sfxPitch = 200:else:sfxPitch = 100:endif + sound 0 clear:sound 0,sfxPitch,8 + endif +endproc +' +' Repaint the tile map +' +proc RepaintInvaders() + tiledraw from xLeft,yTop to xLeft+191,yTop+80 +endproc +' +' Reset Bullets +' +proc ResetBullets() + sprite 9 hide:xPBullet = 0:yPBullet = -99 + local i + for i = 1 to invBulletCount:yBullet(i) = -1:sprite i hide:next +endproc +' +' Move Player Bullet +' +proc MovePlayerBullet() + yPBullet = yPBullet - 4 + if yPBullet > 180 then if point(xPBullet,yPBullet) = 2 then call BreakShield(xPBullet,yPBullet+3):yPBullet = -99 + if yPBullet > xTop & yPBullet < yTop+80 + local row,col,pos + row = (yPBullet - yTop) >> 4 + col = (xPBullet - xLeft + 4) >> 4 + pos = (xPBullet - xLeft + 4) & 15 + if col >= 1 & col <= 11 & pos <= 12 + mask = 1 << (row) + if (colAlive(col) & mask) <> 0 + colAlive(col) = colAlive(col)-mask + if colAlive(col) = 0 then call ResetColumns() + sprite 10 image $86 to xLeft+col*16,yTop+row*16+8 + call DeleteAlien(col,row) + score = score + (6-row)\2*10:call DrawScore() + yPBullet = -99 + endif + endif + endif + sprite 9 image $80+((yPBullet >> 2) & 3) to xPBullet,yPBullet +endproc +' +' Hit shields +' +proc BreakShield(x,y) + ellipse from x-5,y-5 ink 0 solid to x+5,y+5 +endproc +' +' Delete Alien +' +proc DeleteAlien(x,y) + poke invMap+3+x+y*13,$F8 + remaining = remaining - 1 + call RepaintInvaders() + sfx 0,21 + endproc +' +' Delay n cs +' +proc Delay(n) + n = time()+n + repeat:until time() > n +endproc +' +' Check if invaders should fire. +' +proc CheckInvaderFire() + currentCheck = currentCheck + 1:if currentCheck > invBulletCount then currentCheck = 1 + if remaining > 0 & yBullet(currentCheck) < 0 + local col,row,n + repeat:col = rand(11)+1:until colAlive(col) <> 0 + n = colAlive(col) >> 1:row = 0 + while n <> 0:row = row + 1:n = n >> 1:wend + xBullet(currentCheck) = xLeft + col * 16 + yBullet(currentCheck) = yTop + row * 16 + sfx 0,23 + endif +endproc +' +' Move invader bullets +' +proc MoveInvaderBullets() + local i + for i = 1 to invBulletCount + if yBullet(i) >= 0 + yBullet(i) = yBullet(i)+4 + if point(xBullet(i),yBullet(i)) = 2 then call BreakShield(xBullet(i),yBullet(i)):yBullet(i) = -99 + if yBullet(i) > 235 then yBullet(i) = -99 + if yBullet(i) > 224 then if abs(xBullet(i)-xPlayer) < 6 then dead = true:sfx 0,19 + sprite i image ($80+(yBullet(i) >> 2) & 3) to xBullet(i),yBullet(i) + endif + next +endproc +' +' Reset left/right column +' +proc ResetColumns() + if remaining > 0 + leftColumn = 1:rightColumn = 11 + while colAlive(leftColumn) = 0:leftColumn = leftColumn+1:wend + while colAlive(rightColumn) = 0:rightColumn = rightColumn-1:wend + endif +endproc +' +' Animation flip +' +proc AnimationFlipCode() +Animate6502 = alloc(64) + for pass = 0 to 1 + p = Animate6502:o = pass * 3 + ldx #3 + .animloop + lda invMap,x + bmi animxskip + cmp #$F0 + bcs animxskip + eor #4 + sta invMap,x + .animxskip + inx + cpx #3+13*5 + bne animloop + rts + next +endproc \ No newline at end of file diff --git a/basic/storage/invaders.gfx b/basic/storage/invaders.gfx index 44362c53..6710553f 100644 Binary files a/basic/storage/invaders.gfx and b/basic/storage/invaders.gfx differ diff --git a/emulator/storage/invaders.bas b/emulator/storage/invaders.bas new file mode 100644 index 00000000..b91d439d Binary files /dev/null and b/emulator/storage/invaders.bas differ diff --git a/emulator/storage/invaders.bsc b/emulator/storage/invaders.bsc new file mode 100644 index 00000000..0fb6918c --- /dev/null +++ b/emulator/storage/invaders.bsc @@ -0,0 +1,251 @@ +' +' *** Space Invaders *** +' +cls:gload "invaders.gfx" +call Initialise() + +call ResetMap():call RedrawGame():call ResetBullets():call RepaintInvaders() +repeat + call PlayLevel() +until lives = 0 +end +' +' Play/Continue the current level +' +proc PlayLevel() + dead = false + tMoveInvaders = 0:tMovePlayer = 0:tMoveBullets = 0:tCheckFire = 0 + tFireCheckTime = 100 + repeat + if event(tMoveInvaders,moveRate) then call MoveInvaders():call RepaintInvaders():sprite 10 hide + if event(tMovePlayer,3) then call MovePlayer() + if event(tMoveBullets,3) + if yPBullet > -20 then call MovePlayerBullet() + call MoveInvaderBullets() + endif + if event(tCheckFire,tFireCheckTime) then tFireCheckTime = rand(70)+20:call CheckInvaderFire() + until dead|remaining = 0 + if remaining = 0 then call ResetMap() + if dead then lives = lives - 1 + + if lives > 0 + call Delay(200) + call RedrawGame():call ResetBullets():call RepaintInvaders() + endif + + endproc +' +' The invaders are actually a tilemap, so create it. +' +proc Initialise() + invBulletCount = 2 + invMap = alloc(13 * 5 + 3) + poke invMap,1:poke invMap+1,13:poke invMap+2,6 + tilemap invMap,8,0 + dim colAlive(11),xBullet(invBulletCount),yBullet(invBulletCount) + score = 0:highScore = 1000:lives = 3:level = 0 + xPlayer = 160 +endproc +' +' Redraw the score +' +proc DrawScore() + text right$("000000"+str$(score),6) ink 7 dim 1 solid to 62,10 + if score = 0 | score = highScore then text right$("000000"+str$(highScore),6) ink 7 dim 1 to 142,10 +endproc +' +' Initialise the invaders map and counts +' +proc ResetMap() + local a,c,i,x,y + for y = 0 to 4 + a = y * 13 + invMap + 3:c = (y+1) \ 2 + poke a,$F8:poke a+12,$F8 + for i = 1 to 11:poke a+i,c:next + next + xLeft = 160 - 13 * 8:yTop = 28+level*6:xDirection = 4 + for i = 1 to 11:colAlive(i) = $1F:next + remaining = 5*11:moveRate = 3+2*remaining + level = (level+1) % 10 + call ResetColumns() + call AnimationFlipCode() +endproc +' +' Redraw the main game screen +' +proc RedrawGame() + local i + cls:sprite clear:text "000000" solid ink 7 dim 1 to 222,10 + text "SCORE<1>" to 56,0:text "SCORE<2>" to 216,0:text "HI-SCORE" to 136,0 + call DrawScore():call DrawLives() + for i = 1 to 3:call DrawShield(i*80,180):next + sprite 0 image $85 to xPlayer,230 +endproc +' +' Move Player +' +proc MovePlayer() + local fire,dx,dy + fire = joypad(dx,dy) + xPlayer = max(0,min(319,xPlayer+dx*6)) + sprite 0 to xPlayer,230 + if yPBullet < 0 then if fire then xPBullet = xPlayer:yPBullet = 230-8:sfx 0,22 +endproc +' +' Draw lives +' +proc DrawLives() + local i + text str$(lives) solid dim 1 ink 2 to 8,230 + if lives > 1 then for i = 1 to lives-1:image $85 to i*16+4,228:next +endproc +' +' Draw the shield +' +proc DrawShield(x,y) + local i,w,h:w = 50:h = 30 + rect x-w\2,y ink 2 solid to x+w\2,y+h + ellipse ink 0 from x-h\3,y+h-h\3 to x+h\3,y+h+h\3 + for i = 0 to w\4 + line x-w\2+i,y-1 to x-w\2,y+i + line x+w\2-i,y-1 to x+w\2,y+i + next +endproc +' +' Move all the invaders +' +proc MoveInvaders() + sys Animate6502 + xLeft = xLeft + xDirection + if xLeft + rightColumn * 16 > 303 | xLeft < 16-16 * leftColumn + xDirection = -xDirection + xLeft = max(min(xLeft,303-rightColumn*16),0) + rect ink 0 solid from 0,yTop to 319,yTop+8 + yTop = yTop + 8:if yTop > 170 then dead = true + if sfxPitch = 100:sfxPitch = 200:else:sfxPitch = 100:endif + sound 0 clear:sound 0,sfxPitch,8 + endif +endproc +' +' Repaint the tile map +' +proc RepaintInvaders() + tiledraw from xLeft,yTop to xLeft+191,yTop+80 +endproc +' +' Reset Bullets +' +proc ResetBullets() + sprite 9 hide:xPBullet = 0:yPBullet = -99 + local i + for i = 1 to invBulletCount:yBullet(i) = -1:sprite i hide:next +endproc +' +' Move Player Bullet +' +proc MovePlayerBullet() + yPBullet = yPBullet - 4 + if yPBullet > 180 then if point(xPBullet,yPBullet) = 2 then call BreakShield(xPBullet,yPBullet+3):yPBullet = -99 + if yPBullet > xTop & yPBullet < yTop+80 + local row,col,pos + row = (yPBullet - yTop) >> 4 + col = (xPBullet - xLeft + 4) >> 4 + pos = (xPBullet - xLeft + 4) & 15 + if col >= 1 & col <= 11 & pos <= 12 + mask = 1 << (row) + if (colAlive(col) & mask) <> 0 + colAlive(col) = colAlive(col)-mask + if colAlive(col) = 0 then call ResetColumns() + sprite 10 image $86 to xLeft+col*16,yTop+row*16+8 + call DeleteAlien(col,row) + score = score + (6-row)\2*10:call DrawScore() + yPBullet = -99 + endif + endif + endif + sprite 9 image $80+((yPBullet >> 2) & 3) to xPBullet,yPBullet +endproc +' +' Hit shields +' +proc BreakShield(x,y) + ellipse from x-5,y-5 ink 0 solid to x+5,y+5 +endproc +' +' Delete Alien +' +proc DeleteAlien(x,y) + poke invMap+3+x+y*13,$F8 + remaining = remaining - 1 + call RepaintInvaders() + sfx 0,21 + endproc +' +' Delay n cs +' +proc Delay(n) + n = time()+n + repeat:until time() > n +endproc +' +' Check if invaders should fire. +' +proc CheckInvaderFire() + currentCheck = currentCheck + 1:if currentCheck > invBulletCount then currentCheck = 1 + if remaining > 0 & yBullet(currentCheck) < 0 + local col,row,n + repeat:col = rand(11)+1:until colAlive(col) <> 0 + n = colAlive(col) >> 1:row = 0 + while n <> 0:row = row + 1:n = n >> 1:wend + xBullet(currentCheck) = xLeft + col * 16 + yBullet(currentCheck) = yTop + row * 16 + sfx 0,23 + endif +endproc +' +' Move invader bullets +' +proc MoveInvaderBullets() + local i + for i = 1 to invBulletCount + if yBullet(i) >= 0 + yBullet(i) = yBullet(i)+4 + if point(xBullet(i),yBullet(i)) = 2 then call BreakShield(xBullet(i),yBullet(i)):yBullet(i) = -99 + if yBullet(i) > 235 then yBullet(i) = -99 + if yBullet(i) > 224 then if abs(xBullet(i)-xPlayer) < 6 then dead = true:sfx 0,19 + sprite i image ($80+(yBullet(i) >> 2) & 3) to xBullet(i),yBullet(i) + endif + next +endproc +' +' Reset left/right column +' +proc ResetColumns() + if remaining > 0 + leftColumn = 1:rightColumn = 11 + while colAlive(leftColumn) = 0:leftColumn = leftColumn+1:wend + while colAlive(rightColumn) = 0:rightColumn = rightColumn-1:wend + endif +endproc +' +' Animation flip +' +proc AnimationFlipCode() +Animate6502 = alloc(64) + for pass = 0 to 1 + p = Animate6502:o = pass * 3 + ldx #3 + .animloop + lda invMap,x + bmi animxskip + cmp #$F0 + bcs animxskip + eor #4 + sta invMap,x + .animxskip + inx + cpx #3+13*5 + bne animloop + rts + next +endproc \ No newline at end of file diff --git a/emulator/storage/invaders.gfx b/emulator/storage/invaders.gfx new file mode 100644 index 00000000..6710553f Binary files /dev/null and b/emulator/storage/invaders.gfx differ diff --git a/firmware/common/include/data/prompt.h b/firmware/common/include/data/prompt.h index ead1c2d8..4a4e8679 100644 --- a/firmware/common/include/data/prompt.h +++ b/firmware/common/include/data/prompt.h @@ -1,4 +1,4 @@ // // This file is automatically generated // -#define PROMPT "(Build 2567 30-Jan-24)\r" +#define PROMPT "(Build 2580 30-Jan-24)\r" diff --git a/firmware/common/include/data/sfxdata.h b/firmware/common/include/data/sfxdata.h index 6a984775..67289444 100644 --- a/firmware/common/include/data/sfxdata.h +++ b/firmware/common/include/data/sfxdata.h @@ -60,13 +60,13 @@ static const uint16_t sfxData18[] = { 740,75,0,50,740,75,0,50,740,75,0,50,740,75,0,50,65535 }; // 19 expl100 static const uint16_t sfxData19[] = { -464,1,246,1,439,1,391,1,206,1,394,1,224,1,320,1,582,1,691,1,315,1,581,1,679,1,537,1,474,1,261,1,328,1,226,1,422,1,524,1,246,1,630,1,668,1,696,1,596,1,512,1,203,1,384,1,478,1,317,1,562,1,207,1,393,1,620,1,518,1,503,1,214,1,632,1,327,1,501,1,636,1,423,1,680,1,267,1,430,1,561,1,297,1,299,1,623,1,432,1,65535 }; +553,1,571,1,677,1,696,1,332,1,667,1,626,1,572,1,647,1,270,1,475,1,552,1,611,1,289,1,343,1,693,1,282,1,599,1,333,1,529,1,673,1,531,1,691,1,505,1,216,1,309,1,504,1,395,1,229,1,362,1,311,1,573,1,306,1,608,1,424,1,379,1,527,1,648,1,542,1,283,1,246,1,271,1,572,1,332,1,660,1,665,1,304,1,346,1,693,1,259,1,65535 }; // 20 expl50 static const uint16_t sfxData20[] = { -677,1,258,1,346,1,647,1,470,1,596,1,572,1,609,1,247,1,322,1,594,1,424,1,216,1,369,1,347,1,543,1,315,1,246,1,479,1,602,1,407,1,533,1,463,1,413,1,269,1,65535 }; +399,1,569,1,270,1,462,1,695,1,382,1,391,1,424,1,371,1,360,1,213,1,233,1,539,1,529,1,471,1,491,1,404,1,642,1,492,1,436,1,309,1,345,1,403,1,560,1,434,1,65535 }; // 21 expl20 static const uint16_t sfxData21[] = { -418,1,524,1,457,1,354,1,207,1,547,1,392,1,243,1,301,1,560,1,65535 }; +216,1,655,1,585,1,388,1,468,1,219,1,374,1,680,1,382,1,668,1,65535 }; // 22 las30 static const uint16_t sfxData22[] = { 600,1,574,1,547,1,520,1,494,1,467,1,440,1,414,1,387,1,360,1,334,1,307,1,280,1,254,1,227,1,65535 };