diff options
author | Aiden Gall <aiden@aidengall.xyz> | 2024-01-29 10:55:40 +0000 |
---|---|---|
committer | Aiden Gall <aiden@aidengall.xyz> | 2024-01-29 10:55:40 +0000 |
commit | 5f83664e8a4891945512c9adb4d2f0743cbb3afc (patch) | |
tree | 7fe6a6a9d26d885098d50797105706861d35503a |
initial commit
-rw-r--r-- | Makefile | 13 | ||||
-rw-r--r-- | ball-sim.asm | 163 |
2 files changed, 176 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0a9665c --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +SRC = ball-sim.asm +OBJ = ${SRC:.asm=.o} + +ball-sim: ${OBJ} + ld -o $@ $^ -O1 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc -lraylib -lm + +%.o: %.asm + fasm $< $@ + +.PHONY: clean + +clean: + rm -f ${OBJ} ball-sim diff --git a/ball-sim.asm b/ball-sim.asm new file mode 100644 index 0000000..769def2 --- /dev/null +++ b/ball-sim.asm @@ -0,0 +1,163 @@ +format ELF64 + +initial_width = 800 +initial_height = 450 + +FLAG_MSAA_4X_HINT = 32 + +struc splat x { + dd x, x, x, x +} + +struc Vec2 x,y { + dd x, y, 0.0, 0.0 +} + +struc Ball x, y, r { + .pos Vec2 x, y + .vel splat 0.0 + .rad splat r +} + +public _start + +extrn SetConfigFlags +extrn InitWindow +extrn SetTargetFPS +extrn WindowShouldClose +extrn GetMouseWheelMove +extrn IsMouseButtonDown +extrn GetMousePosition +extrn GetScreenWidth +extrn GetScreenHeight +extrn BeginDrawing +extrn EndDrawing +extrn ClearBackground +extrn DrawCircleV +extrn _exit + +section '.text' executable + +_start: + ; enable anti-aliasing + mov edi, FLAG_MSAA_4X_HINT + call SetConfigFlags + + ; initialise window + mov edi, initial_width + mov esi, initial_height + mov rdx, title + call InitWindow + + ; 60 fps + mov edi, 60 + call SetTargetFPS + + jmp loop_entr + +main_loop: + ; change ball size + call GetMouseWheelMove + shufps xmm0, xmm0, 0x0 + addps xmm0, [ball.rad] + maxps xmm0, [minimum_radius] + movlps [ball.rad], xmm0 + + ; check if lmb is pressed + xor edi, edi + call IsMouseButtonDown + test eax, eax + jz no_click + + ; accelerate ball towards mouse + call GetMousePosition + subps xmm0, [ball.pos] + mulps xmm0, [mouse_seek_speed] + + jmp move_and_draw + +no_click: + ; get width/height + call GetScreenWidth + mov ebx, eax + call GetScreenHeight + + ; convert width/height to packed single precision floats + cvtsi2ss xmm0, ebx + cvtsi2ss xmm1, eax + movlhps xmm0, xmm1 + shufps xmm0, xmm0, 0x8 + + ; load ball position and radius + movlps xmm1, [ball.pos] + movlps xmm2, [ball.rad] + + ; calculate upper boundaries + subps xmm0, xmm2 + + ; stash boundaries for later + movaps xmm3, xmm2 + movaps xmm4, xmm0 + + ; dirty, rotten, low-down, no-good hack + cmpnleps xmm2, xmm1 ; out of left/top bounds mask + cmpltps xmm0, xmm1 ; out of right/bottom bounds mask + orps xmm0, xmm2 ; or the masks + andps xmm0, [restitution_minus_one] ; mask & restitution coefficient minus one + addps xmm0, [ones] ; add ones to create bounce vector (0.0 -> 1.0, restitution - 1.0 -> restitution) + maxps xmm1, xmm3 + minps xmm1, xmm4 ; keep position in bounds + + ; scale velocity by bounce vector + mulps xmm0, [ball.vel] + + ; apply air resistance and gravity + mulps xmm0, [air_resistance_coef] + addps xmm0, [grav_accel] + + ; store position + movlps [ball.pos], xmm1 + +move_and_draw: + ; store velocity + movlps [ball.vel], xmm0 + + ; move ball + addps xmm0, [ball.pos] + movlps [ball.pos], xmm0 + + ; draw frame + call BeginDrawing + + ; black background + xor edi, edi + call ClearBackground + + ; sphere + movlps xmm0, [ball.pos] + movss xmm1, [ball.rad] + mov rdi, 0xFF2C7500 ; green + call DrawCircleV + + call EndDrawing + +loop_entr: + call WindowShouldClose + test eax, eax + jz main_loop + + xor edi, edi + call _exit + +section '.data' writable align 16 + mouse_seek_speed splat 0.5 + minimum_radius splat 2.5 + air_resistance_coef splat 0.99 + restitution_minus_one splat -1.8 + ones splat 1.0 + + grav_accel Vec2 0.0, 0.69 + + ball Ball 400.0, 250.0, 25.0 + + title db 'ball simulator',0 |