Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- FORMAT ELF64
- section '.text' executable
- public _start
- include 'functions.asm'
- struc Vector2 x, y {
- .x dd x
- .y dd y
- dd 0, 0 ; padding to fit exactly in one xmm register
- }
- ; Consts
- BLACK_COLOR = 0xFF000000
- SNAKE_COLOR = 0xFF443528
- FOOD_COLOR = 0xFF4422DD
- BACKGROUND_COLOR = 0xFFE0E0E0
- WINDOW_WIDTH = 800
- WINDOW_HEIGHT = 600
- SNAKE_STARTING_LENGTH = 4
- BORDER_MARGIN = 20
- _start:
- mov rdi, WINDOW_WIDTH
- mov rsi, WINDOW_HEIGHT
- mov rdx, window_name
- call InitWindow
- call spawn_food
- .main_loop:
- call WindowShouldClose
- test al, al
- jnz .close_window
- call BeginDrawing
- ; Draw Background
- mov rdi, BACKGROUND_COLOR
- call ClearBackground
- ; Draw Food
- movq xmm0, qword [food_position]
- movss xmm1, [food_size]
- mov rdi, FOOD_COLOR
- call DrawCircleV
- ; Draw Body
- mov rbx, 0
- @@:
- movq xmm0, qword [snake_points+(rbx*8)]
- movss xmm1, [snake_body_size]
- mov rdi, SNAKE_COLOR
- call DrawCircleV
- inc bl
- cmp bl, [snake_length]
- jl @b
- ; Draw Border Around Window
- mov rdi, 0
- mov rsi, 0
- mov rdx, WINDOW_WIDTH
- mov rcx, WINDOW_HEIGHT
- mov r8, BLACK_COLOR
- call DrawRectangleLines
- ; Draw Score
- mov rdi, score_text
- mov sil, [snake_length]
- sub rsi, SNAKE_STARTING_LENGTH
- call TextFormat
- mov rdi, rax
- mov rsi, 10
- mov rdx, WINDOW_HEIGHT-25
- mov rcx, 20
- mov r8, BLACK_COLOR
- call DrawText
- ; Draw FPS Counter
- mov rdi, 10
- mov rsi, 10
- call DrawFPS
- call EndDrawing
- ; Check if the head has touched the walls
- movd xmm0, dword [snake_points]
- cvtss2si rax, xmm0
- cmp rax, WINDOW_WIDTH
- jg .close_window
- movd xmm0, dword [snake_points+4]
- cvtss2si rax, xmm0
- cmp rax, WINDOW_HEIGHT
- jg .close_window
- ; Check if head has touched mouse cursor
- call GetMousePosition
- ptest xmm0, xmm0
- jz .main_loop
- movq xmm1, [snake_points]
- movss xmm2, [snake_hit_box]
- call CheckCollisionPointCircle
- test al, al
- jnz .close_window
- ; Check if snake collides with itself
- movq xmm0, [snake_points]
- call is_colliding_with_snake_body
- test al, al
- jnz .close_window
- ; Check if food is eaten
- movq xmm0, [snake_points]
- movss xmm1, [snake_body_size]
- movq xmm2, qword [food_position]
- movss xmm3, [food_size]
- call CheckCollisionCircles
- test al, al
- jz @f
- inc byte [snake_length]
- ; Increase speed after eating food
- movss xmm0, [speed]
- addss xmm0, [speed_increase]
- movss [speed], xmm0
- call spawn_food
- @@:
- ; Get Unit Vector/Direction Cosines from mouse
- call GetMousePosition
- movaps xmm1, xmm0
- movlps xmm0, [snake_points]
- call get_unit_vector
- movlps xmm1, [snake_points]
- vmovaps xmm2, xmm0
- call GetFrameTime
- mulss xmm0, [speed]
- vbroadcastss xmm4, xmm0
- ; Calculate Velocity and add to position
- vfmadd231ps xmm1, xmm2, xmm4
- vmovlps [snake_points], xmm1
- mov rbx, 1
- .calculate_neck_point:
- ; xmm2 is the last unit vector
- vmulps xmm0, xmm2, xword [neck_distance]
- vaddps xmm1, xmm0, xword [snake_points+((rbx-1)*8)]
- movq xmm3, qword [snake_points+(rbx*8)]
- ; if xmm3 is a zero vector, set the position to the last snake point
- ptest xmm3, xmm3
- jnz @f
- movq xmm3, qword [snake_points+((rbx-1)*8)]
- movq qword [snake_points+(rbx*8)], xmm3
- @@:
- vmovaps xmm0, xmm3
- call get_unit_vector
- vmovaps xmm2, xmm0
- vfmadd231ps xmm3, xmm2, xmm4
- movq qword [snake_points+(rbx*8)], xmm3
- inc bl
- cmp bl, [snake_length]
- jl .calculate_neck_point
- jmp .main_loop
- .close_window:
- call CloseWindow
- ; Exit the program
- mov rax, 0x3c
- mov rdi, 0
- syscall
- ; Functions
- spawn_food: ; void -> void
- mov edi, BORDER_MARGIN
- mov esi, WINDOW_WIDTH-BORDER_MARGIN
- call GetRandomValue
- cvtsi2ss xmm2, rax
- mov edi, BORDER_MARGIN
- mov esi, WINDOW_HEIGHT-BORDER_MARGIN
- call GetRandomValue
- cvtsi2ss xmm3, rax
- vinsertps xmm1, xmm2, xmm3, 16
- vmovlps qword [food_position], xmm1
- ret
- get_unit_vector: ; xmm0: point1, xmm1: point2 -> xmm0: unit_vector
- vsubps xmm1, xmm1, xmm0
- vmovaps xmm0, xmm1
- ; Calculate Inverse of Length
- dpps xmm0, xmm0, 00111111b
- rsqrtps xmm0, xmm0
- vmulps xmm0, xmm1, xmm0
- ret
- is_colliding_with_snake_body: ; xmm0: point -> al: bool
- movaps xmm4, xmm0
- mov bl, 4 ; ignore first 4 segments
- @@:
- cmp bl, [snake_length]
- jge @f
- movaps xmm0, xmm4
- movss xmm1, [snake_body_size]
- movq xmm2, qword [snake_points+(rbx*8)]
- movss xmm3, [snake_hit_box]
- call CheckCollisionCircles
- test al, al
- jnz @f
- inc bl
- jmp @b
- @@:
- ret
- section '.data' writeable align 16
- window_name db "Snake!", 0
- score_text db "Score: %d00", 0
- snake_length db SNAKE_STARTING_LENGTH
- align 4
- speed dd 250.0
- speed_increase dd 7.0
- snake_body_size dd 20.0
- snake_hit_box dd 2.0
- position Vector2 10.0, 10.0
- neck_distance Vector2 -10.0, -10.0
- food_position Vector2 0.0, 0.0
- food_size dd 15.0
- section '.bss' writeable align 16
- snake_points rq 256
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement