summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAiden Gall <aiden@aidengall.xyz>2024-01-29 10:55:40 +0000
committerAiden Gall <aiden@aidengall.xyz>2024-01-29 10:55:40 +0000
commit5f83664e8a4891945512c9adb4d2f0743cbb3afc (patch)
tree7fe6a6a9d26d885098d50797105706861d35503a
initial commit
-rw-r--r--Makefile13
-rw-r--r--ball-sim.asm163
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