OK LETS GIT HOLY SHIT
This commit is contained in:
@@ -0,0 +1,369 @@
|
||||
#define WIDTH 60
|
||||
#define HEIGHT 40
|
||||
|
||||
.bss
|
||||
# Array of longs representing the game field
|
||||
.align 4
|
||||
world: .space WIDTH*HEIGHT*4
|
||||
|
||||
.data
|
||||
# Current length of the snake
|
||||
snakeLength: .long 0
|
||||
# Snake position
|
||||
snakePosX: .long WIDTH / 2
|
||||
snakePosY: .long HEIGHT / 2
|
||||
# Snake direction
|
||||
snakeDirX: .long 1
|
||||
snakeDirY: .long 0
|
||||
# Number of apples
|
||||
numApples: .long 0
|
||||
# Optional score-keeping
|
||||
score: .long 0
|
||||
# Utility strings
|
||||
snibbles: .ascii "NIBBLES"
|
||||
sgameover: .string " Game over! Score: %i "
|
||||
sgameover_end:
|
||||
string1: .string "Started with snake length %i and %i apples!\n"
|
||||
string2: .string "Snake position: (%i, %i)\n"
|
||||
stringi: .string "%i\n"
|
||||
stringtest: .string "> %i %i %c\n"
|
||||
|
||||
.text
|
||||
.global start_game
|
||||
start_game:
|
||||
# snakeLength = len
|
||||
movl 4(%esp), %eax
|
||||
movl %eax, snakeLength
|
||||
# numApples = n_apples
|
||||
movl 8(%esp), %eax
|
||||
movl %eax, numApples
|
||||
|
||||
pushl %ebx
|
||||
pushl %edi
|
||||
|
||||
# Call nib_init
|
||||
call nib_init
|
||||
# Seed randomness
|
||||
pushl $0
|
||||
call time
|
||||
addl $4, %esp
|
||||
pushl %eax
|
||||
call srand
|
||||
addl $4, %esp
|
||||
|
||||
# Print our arguments
|
||||
#pushl numApples
|
||||
#pushl snakeLength
|
||||
#pushl $string1
|
||||
#call printf
|
||||
#addl $4*3, %esp
|
||||
|
||||
# Print worm position
|
||||
#pushl snakePosY
|
||||
#pushl snakePosX
|
||||
#pushl $string2
|
||||
#call printf
|
||||
#addl $4*3, %esp
|
||||
|
||||
# Initialize the snake array
|
||||
# Set every cell to a time value greater than the snake length
|
||||
movl $world, %edi
|
||||
movl snakeLength, %eax
|
||||
movl $WIDTH*HEIGHT, %ebx
|
||||
xorl %ecx, %ecx
|
||||
1:
|
||||
movl %eax, (%edi, %ecx, 4)
|
||||
incl %ecx
|
||||
cmpl %ebx, %ecx
|
||||
jl 1b
|
||||
|
||||
# Spawn initial apples
|
||||
movl numApples, %ecx
|
||||
1:
|
||||
pushl %ecx
|
||||
call spawnApple
|
||||
popl %ecx
|
||||
loop 1b
|
||||
|
||||
# Loop forever
|
||||
loop:
|
||||
# Sleep for 150 ms
|
||||
pushl $500*1000
|
||||
call usleep
|
||||
addl $4, %esp
|
||||
jmp tick
|
||||
|
||||
popl %edi
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
# Update stuff
|
||||
tick:
|
||||
movl $world, %edi
|
||||
|
||||
# Increment cell times
|
||||
movl snakeLength, %ebx
|
||||
xorl %ecx, %ecx
|
||||
1:
|
||||
movl (%edi, %ecx, 4), %eax
|
||||
# If the value is negative it's an apple we don't want to disappear
|
||||
test %eax, %eax
|
||||
js 2f
|
||||
# No need to increment if it's already greater than snakeLength
|
||||
cmpl %ebx, %eax
|
||||
jg 2f
|
||||
# Increment the cell value
|
||||
incl %eax
|
||||
movl %eax, (%edi, %ecx, 4)
|
||||
2: incl %ecx # Loop increment
|
||||
cmpl $WIDTH*HEIGHT, %ecx
|
||||
jne 1b
|
||||
|
||||
# Input
|
||||
call nib_poll_kbd
|
||||
# Down
|
||||
movl $258, %ebx
|
||||
cmpl %eax, %ebx
|
||||
jne 1f
|
||||
movl $0, snakeDirX
|
||||
movl $1, snakeDirY
|
||||
1: # Up
|
||||
movl $259, %ebx
|
||||
cmpl %eax, %ebx
|
||||
jne 1f
|
||||
movl $0, snakeDirX
|
||||
movl $-1, snakeDirY
|
||||
1: # Left
|
||||
movl $260, %ebx
|
||||
cmpl %eax, %ebx
|
||||
jne 1f
|
||||
movl $-1, snakeDirX
|
||||
movl $0, snakeDirY
|
||||
1: # Right
|
||||
movl $261, %ebx
|
||||
cmpl %eax, %ebx
|
||||
jne 1f
|
||||
movl $1, snakeDirX
|
||||
movl $0, snakeDirY
|
||||
1:
|
||||
|
||||
# Move snake
|
||||
# snakePosX = (snakePosX + snakeDirY + WIDTH) % WIDTH
|
||||
movl snakePosX, %eax
|
||||
movl snakeDirX, %ebx
|
||||
addl %ebx, %eax
|
||||
addl $WIDTH, %eax # For modulo wrap-around
|
||||
xorl %edx, %edx
|
||||
movl $WIDTH, %ecx
|
||||
divl %ecx
|
||||
mov %edx, snakePosX
|
||||
# snakePosY = (snakePosY + snakeDirY + HEIGHT) % HEIGHT
|
||||
movl snakePosY, %eax
|
||||
movl snakeDirY, %ebx
|
||||
addl %ebx, %eax
|
||||
addl $HEIGHT, %eax # For modulo wrap-around
|
||||
xorl %edx, %edx
|
||||
movl $HEIGHT, %ecx
|
||||
divl %ecx
|
||||
mov %edx, snakePosY
|
||||
|
||||
# Get value at head position
|
||||
movl snakePosY, %eax
|
||||
movl $WIDTH, %edx
|
||||
mull %edx
|
||||
addl snakePosX, %eax
|
||||
movl (%edi, %eax, 4), %edx
|
||||
|
||||
# Collision with apple if negative
|
||||
test %edx, %edx
|
||||
js 1f
|
||||
# No need to increment if it's already greater than snakeLength
|
||||
movl snakeLength, %ebx
|
||||
cmpl %ebx, %edx
|
||||
jg 2f
|
||||
# End the game when the snake collides with itself
|
||||
jmp gameOver
|
||||
1: # Spawn a new apple
|
||||
pushl %edi
|
||||
pushl %eax
|
||||
call spawnApple
|
||||
popl %eax
|
||||
popl %edi
|
||||
# Extend the snake!
|
||||
incl snakeLength
|
||||
2:
|
||||
|
||||
# Set time value to 0 at snake head position
|
||||
# i = x + y * WIDTH
|
||||
# %edi = %ebx + %ecx * $WIDTH
|
||||
movl $0, (%edi, %eax, 4)
|
||||
|
||||
jmp draw
|
||||
#jmp debug_draw
|
||||
|
||||
# Draw stuff
|
||||
draw:
|
||||
# Loop Y
|
||||
movl $HEIGHT, %ecx
|
||||
1:
|
||||
# Loop X
|
||||
movl $WIDTH, %ebx
|
||||
2:
|
||||
# Save loop registers
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
subl $1, %ecx
|
||||
subl $1, %ebx
|
||||
|
||||
# Call nib_put_scr
|
||||
|
||||
# i = x + y * WIDTH
|
||||
# %eax = %ebx + %ecx * $WIDTH
|
||||
movl %ecx, %eax
|
||||
movl $WIDTH, %edx
|
||||
mull %edx
|
||||
addl %ebx, %eax
|
||||
# Fetch the value of the cell
|
||||
movl $world, %edi
|
||||
movl (%edi, %eax, 4), %eax
|
||||
|
||||
# Compare with the snake length
|
||||
cmpl snakeLength, %eax
|
||||
# If the value is negative, it's an apple
|
||||
test %eax, %eax
|
||||
js 4f
|
||||
# If it's greater or equal to snakeLength, it's empty
|
||||
cmpl snakeLength, %eax
|
||||
jge 3f
|
||||
# Else, it's part of the snake
|
||||
pushl $'@'
|
||||
jmp 5f
|
||||
3: pushl $' '
|
||||
jmp 5f
|
||||
4: pushl $'o'
|
||||
5:
|
||||
|
||||
movl %ecx, %eax # Y
|
||||
pushl %eax
|
||||
|
||||
movl %ebx, %eax # X
|
||||
pushl %eax
|
||||
|
||||
call nib_put_scr
|
||||
addl $4*3, %esp
|
||||
|
||||
# Restore loop registers
|
||||
popl %ebx
|
||||
popl %ecx
|
||||
|
||||
decl %ebx # Decrement X
|
||||
jnz 2b # End of X loop
|
||||
loop 1b # End of Y loop
|
||||
|
||||
jmp loop
|
||||
|
||||
# Debug drawing
|
||||
debug_draw:
|
||||
# Loop Y
|
||||
movl $HEIGHT, %ecx
|
||||
1:
|
||||
# Loop X
|
||||
movl $WIDTH, %ebx
|
||||
2:
|
||||
# Save loop registers
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
subl $1, %ecx
|
||||
subl $1, %ebx
|
||||
|
||||
# Call nib_put_scr
|
||||
|
||||
# i = x + y * WIDTH
|
||||
# %edi = %ebx + %ecx * $WIDTH
|
||||
movl %ecx, %eax
|
||||
movl $WIDTH, %edx
|
||||
mull %edx
|
||||
addl %ebx, %eax
|
||||
# Fetch the value of the cell
|
||||
movl $world, %edi
|
||||
movl (%edi, %eax, 4), %eax
|
||||
pushl %eax
|
||||
|
||||
movl %ecx, %eax # Y
|
||||
pushl %eax
|
||||
|
||||
movl %ebx, %eax # X
|
||||
pushl %eax
|
||||
|
||||
call nib_put_scr
|
||||
addl $4*3, %esp
|
||||
|
||||
# Restore loop registers
|
||||
popl %ebx
|
||||
popl %ecx
|
||||
|
||||
decl %ebx # Decrement X
|
||||
jnz 2b # End of X loop
|
||||
loop 1b # End of Y loop
|
||||
|
||||
jmp loop
|
||||
|
||||
gameOver:
|
||||
# Calculate string length
|
||||
movl $sgameover_end, %eax
|
||||
subl $sgameover, %eax
|
||||
subl $1, %eax # Discount null terminator
|
||||
|
||||
# Calculate X-pos
|
||||
movl $2, %ebx
|
||||
xorl %edx, %edx
|
||||
divl %ebx
|
||||
negl %eax
|
||||
addl $WIDTH/2, %eax
|
||||
|
||||
# Print game over message
|
||||
pushl snakeLength
|
||||
pushl $sgameover
|
||||
pushl %eax # X
|
||||
pushl $HEIGHT/2 # Y
|
||||
call mvprintw
|
||||
add $4*3, %esp
|
||||
call refresh
|
||||
|
||||
pushl $3000*1000
|
||||
call usleep
|
||||
addl $4, %esp
|
||||
call nib_end
|
||||
|
||||
spawnApple:
|
||||
pushl %ebx
|
||||
|
||||
# %ecx = rand() % HEIGHT
|
||||
call rand
|
||||
xorl %edx, %edx
|
||||
movl $HEIGHT, %ebx
|
||||
divl %ebx
|
||||
movl %edx, %ecx
|
||||
# %ebx = rand() % WIDTH
|
||||
pushl %ecx
|
||||
call rand
|
||||
xorl %edx, %edx
|
||||
movl $WIDTH, %ebx
|
||||
divl %ebx
|
||||
movl %edx, %ebx
|
||||
popl %ecx
|
||||
|
||||
# i = x + y * WIDTH
|
||||
# %eax = %ebx + %ecx * $WIDTH
|
||||
movl %ecx, %eax
|
||||
movl $WIDTH, %edx
|
||||
mull %edx
|
||||
addl %ebx, %eax
|
||||
|
||||
# Set the cell negative to represent an apple
|
||||
movl $world, %ecx
|
||||
movl $-1, %edx
|
||||
movl %edx, (%ecx, %eax, 4)
|
||||
|
||||
popl %ebx
|
||||
ret
|
||||
Reference in New Issue
Block a user