aboutsummaryrefslogtreecommitdiff
path: root/src/score.s
blob: ed36283c09d1f6e7066b51b3b380306106c5da30 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
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