-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnv_sprite_raw_collisions_code.asm
336 lines (267 loc) · 11.3 KB
/
nv_sprite_raw_collisions_code.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
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
//////////////////////////////////////////////////////////////////////////////
// nv_sprite_raw_collisions_code.asm
// Copyright(c) 2021 Neal Smith.
// License: MIT. See LICENSE file in root directory.
//////////////////////////////////////////////////////////////////////////////
// Contains code, data, and supporting macros to determine current
// collisions between sprites using the raw sprite HW, not the
// sprite extra data block or sprite_info struct.
#importonce
#if !NV_C64_UTIL_DATA
.error "Error - nv_sprite_raw_collisions_code.asm: NV_C64_UTIL_DATA not defined. Import nv_c64_util_data.asm"
#endif
// the #if above doesn't seem to always work so..
// if data hasn't been imported yet, import it into default location
#importif !NV_C64_UTIL_DATA "nv_c64_util_default_data.asm"
#import "nv_math16_macs.asm"
#import "nv_math8_macs.asm"
#import "nv_branch16_macs.asm"
#import "nv_sprite_raw_macs.asm"
#import "nv_debug_macs.asm"
// Comment out to prevent debug messages on screen
//#define DEBUG_COLLISIONS
//////////////////////////////////////////////////////////////////////////////
// inline macro to check if there is currently a collision between
// one sprite and any other sprites.
// macro parameters:
// sprite_num_to_check: this is the sprite number (0-7) for the sprite
// we are checking
// subroutine params:
// nv_a8: should be set with current HW sprite collisions register
// by calling nv_sprite_raw_get_sprite_collisions_in_a or
// similar methods. it will be modified within though.
// return: (nv_b8) will contain $FF if no collision with sprite_num sprite
// or it will have the sprite number for the colliding sprite
.macro nv_sprite_raw_check_collision(sprite_num)
{
// this macro uses the following data variables from
// nv_c64_util_data.asm
// collision_bit:
// closest_sprite:
// closest_rel_dist:
// The subroutine NvSpriteRawGetRelDistReg will set nv_g16 with the
// relative distance between two sprites. we'll call it
// temp_rel_dist in this routine to try and stay sane.
.label temp_rel_dist = nv_g16
// current HW sprite collisions register value must have
// been placed in nv_a8 prior to calling
lda nv_a8
sta collision_bit
.if (sprite_num > 7)
{
.error("Error - nv_sprite_raw_check_collision: sprite_num too big")
}
.var sprite_mask = $01 << sprite_num
.var sprite_mask_negated = sprite_mask ^ $FF
// initialize closest relative distance to largest positive number
nv_store16_immed(closest_rel_dist, $8FFF)
// initialize closest sprite to $FF which is an invalid sprite
// if its still this at the end, then no collision with sprite_num
nv_xfer8x_immed_mem($FF, closest_sprite)
lda collision_bit
nv_debug_print_labeled_byte_mem_coll(10, 0, collision_bit_label1, 17,
collision_bit, true, false)
and #sprite_mask
bne HaveCollisionWithSpriteNum
jmp ClosestSpriteSet
HaveCollisionWithSpriteNum:
//nv_debug_print_byte_mem(8, 0, collision_bit, true, false)
// turn off the bit for sprite_num so we don't check for collision
// with ourself.
lda #sprite_mask_negated
and collision_bit
sta collision_bit
nv_debug_print_labeled_byte_mem_coll(11, 0, collision_bit_label2, 17,
collision_bit, true, false)
CheckSprite0:
ror collision_bit // rotate bit for sprite 0 (ship) bit to carry
bcs WasSprite0
jmp CheckSprite1
WasSprite0:
ldx #sprite_num
ldy #0
jsr NvSpriteRawGetRelDistReg // load temp_rel_dist with rel distance
nv_debug_print_labeled_word_mem_coll(12, 0, spt_0_dist_label, 14,
temp_rel_dist, true, false)
nv_bge16(temp_rel_dist, closest_rel_dist, CheckSprite1)
// save the new closest rel distance
nv_xfer16_mem_mem(temp_rel_dist, closest_rel_dist)
// save the new closest sprite
nv_xfer8x_immed_mem($00, closest_sprite)
CheckSprite1:
// carry is set here
ror collision_bit // rotate bit for sprite 1 bit to carry
bcs WasSprite1
jmp CheckSprite2
WasSprite1:
ldx #sprite_num
ldy #1
jsr NvSpriteRawGetRelDistReg // load temp_rel_dist with rel distance
nv_debug_print_labeled_word_mem_coll(13, 0, spt_1_dist_label, 14,
temp_rel_dist, true, false)
nv_bge16(temp_rel_dist, closest_rel_dist, CheckSprite2)
// save the new closest rel distance
nv_xfer16_mem_mem(temp_rel_dist, closest_rel_dist)
// save the new closest sprite
nv_xfer8x_immed_mem(1, closest_sprite)
CheckSprite2:
ror collision_bit // rotate bit for sprite 2 bit to carry
bcs WasSprite2
jmp CheckSprite3
WasSprite2:
ldx #sprite_num
ldy #2
jsr NvSpriteRawGetRelDistReg // load temp_rel_dist with rel distance
nv_debug_print_labeled_word_mem_coll(14, 0, spt_2_dist_label, 14,
temp_rel_dist, true, false)
nv_bge16(temp_rel_dist, closest_rel_dist, CheckSprite3)
// save the new closest rel distance
nv_xfer16_mem_mem(temp_rel_dist, closest_rel_dist)
// save the new closest sprite
nv_xfer8x_immed_mem(2, closest_sprite)
CheckSprite3:
ror collision_bit // rotate bit for sprite 3 bit to carry
bcs WasSprite3
jmp CheckSprite4
WasSprite3:
ldx #sprite_num
ldy #3
jsr NvSpriteRawGetRelDistReg // load temp_rel_dist with rel distance
nv_debug_print_labeled_word_mem_coll(15, 0, spt_3_dist_label, 14,
temp_rel_dist, true, false)
nv_bge16(temp_rel_dist, closest_rel_dist, CheckSprite4)
// save the new closest rel distance
nv_xfer16_mem_mem(temp_rel_dist, closest_rel_dist)
// save the new closest sprite
nv_xfer8x_immed_mem(3, closest_sprite)
CheckSprite4:
ror collision_bit // rotate bit for sprite 4 bit to carry
bcs WasSprite4
jmp CheckSprite5
WasSprite4:
ldx #sprite_num
ldy #4
jsr NvSpriteRawGetRelDistReg // load temp_rel_dist with rel distance
nv_debug_print_labeled_word_mem_coll(16, 0, spt_4_dist_label, 14,
temp_rel_dist, true, false)
nv_bge16(temp_rel_dist, closest_rel_dist, CheckSprite5)
// save the new closest rel distance
nv_xfer16_mem_mem(temp_rel_dist, closest_rel_dist)
// save the new closest sprite
nv_xfer8x_immed_mem(4, closest_sprite)
CheckSprite5:
ror collision_bit // rotate bit for sprite 5 bit to carry
bcs WasSprite5
jmp CheckSprite6
WasSprite5:
ldx #sprite_num
ldy #5
jsr NvSpriteRawGetRelDistReg // load temp_rel_dist with rel distance
nv_debug_print_labeled_word_mem_coll(17, 21, nv_g16_label, 8, nv_g16, true, false)
nv_debug_print_labeled_word_mem_coll(17, 0, spt_5_dist_label, 14,
temp_rel_dist, true, false)
nv_bge16(temp_rel_dist, closest_rel_dist, CheckSprite6)
// save the new closest rel distance
nv_xfer16_mem_mem(temp_rel_dist, closest_rel_dist)
// save the new closest sprite
nv_xfer8x_immed_mem(5, closest_sprite)
CheckSprite6:
ror collision_bit // rotate bit for sprite 6 bit to carry
bcs WasSprite6
jmp CheckSprite7
WasSprite6:
ldx #sprite_num
ldy #6
jsr NvSpriteRawGetRelDistReg // load temp_rel_dist with rel distance
nv_debug_print_labeled_word_mem_coll(18, 0, spt_6_dist_label, 14,
temp_rel_dist, true, false)
nv_bge16(temp_rel_dist, closest_rel_dist, CheckSprite7)
// save the new closest rel distance
nv_xfer16_mem_mem(temp_rel_dist, closest_rel_dist)
// save the new closest sprite
nv_xfer8x_immed_mem(6, closest_sprite)
CheckSprite7:
ror collision_bit // rotate bit for sprite 7 bit to carry
bcs WasSprite7
jmp DoneChecking
WasSprite7:
ldx #sprite_num
ldy #7
jsr NvSpriteRawGetRelDistReg // load temp_rel_dist with rel distance
nv_debug_print_labeled_word_mem_coll(19, 0, spt_7_dist_label, 14,
temp_rel_dist, true, false)
nv_bge16(temp_rel_dist, closest_rel_dist, DoneChecking)
// save the new closest rel distance
nv_xfer16_mem_mem(temp_rel_dist, closest_rel_dist)
// save the new closest sprite
nv_xfer8x_immed_mem(7, closest_sprite)
DoneChecking:
ClosestSpriteSet:
lda closest_sprite
sta nv_b8
}
//////////////////////////////////////////////////////////////////////////////
// inline macro to debug collisions by printing a label followed by a byte
// value at specified row, and col on screen. Same params as nv_debug_xxx
// macro with similar name
// only outputs when DEBUG_COLLISIONS is defined
.macro nv_debug_print_labeled_byte_mem_coll(row, col, label_addr,
label_len, value_addr,
include_dollar, wait)
{
#if DEBUG_COLLISIONS
nv_debug_print_labeled_byte_mem(row, col, label_addr,
label_len, value_addr,
include_dollar, wait)
#endif
}
//////////////////////////////////////////////////////////////////////////////
// inline macro to debug collisions by printing a label followed by a word
// value at specified row, and col on screen. Same params as nv_debug_xxx
// macro with similar name
// only outputs when DEBUG_COLLISIONS is defined
.macro nv_debug_print_labeled_word_mem_coll(row, col, label_addr,
label_len, value_addr,
include_dollar, wait)
{
#if DEBUG_COLLISIONS
nv_debug_print_labeled_word_mem(row, col, label_addr, label_len,
value_addr, include_dollar, wait)
#endif
}
//////////////////////////////////////////////////////////////////////////////
// subroutine to get relative distance between two sprites.
// subroutine params:
// X Reg: sprite number for one sprite
// Y Reg: sprite number for other sprite
// Return: (in nv_g16) is a 16bit value that is the relative distance
// between the two sprites
NvSpriteRawGetRelDistReg:
nv_sprite_raw_get_rel_dist_reg(nv_g16)
rts
/*
DebugRelDist:
// closest
nv_debug_print_labeled_word_mem_coll(6, 0, closest_label_str, 12, nv_a16, true, false)
// temp
nv_debug_print_labeled_word_mem_coll(7, 0, temp_label_str, 12, nv_g16, true, false)
//nv_key_wait_any_key()
rts
closest_label_str: .text @"closest\$00"
temp_label_str: .text @"temp\$00"
*/
//////////////////////////////////////////////////////////////////////////////
// some data for the code in this file.
// Debugging labels for collision code
collision_bit_label1: .text @"nv a8 inside 1: \$00"
collision_bit_label2: .text @"nv a8 inside 2: \$00"
spt_0_dist_label: .text @"sprite0 dist: \$00"
spt_1_dist_label: .text @"sprite1 dist: \$00"
spt_2_dist_label: .text @"sprite2 dist: \$00"
spt_3_dist_label: .text @"sprite3 dist: \$00"
spt_4_dist_label: .text @"sprite4 dist: \$00"
spt_5_dist_label: .text @"sprite5 dist: \$00"
spt_6_dist_label: .text @"sprite6 dist: \$00"
spt_7_dist_label: .text @"sprite7 dist: \$00"
nv_g16_label: .text @"nv g16: \$00"
// end debugging labels