From b7c591c930ae74998463435e6f05d3312cfd1c8f Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Thu, 3 Apr 2025 19:02:10 +0200 Subject: Add the ability to pause the game MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miquel Sabaté Solà --- include/globals.s | 3 ++- src/driver.s | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/vectors.s | 9 +++++++-- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/include/globals.s b/include/globals.s index 35665f7..395df61 100644 --- a/include/globals.s +++ b/include/globals.s @@ -29,7 +29,8 @@ ;; |-----+------------+-------------------------------------------------------------| ;; | 7 | render | Game logic is over, block main code until NMI code is over. | ;; | 6 | ppu | PPU registers have to be touched | - ;; | 5-3 | - | Unused | + ;; | 5-4 | - | Unused | + ;; | 3 | paused | Game is in pause state | ;; | 2 | title over | We are transitioning from title to game | ;; | 1-0 | game | 0: title; 1: game; 2: game over, 3: game over (coin) | zp_flags = $20 diff --git a/src/driver.s b/src/driver.s index 00e807c..4c2220f 100644 --- a/src/driver.s +++ b/src/driver.s @@ -14,6 +14,10 @@ zp_pal_counter = $31 .endif + ;; Timer for the pause/unpause workflow. + PAUSE_TIMER_VALUE = (HZ / 3) + zp_pause_timer = $32 + ;; Switch from the title screen to the main street. Note that this function ;; is to be called with the PPU disabled. If that's not the case, then it ;; will set the proper values to disable it on the next `nmi` call and set @@ -77,7 +81,57 @@ @load_player: jsr Player::init + ;; Initialize pause timer. + lda #0 + sta zp_pause_timer + @game: + ;; Check if the player is toggling the `pause` state. + lda #(Joypad::BUTTON_START | Joypad::BUTTON_SELECT) + and Joypad::zp_buttons1 + beq @skip_pause_handling + + ;; What does the timer say, is the player allowed to do it? + lda zp_pause_timer + bne @skip_pause_handling + + ;; The timer is zero and the player asked to pause, let's reset the + ;; timer. + lda #PAUSE_TIMER_VALUE + sta zp_pause_timer + + ;; Pause vs unpause. + lda #%00001000 + and Globals::zp_flags + bne @unpause + + ;; Pause: set the flag and skip the update. + lda #%00001000 + ora Globals::zp_flags + sta Globals::zp_flags + rts + + @unpause: + ;; Unset the flag and go to update. + lda #%11110111 + and Globals::zp_flags + sta Globals::zp_flags + bne @do_update + + @skip_pause_handling: + ;; Decrement the pause timer if it's not in a zero value. + lda zp_pause_timer + beq @pause_check + dec zp_pause_timer + + @pause_check: + ;; Are we paused? If so return before updating. + lda #%00001000 + and Globals::zp_flags + beq @do_update + rts + + @do_update: JAL Player::update .endproc diff --git a/src/vectors.s b/src/vectors.s index f9aa31d..559a59d 100644 --- a/src/vectors.s +++ b/src/vectors.s @@ -85,6 +85,11 @@ lda #$02 sta OAM::DMA + ;; Are we paused? If so skip timers, PAL handler and the likes. + lda #%00001000 + and Globals::zp_flags + bne @ppu_registers + ;; PAL-specific code .ifdef PAL jsr Driver::pal_handler @@ -94,10 +99,10 @@ ;; Decrease title timer. lda Title::zp_title_timer - beq :+ + beq @ppu_registers dec Title::zp_title_timer -: +@ppu_registers: ;; Should we update PPU registers? bit Globals::zp_flags bvc @scroll -- cgit v1.2.3