# All the code in one file
# All the code in one file
# All the code in one file
.globl main
.data
#####
victoryMessage:  	.asciiz "You have won the game!"

amountOfRows:    	.word 16		# The mount of rows of pixels
amountOfColumns: 	.word 32		# The mount of columns of pixels

currentPositionX:    	.word 0 		# The column num
currentPositionY: 	.word 0			# The row num

wallColor:      	.word 0x004286F4    # Color used for walls (blue)
passageColor:   	.word 0x00000000    # Color used for passages (black)
playerColor:    	.word 0x00FFFF00    # Color used for player (yellow)
exitColor:		.word 0x0000FF00    # Color used for exit (green)
#####

#####
# for Func read_maze
error_msg:		.asciiz "Error: Could not open file.\n"
mazeFilename:		.asciiz "input_1.txt"
buffer:			.space 4096

file_char_table:
	.byte 'w', 'p', 's', 'u'	# Valid characters
	.space 4                  	# Placeholder

file_char_switch_table:
	.word wall_case				# case
	.word passage_case			# case
	.word player_case			# case
	.word exit_case				# case
	.word file_invalid_case
#####

#####
prompt:      		.asciiz "Enter a character (z, s, q, d): "
up_msg:      		.asciiz "up"
down_msg:    		.asciiz "down"
left_msg:    		.asciiz "left"
right_msg:   		.asciiz "right"
exit_msg:   		.asciiz "exit"
invalid_msg: 		.asciiz "Unknown input! Valid inputs: z s q d x"
newline:     		.asciiz "\n"

input:       		.space 2  # Buffer for input

input_char_table:
	.byte 'q', 's', 'z', 'd', 'x'	# Valid characters
	.space 5                  	# Placeholder

input_char_switch_table:
	.word left_case			# case 'q'
	.word down_case			# case 's'
	.word up_case			# case 'z'
	.word right_case		# case 'd'
	.word game_exit_case		# case 'x'
	.word invalid_case
#####

.text

##############################################################################
read_file:
    sw $fp, 0($sp)
    move $fp, $sp
    subu $sp, $sp, 8
    sw $ra, -4($fp)
    
    sw $s6, -8($fp)

    # Open file
    li $v0, 13
    li $a1, 0
    li $a2, 0
    syscall

    bltz $v0, file_error
    move $s6, $v0

read_loop:
    li $v0, 14
    move $a0, $s6
    la $a1, buffer
    li $a2, 4096
    syscall

    beqz $v0, end_read

    # Null-terminate the buffer
    la $t0, buffer
    add $t0, $t0, $v0
    sb $zero, 0($t0)

    j read_loop

end_read:
    # Close the file
    li $v0, 16
    move $a0, $s6
    syscall

    j file_end

file_error:
    # Print error message
    la $a0, error_msg
    li $v0, 4
    syscall

file_end:

    lw $s6, -8($fp)
    
    lw $ra, -4($fp)
    move $sp, $fp
    lw $fp, 0($sp)
    jr $ra
##############################################################################

##############################################################################
# Func
color_maze:
	sw $fp, 0($sp)
	move $fp, $sp
	subu $sp, $sp, 20
	sw $ra, -4($fp)
	
	sw $s0, -8($fp)
	sw $s1, -12($fp)
	sw $s4, -16($fp)

	li $t6, 0
	lw $s0, amountOfRows
	
	li $t7, 0
	lw $s1, amountOfColumns
	
	la $s4, buffer
	
new_row:	
	bgt $t6, $s0, maze_end
new_colum:	
	bgt $t7, $s1, row_end
	# Load first character from input

	lb $t0, 0($s4)
	
	move $a0, $t6
	move $a1, $t7
	
	# Check the character in the table
    	la $t1, file_char_table
    	la $t4, file_char_table
    	li $t2, 4
file_check_loop:
    	beq $zero, $t2, file_invalid_case
    	lb $t3, 0($t1)
    	beq $t0, $t3, file_char_found
    	addiu $t1, $t1, 1
    	subu $t2, $t2, 1
    	j file_check_loop
    	
file_char_found:
	# Calculate index for switch_table
	subu $t1, $t1, $t4
	sll $t1, $t1, 2
	la $t2, file_char_switch_table
	addu $t2, $t2, $t1
	lw $t2, 0($t2)
	jr $t2
	nop
    
wall_case:
	lw $a2, wallColor
	jal color_pixel
	j end_of_file_case
	
passage_case:
	lw $a2, passageColor
	jal color_pixel
	j end_of_file_case
	
player_case:
	lw $a2, playerColor
	jal color_pixel
	sw $t7, currentPositionX
	sw $t6, currentPositionY
	j end_of_file_case
	
exit_case:
	lw $a2, exitColor
	jal color_pixel
	j end_of_file_case
	
file_invalid_case:
	j end_of_file_case
	
end_of_file_case:

	addi $s4, $s4, 1
	addi $t7, $t7, 1
	j new_colum
	
row_end:
	li $t7, 0
	addi $t6, $t6, 1
	j new_row
	
maze_end:

	lw $s4, -16($fp)
	lw $s1, -12($fp)
	lw $s0, -8($fp)
	
	lw $ra, -4($fp)
	move $sp, $fp
	lw $fp, 0($sp)
	jr $ra
##############################################################################

##############################################################################
# Func
translate_coordinates:
	sw $fp , 0( $sp )
	move $fp , $sp
	subu $sp , $sp , 8
	sw $ra , -4( $fp )
	
	move $t0, $a0
	move $t1, $a1
	
	li $t3, 4
	mult $t1, $t3
	mflo $t1
	
	li $t2, 128
	mult $t0, $t2
	mflo $t0
	
	add $t4, $gp, $t0
	add $v0, $t4, $t1
	
	lw $ra , -4( $fp )
	move $sp , $fp
	lw $fp , ( $sp )
	jr $ra
##############################################################################

##############################################################################
# Func
color_pixel:
	sw $fp , 0( $sp )
	move $fp , $sp
	subu $sp , $sp , 8
	sw $ra , -4( $fp )
	
						#row and column number already in a0 and a1
	jal translate_coordinates
	
	sw $a2, ($v0)
	
	lw $ra , -4( $fp )
	move $sp , $fp
	lw $fp , ( $sp )
	jr $ra
##############################################################################

##############################################################################
# Func
direction:
	sw $fp , 0( $sp )
	move $fp , $sp
	subu $sp , $sp , 8
	sw $ra , -4( $fp )
	
	li $t7, 0
	# Print the prompt
    	li $v0, 4
	la $a0, prompt
	syscall

	# Read a character
	li $v0, 8
	la $a0, input
	li $a1, 2
	syscall

	# Print newline
	la $a0, newline
	li $v0, 4
	syscall

	# Load first character from input
	lb $t0, input
	
	# Check the character in the table
    	la $t1, input_char_table
    	la $t4, input_char_table
    	li $t2, 5
check_loop:
    	beq $zero, $t2, invalid_case
    	lb $t3, 0($t1)
    	beq $t0, $t3, char_found
    	addiu $t1, $t1, 1
    	subu $t2, $t2, 1
    	j check_loop
    	
char_found:
	# Calculate index for switch_table
	subu $t1, $t1, $t4
	sll $t1, $t1, 2
	la $t2, input_char_switch_table
	addu $t2, $t2, $t1
	lw $t2, 0($t2)
	jr $t2
	nop
    
up_case:
	la $a0, up_msg
	li $t5, 0
	li $t6, -1
	j end_of_case
	
down_case:
	la $a0, down_msg
	li $t5, 0
	li $t6, 1
	j end_of_case
	
left_case:
	la $a0, left_msg
	li $t5, -1
	li $t6, 0
	j end_of_case
	
right_case:
	la $a0, right_msg
	li $t5, 1
	li $t6, 0
	j end_of_case

game_exit_case:
	la $a0, exit_msg
	li $t5, 0
	li $t6, 0
	li $t7, 1
	j end_of_case
	
invalid_case:
	la $a0, invalid_msg
	li $t5, 0
	li $t6, 0
	j end_of_case
	
end_of_case:

	li $v0, 4
	syscall

	# Print newline
	la $a0, newline
	li $v0, 4
	syscall
	
	move $a0, $t6
	move $a1, $t5
	move $v1, $t7				
	
	jal move_player

	lw $ra , -4( $fp )
	move $sp , $fp
	lw $fp , ( $sp )
	jr $ra
##############################################################################

##############################################################################
# Func
move_player:
	sw $fp , 0( $sp )
	move $fp , $sp
	subu $sp , $sp , 36
	sw $ra , -4( $fp )
	sw $s0, -8($fp)
	sw $s1, -12($fp)
	sw $s2, -16($fp)
	sw $s3, -20($fp)
	sw $s4, -24($fp)
	sw $s5, -28($fp)
	sw $s6, -32($fp)
	
	lw $s0, currentPositionY
	add $a0, $a0, $s0
	move $s2, $a0
	
	lw $s1, currentPositionX
	add $a1, $a1, $s1
	move $s3, $a1
	
	jal translate_coordinates
	
	lw $t3, 0($v0)
	lw $s4, passageColor
	lw $s5, exitColor
	
	sub $t4, $t3, $s4
	sltu $t4, $zero, $t4
	sub $t5, $t3, $s5
	sltu $s5, $zero, $t5
	
	and $t4, $t4, $s5
	
	bne  $zero, $t4, end_this_move

	lw $t6, playerColor
	sw $t6, 0($v0)
	
	move $a0, $s0
	move $a1, $s1
	jal translate_coordinates
	sw $s4, 0($v0)
	
	sw $s2, currentPositionY
	sw $s3, currentPositionX
	
	bne $zero, $s5, end_this_move
	# Print the victoryMessage
    	li $v0, 4
	la $a0, victoryMessage
	syscall
	addi $v1, $v1, 1
		
end_this_move:
	
	lw $s6, -32($fp)
	lw $s5, -28($fp)
	lw $s4, -24($fp)
	lw $s3, -20($fp)
	lw $s2, -16($fp)
	lw $s1, -12($fp)
	lw $s0, -8($fp)
	lw $ra , -4( $fp )
	move $sp , $fp
	lw $fp , ( $sp )
	jr $ra
##############################################################################
main:
	la $a0, mazeFilename
    	jal read_file
    	jal color_maze
play:
	jal direction
	bne $zero, $v1, exit
	j play
exit:
    # syscall to end the program
    li $v0, 10    
    syscall
