aboutsummaryrefslogtreecommitdiff
path: root/src/score.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/score.s')
-rw-r--r--src/score.s159
1 files changed, 159 insertions, 0 deletions
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