-
Notifications
You must be signed in to change notification settings - Fork 30
/
game.s
491 lines (429 loc) · 12.6 KB
/
game.s
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
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
@ This file is part of the Team 28 Project
@ Licensing information can be found in the LICENSE file
@ (C) 2014 The Team 28 Authors. All rights reserved.
.global setup_game
.global mtx_proj
.global mtx_model
.global mtx_view
.global mtx_temp
.global mtx_vp
.global mtx_mvp
.global mtx_mp
.global mtx_id
.global player_pos
.global light_dir
.global wrench
.global rocket
.global bullet
.global flare
.global score
.global building_small
.global building_medium
.global building_large
.global mountains
.global tristan
.global monkey
.include "ports.s"
.section .data
@ ------------------------------------------------------------------------------
@ Common assets
@ ------------------------------------------------------------------------------
bullet: .incbin "assets/bullet.bin"
rocket: .incbin "assets/rocket.bin"
wrench: .incbin "assets/wrench.bin"
flare: .incbin "assets/flare.bin"
mountains: .incbin "assets/mountains.bin"
tristan: .incbin "assets/tristan.bin"
monkey: .incbin "assets/monkey.bin"
pixfox: .incbin "assets/pifox.bin"
@ ------------------------------------------------------------------------------
@ Pad ascii to a fixed width
@ ------------------------------------------------------------------------------
.macro death_msg x, string
8:
.long \x
.ascii "\string"
9:
.iflt 64 - (9b - 8b)
.error "String too long"
.endif
.ifgt 64 - (9b - 8b)
.zero 64 - (9b - 8b)
.endif
.endm
@ ------------------------------------------------------------------------------
@ Transformation matrices
@ ------------------------------------------------------------------------------
mtx_proj: .float 1.810660, 0.0, 0.0, 0.0
.float 0.0, 2.4142136, 0.0, 0.0
.float 0.0, 0.0, -1.0040080, -1.0
.float 0.0, 0.0, -2.0040080, 0.0
mtx_model: .float 1.0, 0.0, 0.0, 0.0
.float 0.0, 1.0, 0.0, 0.0
.float 0.0, 0.0, 1.0, 0.0
.float 0.0, 0.0, 0.0, 1.0
mtx_view: .float 1.0, 0.0, 0.0, 0.0
.float 0.0, 1.0, 0.0, 0.0
.float 0.0, 0.0, 1.0, 0.0
.float 0.0, 0.0, 0.0, 1.0
mtx_temp: .space 64, 0
mtx_vp: .space 64, 0
mtx_mvp: .space 64, 0
mtx_mp: .space 64, 0
mtx_id: .float 1.0, 0.0, 0.0, 0.0
.float 0.0, 1.0, 0.0, 0.0
.float 0.0, 0.0, 1.0, 0.0
.float 0.0, 0.0, 0.0, 1.0
@ ------------------------------------------------------------------------------
@ Light direction
@ ------------------------------------------------------------------------------
light_dir: .float 0.3, -0.57, -0.57, 0.0
.section .text
@ ------------------------------------------------------------------------------
@ Enables interrupts & starts the game
@ ------------------------------------------------------------------------------
setup_game:
mov r0, #0xDF
msr cpsr, r0
b start_loop
@ ------------------------------------------------------------------------------
@ Start screen displayed on boot
@ ------------------------------------------------------------------------------
start_loop:
ldr r0, =0xFF441111
bl gfx_clear
@ Draw pifox title card
ldr r0, =pixfox
mov r1, #203
mov r2, #30
bl gfx_draw_image
bl draw_sprites
bl draw_start
bl gfx_swap
bl update_sound
bl update_input
@ Loop until start is pressed
ldr r0, =button_pressed
ldr r0, [r0]
tst r0, #0x08
beq start_loop
b game_loop
@ ------------------------------------------------------------------------------
@ Death screen
@ ------------------------------------------------------------------------------
death_loop:
@ Clear sounds
bl snd_stop_roll
bl snd_stop_bullet
bl snd_stop_rock
bl snd_stop_crash
bl snd_stop_rocket
bl snd_stop_cantlet
bl snd_stop_pickup
@ Play fail sound
bl snd_play_fail
@ Record high score
ldr r1, =player_score
ldr r1, [r1]
ldr r0, =player_high_score
ldr r0, [r0]
cmp r1, r0
ldrgt r0, =player_high_score
strgt r1, [r0]
@ Generate random death message index
bl random
and r1, r0, #0x3
1:
ldr r0, =0xFF0044ff
bl gfx_clear
bl draw_death
bl draw_sprites
bl draw_start
bl gfx_swap
bl update_sound
bl update_input
@ Loop until start is pressed
ldr r0, =button_pressed
ldr r0, [r0]
tst r0, #0x08
beq 1b
bl snd_stop_fail
bl reset_enemies
bl reset_flares
bl reset_rockets
bl reset_objects
bl reset_bullets
bl reset_player_mov
b game_loop
@-------------------------------------------------------------------------------
@ Pause loop
@-------------------------------------------------------------------------------
pause_loop:
stmfd sp!, {lr}
1:
bl update_input
bl update_sound
@ Loop until select is pressed
ldr r0, =button_clicked
ldr r0, [r0]
tst r0, #0x04
beq 1b
ldmfd sp!, {pc}
@ ------------------------------------------------------------------------------
@ Main game loop
@ ------------------------------------------------------------------------------
game_loop:
bl setup_player
bl setup_enemies
bl snd_play_rock
1:
bl gfx_swap
bl update_input
ldr r0, =button_clicked
ldr r0, [r0]
tst r0, #0x04
blne pause_loop
bl update_player
bl update_sound
bl draw_pillars
bl draw_enemies
bl draw_rocks
bl draw_bullets
bl draw_rockets
bl draw_player
bl draw_fps
bl draw_high_score
ldr r0, =player_health
ldr r0, [r0]
cmp r0, #0
bgt 1b
b death_loop
.section .data
@ ------------------------------------------------------------------------------
@ FPS counter
@ ------------------------------------------------------------------------------
frame_counter:
.long 0
last_frame:
.long 0
fps:
.long 0
.section .text
@ ------------------------------------------------------------------------------
@ Renders the FPS counter on screen
@ ------------------------------------------------------------------------------
draw_fps:
stmfd sp!, {lr}
@ Updates the FPS counter
ldr r0, =last_frame
ldr r1, [r0]
ldr r2, =1000000
add r1, r1, r2 @ Update fps once every second
ldr r2, =STIMER_CLO @ Read system timer
ldr r2, [r2]
ldr r3, =frame_counter @ Increment frame count
ldr r4, [r3]
add r4, r4, #1
str r4, [r3]
cmp r1, r2
bgt 1f @ If 1s passed, update fps
ldr r1, =fps
str r4, [r1]
str r2, [r0]
mov r4, #0
1:
str r4, [r3]
@ Renders the FPS on screen
ldr r0, =1f
mov r1, #15
mov r2, #10
ldr r3, =0xFFFFFFFF
ldr r4, =fps
ldr r4, [r4]
push {r4}
ldr r4, =player_score
ldr r4, [r4]
push {r4}
bl printf
add sp, sp, #8
ldmfd sp!, {pc}
1:
.ascii "Score: %5d\nFPS: %2d"
.byte 0x0
.align 2
@ ------------------------------------------------------------------------------
@ Renders the high score for this session
@ ------------------------------------------------------------------------------
draw_high_score:
stmfd sp!, {lr}
ldr r0, =1f
mov r1, #512
sub r1, r1, #23
mov r2, #10
ldr r3, =0xFFFFFFFF
ldr r4, =player_high_score
ldr r4, [r4]
push {r4}
bl printf
add sp, sp, #4
ldmfd sp!, {pc}
1:
.ascii "High Score: %5d\n"
.byte 0x0
.align 2
@ ------------------------------------------------------------------------------
@ Renders the welcome message
@ ------------------------------------------------------------------------------
draw_start:
stmfd sp!, {r0 - r3, lr}
ldr r0, =1f
mov r1, #240
mov r2, #400
ldr r3, =0xFFFFFFFF
bl printf
ldmfd sp!, {r0 - r3, pc}
1:
.ascii "Press START to begin"
.byte 0x0
.align 2
@ ------------------------------------------------------------------------------
@ Prints the death message
@ Arguments:
@ r0 - Random number between 0 and number of strings
@ Returns:
@ Nothing
@ ------------------------------------------------------------------------------
draw_death:
stmfd sp!, {r0 - r4, lr}
@ Draw death message text
ldr r0, =2f
add r0, r0, r1, lsl #6
ldr r1, [r0], #4
mov r2, #170
ldr r3, =0xFFFFFFFF
bl printf
@ Draw score
ldr r0, =1f
mov r1, #272
mov r2, #300
ldr r3, =0xFFFFFFFF
ldr r4, =player_score
ldr r4, [r4]
push {r4}
bl printf
add sp, sp, #4
ldmfd sp!, {r0 - r4, pc}
1:
.ascii "Score: %5d\0"
.align 2
2:
death_msg 200, "You have died, what a tragedy!\0"
death_msg 172, "You have died, better luck next time!\0"
death_msg 124, "You have died, maybe you should go back to Mario?\0"
death_msg 184, "You have died, give it another go?\0"
.section .text
@ ------------------------------------------------------------------------------
@ Prints rotating sprites
@ Arguments:
@ none
@ Returns:
@ none
@ Clobbers:
@ s0 - s31
@ ------------------------------------------------------------------------------
draw_sprites:
stmfd sp!, {r0 - r4, lr}
@ Clear model matrix
ldr r0, =mtx_id
vldm.f32 r0, {s0 - s15}
ldr r0, =mtx_model
vstm.f32 r0, {s0 - s15}
ldr r0, =mtx_temp
vstm.f32 r0, {s0 - s15}
@ Compute the proj - view matrix
ldr r0, =0
vmov.f32 s0, r0
ldr r0, =0
vmov.f32 s1, r0
ldr r0, =0xc0e00000
vmov.f32 s2, r0
ldr r0, =mtx_view
bl mat4_translate
ldr r0, =mtx_proj
ldr r1, =mtx_view
ldr r2, =mtx_vp
bl mat4_mul_mat4
@ Prepare the model matrix
ldr r0, =0x3f800000 @ 1.0
vmov.f32 s0, r0
ldr r0, =0
vmov.f32 s1, r0
ldr r0, =0
vmov.f32 s2, r0
ldr r0, =mtx_model
bl mat4_translate
@ Update rotation around y
ldr r0, =1f
vldr.f32 s0, [r0]
ldr r1, =0x3d000000 @ 0.03125
vmov.f32 s1, r1
vadd.f32 s0, s1
vstr.f32 s0, [r0]
ldr r0, =mtx_temp
bl mat4_rot_y
ldr r0, =mtx_temp
ldr r1, =mtx_model
ldr r2, =mtx_model
bl mat4_mul_mat4
@ Rotate around y by 120 degrees
ldr r0, =0x40060a92 @ 2 * PI / 3
vmov.f32 s0, r0
ldr r0, =mtx_temp
bl mat4_rot_y
@ Draw a bullet
ldr r0, =mtx_vp
ldr r1, =mtx_model
ldr r2, =mtx_mvp
bl mat4_mul_mat4
ldr r0, =bullet
ldr r1, =mtx_mvp
ldr r2, =mtx_model @ don't ask me why
ldr r3, =0x3e800000
vmov.f32 s0, r3
vmov.f32 s1, r3
bl gfx_draw_sprite
@ Draw a rocket
ldr r0, =mtx_temp
ldr r1, =mtx_model
ldr r2, =mtx_model
bl mat4_mul_mat4
ldr r0, =mtx_vp
ldr r1, =mtx_model
ldr r2, =mtx_mvp
bl mat4_mul_mat4
ldr r0, =rocket
ldr r1, =mtx_mvp
ldr r2, =mtx_model
ldr r3, =0x3e800000
vmov.f32 s0, r3
vmov.f32 s1, r3
bl gfx_draw_sprite
@ Draw a wrench
ldr r0, =mtx_temp
ldr r1, =mtx_model
ldr r2, =mtx_model
bl mat4_mul_mat4
ldr r0, =mtx_vp
ldr r1, =mtx_model
ldr r2, =mtx_mvp
bl mat4_mul_mat4
ldr r0, =wrench
ldr r1, =mtx_mvp
ldr r2, =mtx_model
ldr r3, =0x3e800000
vmov.f32 s0, r3
vmov.f32 s1, r3
bl gfx_draw_sprite
ldmfd sp!, {r0 - r4, pc}
1:
.float 0.0