-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbullets.asm
282 lines (210 loc) · 4.91 KB
/
bullets.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
# MAV120
# Mathew Varughese
.eqv PLAYER_BULLET_COUNT 10
# The time in frames between shots
.eqv PLAYER_SHOT_WAIT_TIME 10 # in frames
# The number of pixels the bullet moves a frame
.eqv BULLET_MOVEMENT_SPEED 1
.eqv ENEMY_BULLET_COUNT 5
# .eqv ENEMY_SHOT_WAIT_TIME 90
.eqv ENEMY_COUNT 20
.eqv ENEMY_PER_ROW 5
.eqv ENEMY_PER_COL 4
.eqv ENEMY_COL_SPACING 10
.eqv ENEMY_ROW_SPACING 7
.data
bullet_x: .byte 0:PLAYER_BULLET_COUNT
bullet_y: .byte 0:PLAYER_BULLET_COUNT
bullet_active: .byte 0:PLAYER_BULLET_COUNT
enemy_last_shot: .word 0
enemy_bullet_active: .byte 0:ENEMY_BULLET_COUNT
enemy_bullet_x: .byte 0:ENEMY_BULLET_COUNT
enemy_bullet_y: .byte 0:ENEMY_BULLET_COUNT
ENEMY_SHOT_WAIT_TIME: .word 90
.text
####### ENEMY BULLETS
check_if_enemy_firing:
enter
# t0 = frames since last enemy shot
lw t0, enemy_last_shot
lw t1, frame_counter
sub t0 t1 t0
lw t9 ENEMY_SHOT_WAIT_TIME
# shoot if frame is below
blt t0, t9, _finish_check_if_enemy_firing
sw t1, enemy_last_shot
jal fire_enemy_bullet
_finish_check_if_enemy_firing:
leave
fire_enemy_bullet:
enter s0
la a0 enemy_bullet_active
li a1 ENEMY_BULLET_COUNT
jal find_active_bullet
move s0 v0
bge s0 ENEMY_BULLET_COUNT _end_fire_e_bullet
lw t0 enemy_kill_count
li t1 ENEMY_COUNT
sub t0 t1 t0
ble t0 0 _end_fire_e_bullet
jal get_rand_alive_enemy
lw t0 enemy_x
lw t1 enemy_y
# v0 = row_index
# v1 = col_index
# t5 = x = enemy_x + ENEMY_COL_SPACING * col_index
# t6 = y = enemy_y + ENEMY_ROW_SPACING * row_index
mul t5 v1, ENEMY_COL_SPACING
mul t6 v0 ENEMY_ROW_SPACING
add t0 t0 t5
add t1 t1 t6
add t0 t0 2
add t1 t1 5
sb t0 enemy_bullet_x(s0)
sb t1 enemy_bullet_y(s0)
li t0 1
sb t0, enemy_bullet_active(s0)
_end_fire_e_bullet:
leave s0
get_rand_alive_enemy:
enter s0, s1
# returns random alive enemy row and col
# enemy_index = ENEMY_PER_COL*col + row
_get_rand_alive_enemy_loop_top:
# s0 = rand row [0,4] = col index
li v0 sys_randRange
li a1 ENEMY_PER_ROW
syscall
move s0 a0
# s1 = rand col [0,3] = row index
li v0 sys_randRange
li a1 ENEMY_PER_COL
syscall
move s1 a0
mul t0 s0 ENEMY_PER_COL
add t0 t0 s1
lbu t7 enemy_active(t0)
bne t7 1 _get_rand_alive_enemy_loop_top
_get_rand_alive_enemy_loop_finish:
move v0 s1
move v1 s0
leave s0, s1
##########
####### PLAYER BULLETS
check_if_firing:
enter
jal input_get_keys
and t0, v0, KEY_B # t0 = keys & KEY_B
bne t0, KEY_B, _finish_check_if_firing
# They clicked the B key:
# t0 = frames since last fire
lw t0, player_bullet_last_fired
lw t1, frame_counter
sub t0 t1 t0
# attempt to fire bullet if frames since last fire is more than PLAYER_SHOT_WAIT_TIME
blt t0, PLAYER_SHOT_WAIT_TIME, _finish_check_if_firing
sw t1, player_bullet_last_fired
jal fire_player_bullet
_finish_check_if_firing:
leave
fire_player_bullet:
enter s0
la a0 bullet_active
li a1 PLAYER_BULLET_COUNT
jal find_active_bullet
move s0 v0
bge s0 PLAYER_BULLET_COUNT _end_firebullet
lw t0 player_x
lw t1 player_y
la t2 bullet_x
add t2, t2, s0
add t0, t0, 2 # to make it shoot from the center
sb t0, (t2)
la t2 bullet_y
add t2, t2, s0
sb t1, (t2)
li t0 1
la t1 bullet_active
add t1, t1, s0
sb t0 (t1)
# Decrement bullets left and game over if none left
lw t1 player_bullets_left
dec t1
sw t1 player_bullets_left
bgt t1, 0, _end_firebullet
jal game_over
_end_firebullet:
leave s0
find_active_bullet:
enter
# a0 : address of bullet array
# a1 : bullet array length
li t0 0
_main_loop_findactivebullet:
bgt t0, a1 _end_findactivebullet
_loop_findactivebullet:
# bullet_active [i]
move t1, a0
add t1, t1, t0
lbu t2, (t1)
beq t2, 0, _end_findactivebullet
inc t0
b _main_loop_findactivebullet
_end_findactivebullet:
move v0, t0
leave
move_enemy_bullets:
enter s0
li s0 0
_main_loop_move_e_bullets:
bge s0, ENEMY_BULLET_COUNT _end_move_e_bullets
_loop_move_e_bullets:
lb t0 enemy_bullet_active(s0)
bne t0 0, _move_bullet_down
inc s0
b _main_loop_move_e_bullets
_move_bullet_down:
lbu t1 enemy_bullet_y(s0)
add t1 t1 BULLET_MOVEMENT_SPEED
bge t1 64 _delete_e_bullet
sb t1 enemy_bullet_y(s0)
lbu a0 enemy_bullet_x(s0)
move a1 t1
move a2 s0
jal check_if_enemy_bullet_hit_player
b _do_not_delete_e_bullet
_delete_e_bullet:
sb zero enemy_bullet_active(s0)
_do_not_delete_e_bullet:
inc s0
b _main_loop_move_e_bullets
_end_move_e_bullets:
leave s0
move_player_bullets:
enter s0
li s0 0
_main_loop_movebullets:
bge s0, PLAYER_BULLET_COUNT _end_movebullets
_loop_movebullets:
lb t0 bullet_active(s0)
bne t0 0, _move_bullet_up
inc s0
b _main_loop_movebullets
_move_bullet_up:
lbu t1 bullet_y(s0)
sub t1 t1 BULLET_MOVEMENT_SPEED
blt t1 0 _delete_bullet
sb t1 bullet_y(s0)
lbu a0 bullet_x(s0)
move a1 t1
move a3 s0
jal check_if_bullet_hit_enemy
b _do_not_delete_bullet
_delete_bullet:
sb zero bullet_active(s0)
_do_not_delete_bullet:
inc s0
b _main_loop_movebullets
_end_movebullets:
leave s0
####### END BULLETS