-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathgamefield.asm
289 lines (244 loc) · 5.33 KB
/
gamefield.asm
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
; Troy's HBC-56 - 6502 - Invaders
;
; Copyright (c) 2021 Troy Schrapel
;
; This code is licensed under the MIT license
;
; https://github.com/visrealm/hbc-56
;
; Game field definitions
;
GAMEFIELD = $6000
GAME_COLS = 11
GAME_ROWS = 10
; X/Y indexes as tile location in screeen tiles
; returns:
; X/Y
tileXyToGameFieldXy:
txa
clc ; clear to subtract (offset + 1)
sbc GAMEFIELD_OFFSET_X
+div2
tax
tya
sec
sbc GAMEFIELD_OFFSET_Y
+div2
tay
rts
randomBottomRowInvader:
lda GAMEFIELD_LAST_ROW
+div2
sta TMP_Y_POSITION
inc TMP_Y_POSITION
lda HBC56_SECONDS_L
eor HBC56_TICKS
eor PLAYER_X
eor SCORE_BCD_L
and #$0f
tay
cmp #11
bcc .inRange
sec
sbc #10
.inRange
sta TMP_X_POSITION
-
dec TMP_Y_POSITION
bmi +
jsr gameFieldObjectAt
cmp #INVADER1_PATT
bcc -
+
ldx TMP_X_POSITION
ldy TMP_Y_POSITION
rts
; Sets the TMS location for the given gamefield offset
gameFieldRowSetTmsPos:
lda TMP_X_POSITION
+mul2
clc
adc GAMEFIELD_OFFSET_X
tax
lda TMP_Y_POSITION
clc
adc GAMEFIELD_OFFSET_Y
tay
jmp tmsSetPosWrite
; X/Y gamefield index
; returns:
; screen pixel location of centre of the game object
gameFieldXyToPixelXy:
txa
+mul2
clc
adc GAMEFIELD_OFFSET_X
+mul8
clc
adc INVADER_PIXEL_OFFSET
adc #6
tax
tya
+mul2
clc
adc GAMEFIELD_OFFSET_Y
+mul8
sec
sbc #6
tay
rts
; -----------------------------------------------------------------------------
; gameFieldObjectAt: Return gamefield object at given location
; -----------------------------------------------------------------------------
; TMP_X_POSITION: X Offset into gamefield
; TMP_Y_POSITION: Y Offset into gamefield
; -----------------------------------------------------------------------------
gameFieldObjectAt:
lda TMP_Y_POSITION
and #$fe
+mul8
clc
adc TMP_X_POSITION
tax
lda GAMEFIELD, x
rts
; -----------------------------------------------------------------------------
; killObjectAt: Kill gamefield object at given location
; -----------------------------------------------------------------------------
; TMP_X_POSITION: X Offset into gamefield
; TMP_Y_POSITION: Y Offset into gamefield
; -----------------------------------------------------------------------------
killObjectAt:
lda TMP_Y_POSITION
+mul16
clc
adc TMP_X_POSITION
tax
lda GAMEFIELD, x
pha
lda #0
sta GAMEFIELD, x
; return score in A
pla
+div8
sec
sbc #15
sta GAMEFIELD_TMP
sed
clc
adc GAMEFIELD_TMP
adc GAMEFIELD_TMP
adc GAMEFIELD_TMP
adc GAMEFIELD_TMP
cld
rts
; Returns:
; X/Y - pixel location of object that was killed
; Is the row at TMP_Y_POSITION clear?
gameFieldRowClear:
lda #0
sta TMP_X_POSITION
jsr gameFieldObjectAt
ldy #12
-
inx
lda GAMEFIELD, x
bne .notClear
dey
bne -
clc
rts
.notClear
sec
rts
renderGameField:
lda #0
sta TMP_X_POSITION
sta TMP_GAMEFIELD_OFFSET
lda #255
sta TMP_Y_POSITION
jsr gameFieldRowSetTmsPos
; send a blank row
ldx #GAME_COLS * 2 + 2
lda #0
-
+tmsPut
dex
bne -
lda #0
sta TMP_Y_POSITION
.startRow
lda #0
sta TMP_X_POSITION
jsr gameFieldRowSetTmsPos
+tmsPut 0 ; first col - 0
.renderGameObjRow0
; get the game object at TMP_X_POSITION, TMP_Y_POSITION
jsr gameFieldObjectAt
+tmsPut
beq +
clc
adc #1
+
+tmsPut
inc TMP_X_POSITION
lda TMP_X_POSITION
cmp #GAME_COLS
bne .renderGameObjRow0
+tmsPut 0 ; last col - 0
lda #0
sta TMP_X_POSITION
inc TMP_Y_POSITION
jsr gameFieldRowSetTmsPos
+tmsPut 0 ; first col - 0
lda TMP_Y_POSITION
cmp GAMEFIELD_LAST_ROW
beq +
bcc +
rts
+
.renderGameObjRow1
; get the game object at TMP_X_POSITION, TMP_Y_POSITION
jsr gameFieldObjectAt
beq +
clc
adc #2
+
+tmsPut
beq +
clc
adc #1
+
+tmsPut
inc TMP_X_POSITION
lda TMP_X_POSITION
cmp #GAME_COLS
bne .renderGameObjRow1
+tmsPut 0 ; last col - 0
jsr gameFieldRowClear
bcs +
lda TMP_Y_POSITION
sta GAMEFIELD_LAST_ROW
dec GAMEFIELD_LAST_ROW
rts
+
inc TMP_Y_POSITION
lda TMP_Y_POSITION
cmp GAMEFIELD_LAST_ROW
beq +
bcs +
jmp .startRow
+
rts
initialGameField:
!fill 11, INVADER3_PATT
!fill 5, 0
!fill 11, INVADER2_PATT
!fill 5, 0
!fill 11, INVADER2_PATT
!fill 5, 0
!fill 11, INVADER1_PATT
!fill 5, 0
!fill 11, INVADER1_PATT
!fill 5, 0
!fill 11, 0