forked from Misto423/Assembly-Snake
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSnakeFinished.asm
More file actions
1000 lines (885 loc) · 27.4 KB
/
Copy pathSnakeFinished.asm
File metadata and controls
1000 lines (885 loc) · 27.4 KB
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
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
######################################################################
# SNAKE!!!! #
######################################################################
# Programmed by Shane Shafferman and Eric Deas #
######################################################################
# This program requires the Keyboard and Display MMIO #
# and the Bitmap Display to be connected to MIPS. #
# #
# Bitmap Display Settings: #
# Unit Width: 8 #
# Unit Height: 8 #
# Display Width: 512 #
# Display Height: 512 #
# Base Address for Display: 0x10008000 ($gp) #
######################################################################
.data
#Game Core information
#Screen
screenWidth: .word 64
screenHeight: .word 64
#Colors
snakeColor: .word 0x0066cc # blue
backgroundColor:.word 0x000000 # black
borderColor: .word 0x00ff00 # green
fruitColor: .word 0xcc6611 # orange
#score variable
score: .word 0
#stores how many points are recieved for eating a fruit
#increases as program gets harder
scoreGain: .word 10
#speed the snake moves at, increases as game progresses
gameSpeed: .word 200
#array to store the scores in which difficulty should increase
scoreMilestones: .word 100, 250, 500, 1000, 5000, 10000
scoreArrayPosition: .word 0
#end game message
lostMessage: .asciiz "You have died.... Your score was: "
replayMessage: .asciiz "Would you like to replay?"
#Snake Information
snakeHeadX: .word 31
snakeHeadY: .word 31
snakeTailX: .word 31
snakeTailY: .word 37
direction: .word 119 #initially moving up
tailDirection: .word 119
# direction variable
# 119 - moving up - W
# 115 - moving down - S
# 97 - moving left - A
# 100 - moving right - D
# numbers are selected due to ASCII characters
#this array stores the screen coordinates of a direction change
#once the tail hits a position in this array, its direction is changed
#this is used to have the tail follow the head correctly
directionChangeAddressArray: .word 0:100
#this stores the new direction for the tail to move once it hits
#an address in the above array
newDirectionChangeArray: .word 0:100
#stores the position of the end of the array (multiple of 4)
arrayPosition: .word 0
locationInArray: .word 0
#Fruit Information
fruitPositionX: .word
fruitPositionY: .word
.text
main:
######################################################
# Fill Screen to Black, for reset
######################################################
lw $a0, screenWidth
lw $a1, backgroundColor
mul $a2, $a0, $a0 #total number of pixels on screen
mul $a2, $a2, 4 #align addresses
add $a2, $a2, $gp #add base of gp
add $a0, $gp, $zero #loop counter
FillLoop:
beq $a0, $a2, Init
sw $a1, 0($a0) #store color
addiu $a0, $a0, 4 #increment counter
j FillLoop
######################################################
# Initialize Variables
######################################################
Init:
li $t0, 31
sw $t0, snakeHeadX
sw $t0, snakeHeadY
sw $t0, snakeTailX
li $t0, 37
sw $t0, snakeTailY
li $t0, 119
sw $t0, direction
sw $t0, tailDirection
li $t0, 10
sw $t0, scoreGain
li $t0, 200
sw $t0, gameSpeed
sw $zero, arrayPosition
sw $zero, locationInArray
sw $zero, scoreArrayPosition
sw $zero, score
ClearRegisters:
li $v0, 0
li $a0, 0
li $a1, 0
li $a2, 0
li $a3, 0
li $t0, 0
li $t1, 0
li $t2, 0
li $t3, 0
li $t4, 0
li $t5, 0
li $t6, 0
li $t7, 0
li $t8, 0
li $t9, 0
li $s0, 0
li $s1, 0
li $s2, 0
li $s3, 0
li $s4, 0
######################################################
# Draw Border
######################################################
DrawBorder:
li $t1, 0 #load Y coordinate for the left border
LeftLoop:
move $a1, $t1 #move y coordinate into $a1
li $a0, 0 # load x direction to 0, doesnt change
jal CoordinateToAddress #get screen coordinates
move $a0, $v0 # move screen coordinates into $a0
lw $a1, borderColor #move color code into $a1
jal DrawPixel #draw the color at the screen location
add $t1, $t1, 1 #increment y coordinate
bne $t1, 64, LeftLoop #loop through to draw entire left border
li $t1, 0 #load Y coordinate for right border
RightLoop:
move $a1, $t1 #move y coordinate into $a1
li $a0, 63 #set x coordinate to 63 (right side of screen)
jal CoordinateToAddress #convert to screen coordinates
move $a0, $v0 # move coordinates into $a0
lw $a1, borderColor #move color data into $a1
jal DrawPixel #draw color at screen coordinates
add $t1, $t1, 1 #increment y coordinate
bne $t1, 64, RightLoop #loop through to draw entire right border
li $t1, 0 #load X coordinate for top border
TopLoop:
move $a0, $t1 # move x coordinate into $a0
li $a1, 0 # set y coordinate to zero for top of screen
jal CoordinateToAddress #get screen coordinate
move $a0, $v0 # move screen coordinates to $a0
lw $a1, borderColor # store color data to $a1
jal DrawPixel #draw color at screen coordinates
add $t1, $t1, 1 #increment X position
bne $t1, 64, TopLoop #loop through to draw entire top border
li $t1, 0 #load X coordinate for bottom border
BottomLoop:
move $a0, $t1 # move x coordinate to $a0
li $a1, 63 # load Y coordinate for bottom of screen
jal CoordinateToAddress #get screen coordinates
move $a0, $v0 #move screen coordinates to $a0
lw $a1, borderColor #put color data into $a1
jal DrawPixel #draw color at screen position
add $t1, $t1, 1 #increment X coordinate
bne $t1, 64, BottomLoop # loop through to draw entire bottom border
######################################################
# Draw Initial Snake Position
######################################################
#draw snake head
lw $a0, snakeHeadX #load x coordinate
lw $a1, snakeHeadY #load y coordinate
jal CoordinateToAddress #get screen coordinates
move $a0, $v0 #copy coordinates to $a0
lw $a1, snakeColor #store color into $a1
jal DrawPixel #draw color at pixel
#draw middle portion
lw $a0, snakeHeadX #load x coordinate
lw $a1, snakeHeadY #load y coordinate
add $a1, $a1, 1
jal CoordinateToAddress #get screen coordinates
move $a0, $v0 #copy coordinates to $a0
lw $a1, snakeColor #store color into $a1
jal DrawPixel #draw color at pixel
#TEST 8 PIXELS
lw $a0, snakeHeadX #load x coordinate
lw $a1, snakeHeadY #load y coordinate
add $a1, $a1, 2
jal CoordinateToAddress #get screen coordinates
move $a0, $v0 #copy coordinates to $a0
lw $a1, snakeColor #store color into $a1
jal DrawPixel #draw color at pixel
lw $a0, snakeHeadX #load x coordinate
lw $a1, snakeHeadY #load y coordinate
add $a1, $a1, 3
jal CoordinateToAddress #get screen coordinates
move $a0, $v0 #copy coordinates to $a0
lw $a1, snakeColor #store color into $a1
jal DrawPixel #draw color at pixel
lw $a0, snakeHeadX #load x coordinate
lw $a1, snakeHeadY #load y coordinate
add $a1, $a1, 4
jal CoordinateToAddress #get screen coordinates
move $a0, $v0 #copy coordinates to $a0
lw $a1, snakeColor #store color into $a1
jal DrawPixel #draw color at pixel
lw $a0, snakeHeadX #load x coordinate
lw $a1, snakeHeadY #load y coordinate
add $a1, $a1, 5
jal CoordinateToAddress #get screen coordinates
move $a0, $v0 #copy coordinates to $a0
lw $a1, snakeColor #store color into $a1
jal DrawPixel #draw color at pixel
lw $a0, snakeHeadX #load x coordinate
lw $a1, snakeHeadY #load y coordinate
add $a1, $a1, 6
jal CoordinateToAddress #get screen coordinates
move $a0, $v0 #copy coordinates to $a0
lw $a1, snakeColor #store color into $a1
jal DrawPixel #draw color at pixel
#draw snake tail
lw $a0, snakeTailX #load x coordinate
lw $a1, snakeTailY #load y coordinate
jal CoordinateToAddress #get screen coordinates
move $a0, $v0 #copy coordinates to $a0
lw $a1, snakeColor #store color into $a1
jal DrawPixel #draw color at pixel
######################################################
# Spawn Fruit
######################################################
SpawnFruit:
#syscall for random int with a upper bound
li $v0, 42
#upper bound 61 (0 <= $a0 < $a1)
li $a1, 62
syscall
#increment the X position so it doesnt draw on a border
addiu $a0, $a0, 1
#store X position
sw $a0, fruitPositionX
syscall
#increment the Y position so it doesnt draw on a border
addiu $a0, $a0, 1
#store Y position
sw $a0, fruitPositionY
jal IncreaseDifficulty
######################################################
# Check for Direction Change
######################################################
InputCheck:
lw $a0, gameSpeed
jal Pause
#get the coordinates for direction change if needed
lw $a0, snakeHeadX
lw $a1, snakeHeadY
jal CoordinateToAddress
add $a2, $v0, $zero
#get the input from the keyboard
li $t0, 0xffff0000
lw $t1, ($t0)
andi $t1, $t1, 0x0001
beqz $t1, SelectDrawDirection #if no new input, draw in same direction
lw $a1, 4($t0) #store direction based on input
DirectionCheck:
lw $a0, direction # load current direction into #a0
jal CheckDirection #check to see if the direction is valid
beqz $v0, InputCheck #if input is not valid, get new input
sw $a1, direction #store the new direction if valid
lw $t7, direction #store the direction into $t7
######################################################
# Update Snake Head position
######################################################
SelectDrawDirection:
#check to see which direction to draw
beq $t7, 119, DrawUpLoop
beq $t7, 115, DrawDownLoop
beq $t7, 97, DrawLeftLoop
beq $t7, 100, DrawRightLoop
#jump back to get input if an unsupported key was pressed
j InputCheck
DrawUpLoop:
#check for collision before moving to next pixel
lw $a0, snakeHeadX
lw $a1, snakeHeadY
lw $a2, direction
jal CheckGameEndingCollision
#draw head in new position, move Y position up
lw $t0, snakeHeadX
lw $t1, snakeHeadY
addiu $t1, $t1, -1
add $a0, $t0, $zero
add $a1, $t1, $zero
jal CoordinateToAddress
add $a0, $v0, $zero
lw $a1, snakeColor
jal DrawPixel
sw $t1, snakeHeadY
j UpdateTailPosition #head updated, update tail
DrawDownLoop:
#check for collision before moving to next pixel
lw $a0, snakeHeadX
lw $a1, snakeHeadY
lw $a2, direction
jal CheckGameEndingCollision
#draw head in new position, move Y position down
lw $t0, snakeHeadX
lw $t1, snakeHeadY
addiu $t1, $t1, 1
add $a0, $t0, $zero
add $a1, $t1, $zero
jal CoordinateToAddress
add $a0, $v0, $zero
lw $a1, snakeColor
jal DrawPixel
sw $t1, snakeHeadY
j UpdateTailPosition #head updated, update tail
DrawLeftLoop:
#check for collision before moving to next pixel
lw $a0, snakeHeadX
lw $a1, snakeHeadY
lw $a2, direction
jal CheckGameEndingCollision
#draw head in new position, move X position left
lw $t0, snakeHeadX
lw $t1, snakeHeadY
addiu $t0, $t0, -1
add $a0, $t0, $zero
add $a1, $t1, $zero
jal CoordinateToAddress
add $a0, $v0, $zero
lw $a1, snakeColor
jal DrawPixel
sw $t0, snakeHeadX
j UpdateTailPosition #head updated, update tail
DrawRightLoop:
#check for collision before moving to next pixel
lw $a0, snakeHeadX
lw $a1, snakeHeadY
lw $a2, direction
jal CheckGameEndingCollision
#draw head in new position, move X position right
lw $t0, snakeHeadX
lw $t1, snakeHeadY
addiu $t0, $t0, 1
add $a0, $t0, $zero
add $a1, $t1, $zero
jal CoordinateToAddress
add $a0, $v0, $zero
lw $a1, snakeColor
jal DrawPixel
sw $t0, snakeHeadX
j UpdateTailPosition #head updated, update tail
######################################################
# Update Snake Tail Position
######################################################
UpdateTailPosition:
lw $t2, tailDirection
#branch based on which direction tail is moving
beq $t2, 119, MoveTailUp
beq $t2, 115, MoveTailDown
beq $t2, 97, MoveTailLeft
beq $t2, 100, MoveTailRight
MoveTailUp:
#get the screen coordinates of the next direction change
lw $t8, locationInArray
la $t0, directionChangeAddressArray #get direction change coordinate
add $t0, $t0, $t8
lw $t9, 0($t0)
lw $a0, snakeTailX #get snake tail position
lw $a1, snakeTailY
#if the index is out of bounds, set back to zero
beq $s1, 1, IncreaseLengthUp #branch if length should be increased
addiu $a1, $a1, -1 #change tail position if no length change
sw $a1, snakeTailY
IncreaseLengthUp:
li $s1, 0 #set flag back to false
jal CoordinateToAddress
add $a0, $v0, $zero
bne $t9, $a0, DrawTailUp #change direction if needed
la $t3, newDirectionChangeArray #update direction
add $t3, $t3, $t8
lw $t9, 0($t3)
sw $t9, tailDirection
addiu $t8,$t8,4
#if the index is out of bounds, set back to zero
bne $t8, 396, StoreLocationUp
li $t8, 0
StoreLocationUp:
sw $t8, locationInArray
DrawTailUp:
lw $a1, snakeColor
jal DrawPixel
#erase behind the snake
lw $t0, snakeTailX
lw $t1, snakeTailY
addiu $t1, $t1, 1
add $a0, $t0, $zero
add $a1, $t1, $zero
jal CoordinateToAddress
add $a0, $v0, $zero
lw $a1, backgroundColor
jal DrawPixel
j DrawFruit #finished updating snake, update fruit
MoveTailDown:
#get the screen coordinates of the next direction change
lw $t8, locationInArray
la $t0, directionChangeAddressArray #get direction change coordinate
add $t0, $t0, $t8
lw $t9, 0($t0)
lw $a0, snakeTailX #get snake tail position
lw $a1, snakeTailY
beq $s1, 1, IncreaseLengthDown #branch if length should be increased
addiu $a1, $a1, 1 #change tail position if no length change
sw $a1, snakeTailY
IncreaseLengthDown:
li $s1, 0 #set flag back to false
jal CoordinateToAddress
add $a0, $v0, $zero
bne $t9, $a0, DrawTailDown #change direction if needed
la $t3, newDirectionChangeArray #update direction
add $t3, $t3, $t8
lw $t9, 0($t3)
sw $t9, tailDirection
addiu $t8,$t8,4
#if the index is out of bounds, set back to zero
bne $t8, 396, StoreLocationDown
li $t8, 0
StoreLocationDown:
sw $t8, locationInArray
DrawTailDown:
lw $a1, snakeColor
jal DrawPixel
#erase behind the snake
lw $t0, snakeTailX
lw $t1, snakeTailY
addiu $t1, $t1, -1
add $a0, $t0, $zero
add $a1, $t1, $zero
jal CoordinateToAddress
add $a0, $v0, $zero
lw $a1, backgroundColor
jal DrawPixel
j DrawFruit #finished updating snake, update fruit
MoveTailLeft:
#update the tail position when moving left
lw $t8, locationInArray
la $t0, directionChangeAddressArray #get direction change coordinate
add $t0, $t0, $t8
lw $t9, 0($t0)
lw $a0, snakeTailX #get snake tail position
lw $a1, snakeTailY
beq $s1, 1, IncreaseLengthLeft #branch if length should be increased
addiu $a0, $a0, -1 #change tail position if no length change
sw $a0, snakeTailX
IncreaseLengthLeft:
li $s1, 0 #set flag back to false
jal CoordinateToAddress
add $a0, $v0, $zero
bne $t9, $a0, DrawTailLeft #change direction if needed
la $t3, newDirectionChangeArray #update direction
add $t3, $t3, $t8
lw $t9, 0($t3)
sw $t9, tailDirection
addiu $t8,$t8,4
#if the index is out of bounds, set back to zero
bne $t8, 396, StoreLocationLeft
li $t8, 0
StoreLocationLeft:
sw $t8, locationInArray
DrawTailLeft:
lw $a1, snakeColor
jal DrawPixel
#erase behind the snake
lw $t0, snakeTailX
lw $t1, snakeTailY
addiu $t0, $t0, 1
add $a0, $t0, $zero
add $a1, $t1, $zero
jal CoordinateToAddress
add $a0, $v0, $zero
lw $a1, backgroundColor
jal DrawPixel
j DrawFruit #finished updating snake, update fruit
MoveTailRight:
#get the screen coordinates of the next direction change
lw $t8, locationInArray
#get the base address of the coordinate array
la $t0, directionChangeAddressArray
#go to the correct index of array
add $t0, $t0, $t8
#get the data from the array
lw $t9, 0($t0)
#get current tail position
lw $a0, snakeTailX
lw $a1, snakeTailY
#if the length needs to be increased
#do not change coordinates
beq $s1, 1, IncreaseLengthRight
#change tail position
addiu $a0, $a0, 1
#store new tail position
sw $a0, snakeTailX
IncreaseLengthRight:
li $s1, 0 #set flag back to false
#get screen coordinates
jal CoordinateToAddress
#store coordinates in $a0
add $a0, $v0, $zero
#if the coordinates is a position change
#continue drawing tail in same direction
bne $t9, $a0, DrawTailRight
#get the base address of the direction change array
la $t3, newDirectionChangeArray
#move to correct index in array
add $t3, $t3, $t8
#get data from array
lw $t9, 0($t3)
#store new direction
sw $t9, tailDirection
#increment position in array
addiu $t8,$t8,4
#if the index is out of bounds, set back to zero
bne $t8, 396, StoreLocationRight
li $t8, 0
StoreLocationRight:
sw $t8, locationInArray
DrawTailRight:
lw $a1, snakeColor
jal DrawPixel
#erase behind the snake
lw $t0, snakeTailX
lw $t1, snakeTailY
addiu $t0, $t0, -1
add $a0, $t0, $zero
add $a1, $t1, $zero
jal CoordinateToAddress
add $a0, $v0, $zero
lw $a1, backgroundColor
jal DrawPixel
j DrawFruit #finished updating snake, update fruit
######################################################
# Draw Fruit
######################################################
DrawFruit:
#check collision with fruit
lw $a0, snakeHeadX
lw $a1, snakeHeadY
jal CheckFruitCollision
beq $v0, 1, AddLength #if fruit was eaten, add length
#draw the fruit
lw $a0, fruitPositionX
lw $a1, fruitPositionY
jal CoordinateToAddress
add $a0, $v0, $zero
lw $a1, fruitColor
jal DrawPixel
j InputCheck
AddLength:
li $s1, 1 #flag to increase snake length
j SpawnFruit
j InputCheck #shouldn't need, but there in case of errors
##################################################################
#CoordinatesToAddress Function
# $a0 -> x coordinate
# $a1 -> y coordinate
##################################################################
# returns $v0 -> the address of the coordinates for bitmap display
##################################################################
CoordinateToAddress:
lw $v0, screenWidth #Store screen width into $v0
mul $v0, $v0, $a1 #multiply by y position
add $v0, $v0, $a0 #add the x position
mul $v0, $v0, 4 #multiply by 4
add $v0, $v0, $gp #add global pointerfrom bitmap display
jr $ra # return $v0
##################################################################
#Draw Function
# $a0 -> Address position to draw at
# $a1 -> Color the pixel should be drawn
##################################################################
# no return value
##################################################################
DrawPixel:
sw $a1, ($a0) #fill the coordinate with specified color
jr $ra #return
##################################################################
# Check Acceptable Direction
# $a0 - current direction
# $a1 - input
# $a2 - coordinates of direction change if acceptable
##################################################################
# return $v0 = 0 - direction unacceptable
# $v0 = 1 - direction is acceptable
##################################################################
CheckDirection:
beq $a0, $a1, Same #if the input is the same as current direction
#continue moving in the direction
beq $a0, 119, checkIsDownPressed #if moving up, check to see if down is pressed
beq $a0, 115, checkIsUpPressed #if moving down, check to see if up is pressed
beq $a0, 97, checkIsRightPressed #if moving left, check to see if right is pressed
beq $a0, 100, checkIsLeftPressed #if moving right, check to see if left is pressed
j DirectionCheckFinished # if input is incorrect, get new input
checkIsDownPressed:
beq $a1, 115, unacceptable #if down is pressed while moving up
#prevent snake from moving into itself
j acceptable
checkIsUpPressed:
beq $a1, 119, unacceptable #if up is pressed while moving down
#prevent snake from moving into itself
j acceptable
checkIsRightPressed:
beq $a1, 100, unacceptable #if right is pressed while moving left
#prevent snake from moving into itself
j acceptable
checkIsLeftPressed:
beq $a1, 97, unacceptable #if left is pressed while moving right
#prevent snake from moving into itself
j acceptable
acceptable:
li $v0, 1
beq $a1, 119, storeUpDirection #store the location of up direction change
beq $a1, 115, storeDownDirection #store the location of down direction change
beq $a1, 97, storeLeftDirection #store the location of left direction change
beq $a1, 100, storeRightDirection #store the location of right direction change
j DirectionCheckFinished
storeUpDirection:
lw $t4, arrayPosition #get the array index
la $t2, directionChangeAddressArray #get the address for the coordinate for direction change
la $t3, newDirectionChangeArray #get address for new direction
add $t2, $t2, $t4 #add the index to the base
add $t3, $t3, $t4
sw $a2, 0($t2) #store the coordinates in that index
li $t5, 119
sw $t5, 0($t3) #store the direction in that index
addiu $t4, $t4, 4 #increment the array index
#if the array will go out of bounds, start it back at 0
bne $t4, 396, UpStop
li $t4, 0
UpStop:
sw $t4, arrayPosition
j DirectionCheckFinished
storeDownDirection:
lw $t4, arrayPosition #get the array index
la $t2, directionChangeAddressArray #get the address for the coordinate for direction change
la $t3, newDirectionChangeArray #get address for new direction
add $t2, $t2, $t4 #add the index to the base
add $t3, $t3, $t4
sw $a2, 0($t2) #store the coordinates in that index
li $t5, 115
sw $t5, 0($t3) #store the direction in that index
addiu $t4, $t4, 4 #increment the array index
#if the array will go out of bounds, start it back at 0
bne $t4, 396, DownStop
li $t4, 0
DownStop:
sw $t4, arrayPosition
j DirectionCheckFinished
storeLeftDirection:
lw $t4, arrayPosition #get the array index
la $t2, directionChangeAddressArray #get the address for the coordinate for direction change
la $t3, newDirectionChangeArray #get address for new direction
add $t2, $t2, $t4 #add the index to the base
add $t3, $t3, $t4
sw $a2, 0($t2) #store the coordinates in that index
li $t5, 97
sw $t5, 0($t3) #store the direction in that index
addiu $t4, $t4, 4 #increment the array index
#if the array will go out of bounds, start it back at 0
bne $t4, 396, LeftStop
li $t4, 0
LeftStop:
sw $t4, arrayPosition
j DirectionCheckFinished
storeRightDirection:
lw $t4, arrayPosition #get the array index
la $t2, directionChangeAddressArray #get the address for the coordinate for direction change
la $t3, newDirectionChangeArray #get address for new direction
add $t2, $t2, $t4 #add the index to the base
add $t3, $t3, $t4
sw $a2, 0($t2) #store the coordinates in that index
li $t5, 100
sw $t5, 0($t3) #store the direction in that index
addiu $t4, $t4, 4 #increment the array index
#if the array will go out of bounds, start it back at 0
bne $t4, 396, RightStop
li $t4, 0
RightStop:
#store array position
sw $t4, arrayPosition
j DirectionCheckFinished
unacceptable:
li $v0, 0 #direction is not acceptable
j DirectionCheckFinished
Same:
li $v0, 1
DirectionCheckFinished:
jr $ra
##################################################################
# Pause Function
# $a0 - amount to pause
##################################################################
# no return values
##################################################################
Pause:
li $v0, 32 #syscall value for sleep
syscall
jr $ra
##################################################################
# Check Fruit Collision
# $a0 - snakeHeadPositionX
# $a1 - snakeHeadPositionY
##################################################################
# returns $v0:
# 0 - does not hit fruit
# 1 - does hit fruit
##################################################################
CheckFruitCollision:
#get fruit coordinates
lw $t0, fruitPositionX
lw $t1, fruitPositionY
#set $v0 to zero, to default to no collision
add $v0, $zero, $zero
#check first to see if x is equal
beq $a0, $t0, XEqualFruit
#if not equal end function
j ExitCollisionCheck
XEqualFruit:
#check to see if the y is equal
beq $a1, $t1, YEqualFruit
#if not eqaul end function
j ExitCollisionCheck
YEqualFruit:
#update the score as fruit has been eaten
lw $t5, score
lw $t6, scoreGain
add $t5, $t5, $t6
sw $t5, score
# play sound to signify score update
li $v0, 31
li $a0, 79
li $a1, 150
li $a2, 7
li $a3, 127
syscall
li $a0, 96
li $a1, 250
li $a2, 7
li $a3, 127
syscall
li $v0, 1 #set return value to 1 for collision
ExitCollisionCheck:
jr $ra
##################################################################
# Check Snake Body Collision
# $a0 - snakeHeadPositionX
# $a1 - snakeHeadPositionY
# $a2 - snakeHeadDirection
##################################################################
# returns $v0:
# 0 - does not hit body
# 1 - does hit body
##################################################################
CheckGameEndingCollision:
#save head coordinates
add $s3, $a0, $zero
add $s4, $a1, $zero
#save return address
sw $ra, 0($sp)
beq $a2, 119, CheckUp
beq $a2, 115, CheckDown
beq $a2, 97, CheckLeft
beq $a2, 100, CheckRight
j BodyCollisionDone #for error?
CheckUp:
#look above the current position
addiu $a1, $a1, -1
jal CoordinateToAddress
#get color at screen address
lw $t1, 0($v0)
#add $s6, $t1, $zero
lw $t2, snakeColor
lw $t3, borderColor
beq $t1, $t2, Exit #If colors are equal - YOU LOST!
beq $t1, $t3, Exit #If you hit the border - YOU LOST!
j BodyCollisionDone # if not, leave function
CheckDown:
#look below the current position
addiu $a1, $a1, 1
jal CoordinateToAddress
#get color at screen address
lw $t1, 0($v0)
#add $s6, $t1, $zero
lw $t2, snakeColor
lw $t3, borderColor
beq $t1, $t2, Exit #If colors are equal - YOU LOST!
beq $t1, $t3, Exit #If you hit the border - YOU LOST!
j BodyCollisionDone # if not, leave function
CheckLeft:
#look to the left of the current position
addiu $a0, $a0, -1
jal CoordinateToAddress
#get color at screen address
lw $t1, 0($v0)
#add $s6, $t1, $zero
lw $t2, snakeColor
lw $t3, borderColor
beq $t1, $t2, Exit #If colors are equal - YOU LOST!
beq $t1, $t3, Exit #If you hit the border - YOU LOST!
j BodyCollisionDone # if not, leave function
CheckRight:
#look to the right of the current position
addiu $a0, $a0, 1
jal CoordinateToAddress
#get color at screen address
lw $t1, 0($v0)
#add $s6, $t1, $zero
lw $t2, snakeColor
lw $t3, borderColor
beq $t1, $t2, Exit #If colors are equal - YOU LOST!
beq $t1, $t3, Exit #If you hit the border - YOU LOST!
j BodyCollisionDone # if not, leave function
BodyCollisionDone:
lw $ra, 0($sp) #restore return address
jr $ra
##################################################################
# Increase Difficulty Function
# no parameters
##################################################################
# no return values
##################################################################
IncreaseDifficulty:
lw $t0, score #get the player's score
la $t1, scoreMilestones #get the milestones base address
lw $t2, scoreArrayPosition #get the array position
add $t1, $t1, $t2 #move to position in array
lw $t3, 0($t1) #get the value at the array index
#if the player score is not equal to the current milestone
#exit the function, if they are equal increase difficulty
bne $t3, $t0, FinishedDiff
#increase the index for the milestones array
addiu $t2, $t2, 4
#store new position
sw $t2, scoreArrayPosition
#load the scoreGain variable to increase the
#points awarded for eating fruit
lw $t0, scoreGain
#multiply gain by 2
sll $t0, $t0, 1
#load the game speed
lw $t1, gameSpeed
#subtract 25 from the move speed
addiu $t1, $t1, -25
#store new speed
sw $t1, gameSpeed
FinishedDiff:
jr $ra
Exit:
#play a sound tune to signify game over
li $v0, 31
li $a0, 28
li $a1, 250
li $a2, 32
li $a3, 127
syscall
li $a0, 33
li $a1, 250
li $a2, 32
li $a3, 127
syscall
li $a0, 47
li $a1, 1000
li $a2, 32
li $a3, 127
syscall
li $v0, 56 #syscall value for dialog
la $a0, lostMessage #get message
lw $a1, score #get score
syscall
li $v0, 50 #syscall for yes/no dialog
la $a0, replayMessage #get message
syscall
beqz $a0, main#jump back to start of program
#end program
li $v0, 10
syscall