Advertisement
Guest User

snake.asm (fasm)

a guest
Feb 5th, 2025
70
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. FORMAT ELF64
  2.  
  3. section '.text' executable
  4. public _start
  5.  
  6. include 'functions.asm'
  7.  
  8. struc Vector2 x, y {
  9.     .x dd x
  10.     .y dd y
  11.     dd 0, 0 ; padding to fit exactly in one xmm register
  12. }
  13.  
  14. ; Consts
  15. BLACK_COLOR = 0xFF000000
  16. SNAKE_COLOR = 0xFF443528
  17. FOOD_COLOR = 0xFF4422DD
  18. BACKGROUND_COLOR = 0xFFE0E0E0
  19. WINDOW_WIDTH = 800
  20. WINDOW_HEIGHT = 600
  21. SNAKE_STARTING_LENGTH = 4
  22. BORDER_MARGIN = 20
  23.  
  24. _start:
  25.     mov rdi, WINDOW_WIDTH
  26.     mov rsi, WINDOW_HEIGHT
  27.     mov rdx, window_name
  28.     call InitWindow
  29.  
  30.     call spawn_food
  31.  
  32. .main_loop:
  33.     call WindowShouldClose
  34.     test al, al
  35.     jnz .close_window
  36.  
  37.     call BeginDrawing
  38.  
  39.     ; Draw Background
  40.     mov rdi, BACKGROUND_COLOR
  41.     call ClearBackground
  42.  
  43.     ; Draw Food
  44.     movq xmm0, qword [food_position]
  45.     movss xmm1, [food_size]
  46.     mov rdi, FOOD_COLOR
  47.     call DrawCircleV
  48.  
  49.     ; Draw Body
  50.     mov rbx, 0
  51.     @@:
  52.     movq xmm0, qword [snake_points+(rbx*8)]
  53.     movss xmm1, [snake_body_size]
  54.     mov rdi, SNAKE_COLOR
  55.     call DrawCircleV
  56.  
  57.     inc bl
  58.     cmp bl, [snake_length]
  59.     jl @b
  60.  
  61.     ; Draw Border Around Window
  62.     mov rdi, 0
  63.     mov rsi, 0
  64.     mov rdx, WINDOW_WIDTH
  65.     mov rcx, WINDOW_HEIGHT
  66.     mov r8, BLACK_COLOR
  67.     call DrawRectangleLines
  68.  
  69.     ; Draw Score
  70.     mov rdi, score_text
  71.     mov sil, [snake_length]
  72.     sub rsi, SNAKE_STARTING_LENGTH
  73.     call TextFormat
  74.  
  75.     mov rdi, rax
  76.     mov rsi, 10
  77.     mov rdx, WINDOW_HEIGHT-25
  78.     mov rcx, 20
  79.     mov r8, BLACK_COLOR
  80.     call DrawText
  81.  
  82.     ; Draw FPS Counter
  83.     mov rdi, 10
  84.     mov rsi, 10
  85.     call DrawFPS
  86.  
  87.     call EndDrawing
  88.  
  89.     ; Check if the head has touched the walls
  90.     movd xmm0, dword [snake_points]
  91.     cvtss2si rax, xmm0
  92.     cmp rax, WINDOW_WIDTH
  93.     jg .close_window
  94.  
  95.     movd xmm0, dword [snake_points+4]
  96.     cvtss2si rax, xmm0
  97.     cmp rax, WINDOW_HEIGHT
  98.     jg .close_window
  99.  
  100.     ; Check if head has touched mouse cursor
  101.     call GetMousePosition
  102.  
  103.     ptest xmm0, xmm0
  104.     jz .main_loop
  105.    
  106.     movq xmm1, [snake_points]
  107.     movss xmm2, [snake_hit_box]
  108.     call CheckCollisionPointCircle
  109.     test al, al
  110.     jnz .close_window
  111.  
  112.     ; Check if snake collides with itself
  113.     movq xmm0, [snake_points]
  114.     call is_colliding_with_snake_body
  115.     test al, al
  116.     jnz .close_window
  117.  
  118.     ; Check if food is eaten
  119.     movq xmm0, [snake_points]
  120.     movss xmm1, [snake_body_size]
  121.     movq xmm2, qword [food_position]
  122.     movss xmm3, [food_size]
  123.     call CheckCollisionCircles
  124.     test al, al
  125.     jz @f
  126.    
  127.     inc byte [snake_length]
  128.  
  129.     ; Increase speed after eating food
  130.     movss xmm0, [speed]
  131.     addss xmm0, [speed_increase]
  132.     movss [speed], xmm0
  133.  
  134.     call spawn_food
  135.  
  136.     @@:
  137.  
  138.     ; Get Unit Vector/Direction Cosines from mouse
  139.     call GetMousePosition
  140.     movaps xmm1, xmm0
  141.  
  142.     movlps xmm0, [snake_points]
  143.  
  144.     call get_unit_vector
  145.  
  146.     movlps xmm1, [snake_points]
  147.     vmovaps xmm2, xmm0
  148.  
  149.     call GetFrameTime
  150.     mulss xmm0, [speed]
  151.     vbroadcastss xmm4, xmm0
  152.    
  153.     ; Calculate Velocity and add to position
  154.     vfmadd231ps xmm1, xmm2, xmm4
  155.     vmovlps [snake_points], xmm1
  156.  
  157.     mov rbx, 1
  158. .calculate_neck_point:
  159.     ; xmm2 is the last unit vector
  160.     vmulps xmm0, xmm2, xword [neck_distance]
  161.     vaddps xmm1, xmm0, xword [snake_points+((rbx-1)*8)]
  162.  
  163.     movq xmm3, qword [snake_points+(rbx*8)]
  164.  
  165.     ; if xmm3 is a zero vector, set the position to the last snake point
  166.     ptest xmm3, xmm3
  167.     jnz @f
  168.     movq xmm3, qword [snake_points+((rbx-1)*8)]
  169.     movq qword [snake_points+(rbx*8)], xmm3
  170.     @@:
  171.    
  172.     vmovaps xmm0, xmm3
  173.     call get_unit_vector
  174.     vmovaps xmm2, xmm0
  175.  
  176.     vfmadd231ps xmm3, xmm2, xmm4
  177.     movq qword [snake_points+(rbx*8)], xmm3
  178.  
  179.     inc bl
  180.     cmp bl, [snake_length]
  181.     jl .calculate_neck_point
  182.  
  183.     jmp .main_loop
  184.  
  185. .close_window:
  186.     call CloseWindow
  187.  
  188.     ; Exit the program
  189.     mov rax, 0x3c
  190.     mov rdi, 0
  191.     syscall
  192.  
  193.  
  194. ; Functions
  195. spawn_food: ; void -> void
  196.     mov edi, BORDER_MARGIN
  197.     mov esi, WINDOW_WIDTH-BORDER_MARGIN
  198.     call GetRandomValue
  199.     cvtsi2ss xmm2, rax
  200.  
  201.     mov edi, BORDER_MARGIN
  202.     mov esi, WINDOW_HEIGHT-BORDER_MARGIN
  203.     call GetRandomValue
  204.     cvtsi2ss xmm3, rax
  205.  
  206.     vinsertps xmm1, xmm2, xmm3, 16
  207.     vmovlps qword [food_position], xmm1
  208.     ret
  209.  
  210. get_unit_vector: ; xmm0: point1, xmm1: point2 -> xmm0: unit_vector
  211.     vsubps xmm1, xmm1, xmm0
  212.     vmovaps xmm0, xmm1
  213.  
  214.     ; Calculate Inverse of Length
  215.     dpps xmm0, xmm0, 00111111b
  216.     rsqrtps xmm0, xmm0
  217.  
  218.     vmulps xmm0, xmm1, xmm0
  219.     ret
  220.  
  221. is_colliding_with_snake_body: ; xmm0: point -> al: bool
  222.     movaps xmm4, xmm0
  223.  
  224.     mov bl, 4 ; ignore first 4 segments
  225.     @@:
  226.     cmp bl, [snake_length]
  227.     jge @f
  228.  
  229.     movaps xmm0, xmm4
  230.     movss xmm1, [snake_body_size]
  231.     movq xmm2, qword [snake_points+(rbx*8)]
  232.     movss xmm3, [snake_hit_box]
  233.     call CheckCollisionCircles
  234.     test al, al
  235.     jnz @f
  236.  
  237.     inc bl
  238.     jmp @b
  239.     @@:
  240.    
  241.     ret
  242.  
  243.  
  244. section '.data' writeable align 16
  245.     window_name db "Snake!", 0
  246.     score_text db "Score: %d00", 0
  247.  
  248.     snake_length db SNAKE_STARTING_LENGTH
  249.        
  250.     align 4
  251.  
  252.     speed dd 250.0
  253.     speed_increase dd 7.0
  254.    
  255.     snake_body_size dd 20.0
  256.     snake_hit_box dd 2.0
  257.  
  258.     position Vector2 10.0, 10.0
  259.    
  260.     neck_distance Vector2 -10.0, -10.0
  261.  
  262.     food_position Vector2 0.0, 0.0
  263.     food_size dd 15.0
  264.  
  265. section '.bss' writeable align 16
  266.     snake_points rq 256
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement