;;;; raylib [core] example - delta time ;;;; ;;;; examples/core/core_delta_time.c. Needed get-mouse-wheel-move and get-fps, ;;;; both now bound — draw-fps was already there, but it puts the number on the ;;;; screen itself and this example wants to compare it against the target it ;;;; set, so it needs the number back. ;;;; ;;;; Three TextFormats in the C. Two of the three are a fixed number of ;;;; decimal places, which `f64->bytes` cannot do — it is "%g" — so they ;;;; still go through examples/digits.flan. The integer one does too, only ;;;; because its width is needed to put the next piece after it; the draw ;;;; itself is now (string (i64->bytes n)) and one draw-text. ;;;; ;;;; One faithfulness note that is a bug in the C and is kept anyway: it draws ;;;; `TextFormat("Frame time: %02.02f ms", GetFrameTime())` — GetFrameTime is ;;;; in SECONDS, so at 60 fps the C's own screen reads "0.02 ms" for what is ;;;; really 16.7 ms. Porting it as-is means the two programs show the same ;;;; thing, which is what a port is for; the milliseconds are drawn beside it ;;;; here rather than instead of it, so the file is not quietly asserting that ;;;; the original was right. ;;;; ;;;; The two circle positions are `defvar`s for the usual reason: they are ;;;; state between frames and a `let` inside the loop would reset them. (import rl "vendor:raylib") (import d "digits.flan") (defconst screen-width 800) (defconst screen-height 450) (defconst speed f32 10.0) (defconst circle-radius f32 32.0) (defvar delta-circle rl/Vector2) (defvar frame-circle rl/Vector2) (defvar current-fps i32) (defn main [] () (rl/init-window screen-width screen-height "raylib [core] example - delta time") (defer (rl/close-window)) (set current-fps 60) (set delta-circle (rl/Vector2 {.x 0.0 .y (/ (f32 screen-height) 3.0)})) (set frame-circle (rl/Vector2 {.x 0.0 .y (* (f32 screen-height) (/ 2.0 3.0))})) (rl/set-target-fps current-fps) (until (rl/window-should-close?) ;; Update (let [wheel (rl/get-mouse-wheel-move)] (unless (= wheel 0.0) (set current-fps (+ current-fps (i32 wheel))) (when (< current-fps 0) (set current-fps 0)) (rl/set-target-fps current-fps))) ;; The whole point of the example: one circle is scaled by the frame time ;; and one is not, so lowering the target with the wheel makes the second ;; one crawl while the first keeps its speed. (set (.x delta-circle) (+ (.x delta-circle) (* (rl/get-frame-time) (* 6.0 speed)))) (set (.x frame-circle) (+ (.x frame-circle) (* 0.1 speed))) (when (> (.x delta-circle) (f32 screen-width)) (set (.x delta-circle) 0.0)) (when (> (.x frame-circle) (f32 screen-width)) (set (.x frame-circle) 0.0)) (when (rl/key-pressed? :r) (set (.x delta-circle) 0.0) (set (.x frame-circle) 0.0)) ;; Draw (rl/with-drawing (rl/clear-background rl/raywhite) (rl/draw-circle-v delta-circle circle-radius rl/red) (rl/draw-circle-v frame-circle circle-radius rl/blue) ;; "FPS: unlimited (%i)" when the target is 0, "FPS: %i (target: %i)" ;; otherwise — the C's own branch, reassembled out of literals and ;; draw-int. `x` walks along the line as each piece is drawn, which is what ;; the returned width from draw-int is for. (if (<= current-fps 0) (let [x 10] (rl/draw-text "FPS: unlimited (" x 10 20 rl/darkgray) (set x (+ x (rl/measure-text "FPS: unlimited (" 20))) (set x (+ x (d/draw-int (rl/get-fps) x 10 20 rl/darkgray))) (rl/draw-text ")" x 10 20 rl/darkgray)) (let [x 10] (rl/draw-text "FPS: " x 10 20 rl/darkgray) (set x (+ x (rl/measure-text "FPS: " 20))) (set x (+ x (d/draw-int (rl/get-fps) x 10 20 rl/darkgray))) (rl/draw-text " (target: " x 10 20 rl/darkgray) (set x (+ x (rl/measure-text " (target: " 20))) (set x (+ x (d/draw-int current-fps x 10 20 rl/darkgray))) (rl/draw-text ")" x 10 20 rl/darkgray))) ;; The C's line, kept exactly — seconds, labelled ms. (let [x 10] (rl/draw-text "Frame time: " x 30 20 rl/darkgray) (set x (+ x (rl/measure-text "Frame time: " 20))) (set x (+ x (d/draw-f32 (rl/get-frame-time) 2 x 30 20 rl/darkgray))) (rl/draw-text " ms" x 30 20 rl/darkgray)) ;; And the same number in the unit the label claims, so the file does not ;; have to be read to notice. (let [x 10] (rl/draw-text "(really " x 50 20 rl/lightgray) (set x (+ x (rl/measure-text "(really " 20))) (set x (+ x (d/draw-f32 (* (rl/get-frame-time) 1000.0) 2 x 50 20 rl/lightgray))) (rl/draw-text " ms)" x 50 20 rl/lightgray)) (rl/draw-text "Use the scroll wheel to change the fps limit, r to reset" 10 70 20 rl/darkgray) (rl/draw-text "FUNC: x += GetFrameTime()*speed" 10 110 20 rl/red) (rl/draw-text "FUNC: x += speed" 10 260 20 rl/blue))))