diff options
| author | Miquel Sabaté Solà <mssola@mssola.com> | 2026-03-25 01:03:17 +0100 |
|---|---|---|
| committer | Miquel Sabaté Solà <mssola@mssola.com> | 2026-03-25 01:03:17 +0100 |
| commit | ccf320971efe9b11f7b7722b2ee2642a10303203 (patch) | |
| tree | 9ad50e8ffda2194256a9945de0af44a6fad119a2 /src | |
| parent | fcc4a0c30ee01719451596d579abf4cbe1e9b8a1 (diff) | |
| download | jetpac.nes-ccf320971efe9b11f7b7722b2ee2642a10303203.tar.gz jetpac.nes-ccf320971efe9b11f7b7722b2ee2642a10303203.zip | |
Add support for adding scores
Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/jetpac.s | 14 | ||||
| -rw-r--r-- | src/score.s | 159 |
2 files changed, 172 insertions, 1 deletions
diff --git a/src/jetpac.s b/src/jetpac.s index 3cf8f0a..b356192 100644 --- a/src/jetpac.s +++ b/src/jetpac.s @@ -42,6 +42,7 @@ .include "background.s" .include "prng.s" .include "explosions.s" +.include "score.s" .include "items.s" .include "player.s" .include "enemies.s" @@ -112,7 +113,14 @@ .endproc .proc main - ;; TODO: high score initialization has to happen here. + ;; Initialize the high score. + lda #0 + sta Score::m_hi + sta Score::m_hi + 1 + sta Score::m_hi + 2 + sta Score::m_hi + 3 + sta Score::m_hi + 4 + sta Score::m_hi + 5 @init: ;; Disable the PPU and zero out variables which shadow PPU registers. @@ -156,6 +164,10 @@ ;; Initialize some variables from the "Game Over" side of the game. jsr Over::init + ;; Initialize the score for both players. Note that initializing the high + ;; score is the first thing we do in main(). + jsr Score::init_players_scores + ;; Initialize variables from the game's driver that need to be set before ;; NMIs start ticking. jsr Driver::init_before_nmi diff --git a/src/score.s b/src/score.s new file mode 100644 index 0000000..ed36283 --- /dev/null +++ b/src/score.s @@ -0,0 +1,159 @@ +;; Clear the carry and add ADDR to the indexed digit on 'Score::m_players'. If +;; the result is larger or equal than 10, then 0 is stored and the carry flag is +;; set. Otherwise the carry flag is cleared. +.macro BCD_ADD ADDR + lda Score::m_players, x + clc + adc ADDR + cmp #10 + bcc :+ + sec + lda #0 +: + sta Score::m_players, x +.endmacro + +;; Add ADDR to the indexed digit on 'Score::m_players' _with_ carry. If the +;; result is larger or equal than 10, then 0 is stored and the carry flag is +;; set. Otherwise the carry flag is cleared. +.macro BCD_ADDC ADDR + lda Score::m_players, x + adc ADDR + clc + cmp #10 + bcc :+ + sec + lda #0 +: + sta Score::m_players, x +.endmacro + +;; Only add the carry to the indexed digit on 'Score::m_players' _with_ +;; carry. If the result is larger or equal than 10, then 0 is stored and the +;; carry flag is set. Otherwise the carry flag is cleared. +.macro BCD_JUST_CARRY + lda Score::m_players, x + adc #0 + clc + cmp #10 + bne :+ + sec + lda #0 +: + sta Score::m_players, x +.endmacro + +;; A score is a 6-digit number where each digit is stored on a byte of its +;; own. This makes adding numbers and representing them into the screen dead +;; easy. +;; +;; This is indeed rather wasteful, but we have a lot of RAM to spare and the +;; ease of use is quite convenient. +.scope Score + ;; Scores for both players are stored in a single buffer. Even indeces + ;; contain digits for the first player, and odd indeces contain digits for + ;; the second player. Digits are stored in little-endian format. + ;; + ;; Interweaving digits this way might seem weird, but it actually makes + ;; indexing things super easy: the 'active' bit from + ;; 'Globals::zp_multiplayer' can be used to index the first item, and then + ;; it's a matter of advancing the 'x' register twice in order to get the + ;; next digit. + PLAYERS_BUFF_SIZE = $0C + m_players = $300 ; asan:reserve PLAYERS_BUFF_SIZE + + ;; The high score for this session. + m_hi = $30C ; asan:reserve $06 + + ;; Initialize the scores for both players. + .proc init_players_scores + lda #0 + ldx #0 + + @loop: + sta m_players, x + inx + cpx #PLAYERS_BUFF_SIZE + bne @loop + + rts + .endproc + + ;; Add to the current player's score the number stored in + ;; 'Globals::zp_tmp{0,1,2}', where 'Globals::zp_tmp0' has the least + ;; significant number. + .proc add_to_player + ;; See 'Score::m_players' on why this is the way to select the current + ;; player's score. + lda Globals::zp_multiplayer + and #$01 + tax + + ;;; + ;; The first three digits are the product of adding the contents of + ;; 'Globals::zp_tmp{0,1,2}'. + + BCD_ADD Globals::zp_tmp0 + inx + inx + + BCD_ADDC Globals::zp_tmp1 + inx + inx + + BCD_ADDC Globals::zp_tmp2 + inx + inx + + ;;; + ;; The rest are just a matter of adding the carry. + + BCD_JUST_CARRY + inx + inx + + BCD_JUST_CARRY + inx + inx + + BCD_JUST_CARRY + + ;; TODO: set a flag about updating the score on the HUD. + + rts + .endproc +.endscope + +;; Add the score for a dead enemy to the current player's score. +.macro ADD_ENEMY_SCORE + lda #5 + sta Globals::zp_tmp0 + lda #2 + sta Globals::zp_tmp1 + lda #0 + sta Globals::zp_tmp2 + jsr Score::add_to_player +.endmacro + +;; Add the score for grabbing a shuttle part / fuel tank to the current player's +;; score. +.macro ADD_PART_FUEL_SCORE + lda #0 + sta Globals::zp_tmp0 + lda #0 + sta Globals::zp_tmp1 + lda #1 + sta Globals::zp_tmp2 + jsr Score::add_to_player +.endmacro + +;; Add the score for grabbing an item to the current player's score. +.macro ADD_ITEM_SCORE + lda #0 + sta Globals::zp_tmp0 + lda #5 + sta Globals::zp_tmp1 + lda #2 + sta Globals::zp_tmp2 + jsr Score::add_to_player +.endmacro |
