diff --git a/BUGS.md b/BUGS.md index 5e94e2a..6d57e58 100644 --- a/BUGS.md +++ b/BUGS.md @@ -5,6 +5,7 @@ This is a list of the software bugs (as opposed to the bugs in the game that you * The sound is muddy at times on real HW. Especially when lots of stuff is going on, the sound ends up coming out garbled. This isn't happening on emulators where everything is always quite clear. Perhaps I am reaching some limit of the Ensoniq. Do I need to reduce some sampling frequencies perhaps? * I tried reducing the sampling frequency from 11025 for most of the samples to 5513 and I didn't notice any improvement in the quality of the sound on real HW. Nor did I notice any real degredation on real HW or on an emulator. +* The flea appears before the second level actually begins, in the time before the level starts if you have too few mushrooms at the bottom. This is due to the way that levels are incremented now in the game state machine. FIXED diff --git a/BuGS/game.s b/BuGS/game.s index 226598a..188b660 100644 --- a/BuGS/game.s +++ b/BuGS/game.s @@ -26,11 +26,19 @@ game start using tileData using playerData - jsl setupScreen + +PLAYER_DEATH_FRAME_COUNT equ 30 +NEXT_LEVEL_FRAME_COUNT equ 60 +NEXT_PLAYER_FRAME_COUNT equ 180 +GAME_OVER_FRAME_COUNT equ 180 +RESTART_LEVEL_FRAME_COUNT equ 20 + + + jsl setupScreen lda #0 jsl setColour - jsl gameOver + jsl setGameNotRunning jsl updateHighScore gameLoop anop @@ -71,11 +79,11 @@ gameLoop anop jsl updatePlayer jsl updateShot + jsl updateGameState jsl updateScorpion jsl updateSpider jsl updateFlea jsl updateSegments - jsl updateLevel jsl updateSounds jsl checkKeyboard @@ -183,12 +191,13 @@ nextWord anop ; The accumulator has a 0 in it when starting a one player game, 1 when ; starting a two player game. startGame entry - ldx gameRunning - bne startGame_notRunning + ldx gameState + beq startGame_notRunning rtl startGame_notRunning anop sta isSinglePlayer - stz gameRunning + lda #GAME_STATE_LEVEL + sta gameState jsl initPlayer jsl scoreStartGame lda isSinglePlayer @@ -213,12 +222,209 @@ startLevel entry jsl shotInitLevel jsl playerLevelStart jmp levelStart - + +updateGameState entry + lda gameState + beq updateGameState_none + cmp #GAME_STATE_LEVEL + beq updateGameState_level + cmp #GAME_STATE_NEXT_LEVEL + beq updateGameState_nextLevel + cmp #GAME_STATE_PLAYER_DYING + beq updateGameState_playerDying + cmp #GAME_STATE_BONUS + beq updateGameState_bonus + jmp updateGameState_moreStates +updateGameState_none anop + stz frameCount + rtl + +updateGameState_level anop + lda numSegments + bne updateGameState_levelNotDone + jsl levelNext + lda #GAME_STATE_NEXT_LEVEL + sta gameState + lda #NEXT_LEVEL_FRAME_COUNT + sta frameCount + jsl stopSegmentSound +updateGameState_levelNotDone anop + lda playerState + cmp #PLAYER_STATE_EXPLODING + bne updateGameState_levelPlayerNotDying + lda #GAME_STATE_PLAYER_DYING + sta gameState + lda #PLAYER_DEATH_FRAME_COUNT + sta frameCount +updateGameState_levelPlayerNotDying anop + rtl + +updateGameState_nextLevel anop + lda playerState + cmp #PLAYER_STATE_EXPLODING + bne updateGameState_nextLevelPlayerNotDying + lda #GAME_STATE_PLAYER_DYING + sta gameState + lda #PLAYER_DEATH_FRAME_COUNT + sta frameCount + rtl +updateGameState_nextLevelPlayerNotDying anop + lda frameCount + beq updateGameState_startLevel + dec a + sta frameCount + rtl +updateGameState_startLevel anop + lda #GAME_STATE_LEVEL + sta gameState + jmp levelStart + +updateGameState_playerDying anop + lda frameCount + beq updateGameState_playerDead + dec a + sta frameCount + rtl +updateGameState_playerDead anop + lda #GAME_STATE_BONUS + sta gameState + jsl segmentsInitLevel + jsl scorpionInitLevel + jsl spiderInitLevel + jsl fleaInitLevel + rtl + +updateGameState_bonus anop + jsl resetMushrooms + bcc updateGameState_doneBonus + rtl +updateGameState_doneBonus anop + ldx playerNum + lda numLives,x + bne updateGameState_gameNotOver + jsl checkHighScore + bcc updateGameState_notHighScore + lda isSinglePlayer + beq updateGameState_isSinglePlayer + stz isSinglePlayer + bra updateGameState_twoPlayer +updateGameState_isSinglePlayer anop + jmp setGameNotRunning +updateGameState_notHighScore anop + lda isSinglePlayer + beq updateGameState_isSinglePlayer + lda #GAME_STATE_GAME_OVER + sta gameState + lda #GAME_OVER_FRAME_COUNT + rtl +updateGameState_gameNotOver anop + jsl segmentsInitLevel + jsl scorpionInitLevel + jsl spiderInitLevel + jsl fleaInitLevel + lda isSinglePlayer + bne updateGameState_twoPlayer + lda #GAME_STATE_NEXT_LIFE + sta gameState + lda #RESTART_LEVEL_FRAME_COUNT + sta frameCount + rtl +updateGameState_twoPlayer anop + lda #GAME_STATE_NEXT_PLAYER + sta gameState + lda #NEXT_PLAYER_FRAME_COUNT + sta frameCount + lda playerNum + eor #PLAYER_TWO + sta playerNum + jsl scoreSwitchPlayer + ldx playerNum + lda colourLevelNum,x + jsl setColour + lda playerNum + beq updateGameState_toPlayer1 + jsl copyToPlayer1Tiles + jmp copyFromPlayer2Tiles +updateGameState_toPlayer1 anop + jsl copyToPlayer2Tiles + jmp copyFromPlayer1Tiles + +updateGameState_moreStates anop + cmp #GAME_STATE_NEXT_LIFE + beq updateGameState_nextLife + cmp #GAME_STATE_NEXT_PLAYER + beq updateGameState_nextPlayer + cmp #GAME_STATE_GAME_OVER + beq updateGameState_gameOver + rtl + +updateGameState_nextLife anop + lda frameCount + bne updateGameState_nextLifeWait + lda #GAME_STATE_LEVEL + sta gameState + jmp startLevel +updateGameState_nextLifeWait anop + dec a + sta frameCount + rtl + +updateGameState_nextPlayer anop + lda frameCount + bne updateGameState_nextPlayerWait + lda #GAME_STATE_LEVEL + sta gameState + jmp startLevel +updateGameState_nextPlayerWait anop + dec a + sta frameCount +updateGameState_printPlayerNumber anop + ldx #GAME_NUM_TILES_WIDE*12+16 + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_LETTER_P + _overwriteGameTile TILE_LETTER_L + _overwriteGameTile TILE_LETTER_A + _overwriteGameTile TILE_LETTER_Y + _overwriteGameTile TILE_LETTER_E + _overwriteGameTile TILE_LETTER_R + _overwriteGameTile TILE_EMPTY + lda playerNum + beq updateGameState_displayPlayer1 + _overwriteGameTile TILE_NUMBER_2 + rtl +updateGameState_displayPlayer1 anop + _overwriteGameTile TILE_NUMBER_1 + rtl + +updateGameState_gameOver anop + lda frameCount + bne updateGameState_gameOverWait + stz isSinglePlayer + jmp updateGameState_twoPlayer + +updateGameState_gameOverWait anop + dec a + sta frameCount + ldx #GAME_NUM_TILES_WIDE*11+12 + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_LETTER_G + _overwriteGameTile TILE_LETTER_A + _overwriteGameTile TILE_LETTER_M + _overwriteGameTile TILE_LETTER_E + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_LETTER_O + _overwriteGameTile TILE_LETTER_V + _overwriteGameTile TILE_LETTER_E + _overwriteGameTile TILE_LETTER_R + _overwriteGameTile TILE_EMPTY + jmp updateGameState_printPlayerNumber + + copyToPlayer1Tiles entry ldx #0 copyToPlayer1Tiles_loop anop - lda tileData,x + lda tileType,x sta >player1Tiles,x inx inx @@ -230,7 +436,7 @@ copyToPlayer1Tiles_loop anop copyToPlayer2Tiles entry ldx #0 copyToPlayer2Tiles_loop anop - lda tileData,x + lda tileType,x sta >player2Tiles,x inx inx @@ -243,9 +449,9 @@ copyFromPlayer1Tiles entry ldx #0 copyFromPlayer1Tiles_loop anop lda >player1Tiles,x - cmp tileData,x + cmp tileType,x beq copyFromPlayer1Tiles_skip - sta tileData,x + sta tileType,x lda TILE_STATE_DIRTY sta tileDirty,x copyFromPlayer1Tiles_skip anop @@ -260,9 +466,9 @@ copyFromPlayer2Tiles entry ldx #0 copyFromPlayer2Tiles_loop anop lda >player2Tiles,x - cmp tileData,x + cmp tileType,x beq copyFromPlayer2Tiles_skip - sta tileData,x + sta tileType,x lda TILE_STATE_DIRTY sta tileDirty,x copyFromPlayer2Tiles_skip anop @@ -460,15 +666,13 @@ setGameTile_skip anop rts -gameOver entry - lda #1 - sta gameRunning +setGameNotRunning entry + lda #GAME_STATE_NOT_RUNNING + sta gameState jsl segmentsInitLevel jsl scorpionInitLevel jsl spiderInitLevel jsl fleaInitLevel - - jsl checkHighScore jsl addRandomMushrooms jmp staticGameBoard @@ -761,8 +965,8 @@ checkKey_loop2 anop long i,m and #$007f - ldx gameRunning - beq checkKey_pause + ldx gameState + bne checkKey_pause cmp #'q' beq checkKey_quit @@ -823,7 +1027,8 @@ vblLoop anop rtl -shouldQuit dc i2'1' -borderColour dc i2'0' +shouldQuit dc i2'1' +borderColour dc i2'0' +frameCount dc i2'0' end diff --git a/BuGS/gameFlea.s b/BuGS/gameFlea.s index 5701c95..2874559 100644 --- a/BuGS/gameFlea.s +++ b/BuGS/gameFlea.s @@ -96,8 +96,8 @@ updateFlea_explosionDone anop rtl updateFlea_maybeAdd anop - lda gameRunning - bne updateFlea_doNotAdd + lda gameState + beq updateFlea_doNotAdd ldx playerNum lda gameLevel,x beq updateFlea_doNotAdd diff --git a/BuGS/gamePlayer.s b/BuGS/gamePlayer.s index e5aad65..079c903 100644 --- a/BuGS/gamePlayer.s +++ b/BuGS/gamePlayer.s @@ -38,10 +38,6 @@ initPlayer_loop1 anop lda isSinglePlayer beq initPlayer_done -; DEBUG -; lda #PLAYER_TWO -; sta playerNum -; DEBUG ldy #STARTING_NUM_LIVES sty numLives+2 ldx #P2_LIVES_OFFSET @@ -118,34 +114,18 @@ playerAddLife_cont anop updatePlayer entry - lda gameRunning - beq updatePlayer_gameRunning + lda gameState + bne updatePlayer_gameRunning rtl updatePlayer_gameRunning anop lda playerState cmp #PLAYER_STATE_NONE bne updatePlayer_notNone - lda playerFrameCount - bne updatePlayer_wait - ldx playerNum - lda numLives,x - beq updatePlayer_gameOver - lda numSegments - bne updatePlayer_notNextLevel -; If we are going to the next level, let updateLevel handle that for us. - rtl -updatePlayer_notNextLevel anop - jmp startLevel -updatePlayer_gameOver anop - jmp gameOver -updatePlayer_wait anop - dec a - sta playerFrameCount rtl updatePlayer_notNone anop cmp #PLAYER_STATE_EXPLODING beq updatePlayer_exploding - jmp updatePlayer_notExploding + jmp updatePlayer_onScreen updatePlayer_exploding anop lda playerFrameCount beq updatePlayer_nextExplosion @@ -162,7 +142,7 @@ updatePlayer_nextExplosion anop sta playerFrameCount bra updatePlayer_drawExplosion updatePlayer_doneExplosion anop - lda #PLAYER_STATE_MUSHROOMS + lda #PLAYER_STATE_NONE sta playerState rtl @@ -207,21 +187,7 @@ jumpInst anop jmp >shipExplosion1 nop -updatePlayer_notExploding anop - cmp #PLAYER_STATE_MUSHROOMS - bne updatePlayer_notMushrooms - jsl resetMushrooms - bcc updatePlayer_doneMushrooms - rtl - -updatePlayer_doneMushrooms anop - lda #PLAYER_RESTART_LEVEL_FRAME_COUNT - sta playerFrameCount - lda #PLAYER_STATE_NONE - sta playerState - rtl - -updatePlayer_notMushrooms anop +updatePlayer_onScreen anop ldx #0 ldy #0 ; This code for reading the mouse data is based on some code which John Brooks helpfully provided, although I did things diff --git a/BuGS/gameSound.s b/BuGS/gameSound.s index a6d1b83..a86d81c 100644 --- a/BuGS/gameSound.s +++ b/BuGS/gameSound.s @@ -595,8 +595,8 @@ soundInit entry updateSounds entry - lda gameRunning - bne updateSounds_done + lda gameState + beq updateSounds_done lda fleaSoundIsPlaying bne updateSounds_done diff --git a/BuGS/gameSpider.s b/BuGS/gameSpider.s index 056205d..ec64fdb 100644 --- a/BuGS/gameSpider.s +++ b/BuGS/gameSpider.s @@ -294,8 +294,8 @@ updateSpider_done anop rtl updateSpider_maybeAdd anop - lda gameRunning - bne updateSpider_done + lda gameState + beq updateSpider_done lda spiderAddTime bne updateSpider_waitForAdd lda #SPIDER_ADD_TIME diff --git a/BuGS/globals.s b/BuGS/globals.s index b6f678f..6fa1005 100644 --- a/BuGS/globals.s +++ b/BuGS/globals.s @@ -21,8 +21,16 @@ SEGMENT_DIR_RIGHT equ 1 PLAYER_STATE_NONE equ 0 PLAYER_STATE_EXPLODING equ 1 -PLAYER_STATE_MUSHROOMS equ 2 -PLAYER_STATE_ONSCREEN equ 3 +PLAYER_STATE_ONSCREEN equ 2 + +GAME_STATE_NOT_RUNNING equ 0 +GAME_STATE_LEVEL equ 1 +GAME_STATE_NEXT_LEVEL equ 2 +GAME_STATE_PLAYER_DYING equ 3 +GAME_STATE_BONUS equ 4 +GAME_STATE_NEXT_LIFE equ 5 +GAME_STATE_NEXT_PLAYER equ 6 +GAME_STATE_GAME_OVER equ 7 ; The code uses segmentPixelOffset and the segment speed to figure out whether to draw the shifted sprite ; or the regular sprite. By AND-ing with the speed, if the result is 0, then we want a non-shifted sprite. @@ -138,7 +146,7 @@ PLAYER_ONE gequ 0 PLAYER_TWO gequ 2 -gameRunning dc i2'1' +gameState dc i2'GAME_STATE_NOT_RUNNING' ; The following data values hold the game state and when/if 2 player is supported, ; this information will need to be copied to a backup location when the player diff --git a/BuGS/level.s b/BuGS/level.s index c0be4ed..3067592 100644 --- a/BuGS/level.s +++ b/BuGS/level.s @@ -14,8 +14,6 @@ level start using globalData using tileData -NEXT_LEVEL_FRAME_COUNT equ 60 - levelInit entry stz gameLevel @@ -25,7 +23,8 @@ levelInit entry stz colourLevelNum stz colourLevelNum+2 lda #SEGMENT_SPEED_FAST - sta levelOne+2 + sta levelSpeed + sta levelSpeed+2 rtl @@ -39,6 +38,8 @@ levelStart entry ldx centipedeLevelNum,y lda levelTable,x tax + lda levelSpeed,y + sta |$2,x lda |$0,x sta centipedeNum ; We add centipedes in reverse order which means we need to load X up with the address @@ -72,35 +73,7 @@ levelStart_loop anop bra levelStart_loop levelStart_done anop rtl - - -updateLevel entry - lda gameRunning - beq updateLevel_cont - stz nextLevelFrameCount - rtl -updateLevel_cont anop - lda playerState - cmp #PLAYER_STATE_EXPLODING - beq updateLevel_done - cmp #PLAYER_STATE_MUSHROOMS - beq updateLevel_done - lda nextLevelFrameCount - beq updateLevel_checkSegments - dec a - sta nextLevelFrameCount - bne updateLevel_done - jsl levelNext - jmp levelStart -updateLevel_checkSegments anop - bne updateLevel_done - lda numSegments - bne updateLevel_done - lda #NEXT_LEVEL_FRAME_COUNT - sta nextLevelFrameCount - jsl stopSegmentSound -updateLevel_done anop - rtl + levelNext entry ldx playerNum @@ -119,17 +92,16 @@ levelNext_skip anop bge levelNext_fastOnly ldx playerNum - ldy centipedeLevelNum,x - ldx levelTable,y - lda |$2,x + lda levelSpeed,x cmp #SEGMENT_SPEED_FAST beq levelNext_slowIncrement lda #SEGMENT_SPEED_FAST - sta |$2,x + sta levelSpeed,x rtl - + levelNext_slowIncrement anop - ldx playerNum + lda #SEGMENT_SPEED_SLOW + sta levelSpeed,x lda centipedeLevelNum,x cmp #LEVEL_TABLE_LAST_OFFSET bge levelNext_slowWrap @@ -140,14 +112,12 @@ levelNext_slowWrap anop lda #0 levelNext_slowNoWrap anop sta centipedeLevelNum,x - tay - ldx levelTable,y - lda #SEGMENT_SPEED_SLOW - sta |$2,x rtl levelNext_fastOnly anop ldx playerNum + lda #SEGMENT_SPEED_FAST + sta levelSpeed,x lda centipedeLevelNum,x cmp #LEVEL_TABLE_LAST_OFFSET bge levelNext_fastWrap @@ -158,16 +128,12 @@ levelNext_fastWrap anop lda #0 levelNext_fastNoWrap anop sta centipedeLevelNum,x - tay - ldx levelTable,y - lda #SEGMENT_SPEED_FAST - sta |$2,x - rtl -centipedeNum dc i2'0' -nextLevelFrameCount dc i2'0' +centipedeNum dc i2'0' +levelSpeed dc i2'SEGMENT_SPEED_FAST' + dc i2'SEGMENT_SPEED_FAST' ; The level structure looks like this: ; number of independent centipedes (2 bytes) diff --git a/BuGS/score.s b/BuGS/score.s index ccd44d2..84a19fa 100644 --- a/BuGS/score.s +++ b/BuGS/score.s @@ -400,6 +400,7 @@ checkHighScore_next anop tay cpy #SETTINGS_HIGH_SCORE_SIZE*10 blt checkHighScore_loop + clc rtl checkHighScore_isHighScore anop sty scoreIndex @@ -766,7 +767,9 @@ checkHighScore_isInvalid anop checkHighScore_doneInitials anop jsl saveSettings - jmp updateHighScore + jsl updateHighScore + sec + rtl scoreIndex dc i2'0'