106 lines
4.9 KiB
Plaintext
106 lines
4.9 KiB
Plaintext
;;;; raylib, declared for Flan. The directory is the package (plan.org,
|
|
;;;; Modules), and (import rl "vendor:raylib") qualifies all of it as rl/…
|
|
;;;;
|
|
;;;; Nothing here names a raylib symbol. Every `declare` names a wrapper in
|
|
;;;; shim.c, and that is the whole design decision: raylib passes Color by
|
|
;;;; value and returns Vector2 by value, and how a small aggregate is passed
|
|
;;;; differs between x86-64, arm64 and wasm32. Written in C, clang classifies
|
|
;;;; each one correctly per target for free; written in emit.ml it would be
|
|
;;;; three calling conventions to reimplement and then maintain forever. This
|
|
;;;; is "one narrow host ABI, implemented twice" (plan.org, Targets), and it
|
|
;;;; is why the checker rejects an aggregate in a `declare` signature at all.
|
|
;;;;
|
|
;;;; So each struct that crosses does it through a pointer, and the `-raw`
|
|
;;;; declaration is wrapped by an ordinary Flan function just below it. The
|
|
;;;; `-raw` names are visible as rl/…-raw because there is no visibility rule
|
|
;;;; yet; they are not meant to be called.
|
|
|
|
;; Layouts are C's — no object headers anywhere — so these are exactly
|
|
;; raylib's structs and nothing marshals.
|
|
(defstruct Vector2 [x f32 y f32])
|
|
(defstruct Color [r u8 g u8 b u8 a u8])
|
|
|
|
;; KeyboardKey, the subset sand.flan uses. A keyword at a call site resolves
|
|
;; against these members at compile time and a typo is an error there.
|
|
(defenum Key
|
|
[space 32 apostrophe 39 comma 44 minus 45 period 46 slash 47
|
|
zero 48 one 49 two 50 three 51 four 52
|
|
five 53 six 54 seven 55 eight 56 nine 57
|
|
a 65 b 66 c 67 d 68 e 69 f 70 g 71 h 72 i 73
|
|
j 74 k 75 l 76 m 77 n 78 o 79 p 80 q 81 r 82
|
|
s 83 t 84 u 85 v 86 w 87 x 88 y 89 z 90
|
|
escape 256 enter 257 tab 258 backspace 259
|
|
right 262 left 263 down 264 up 265])
|
|
|
|
(defenum MouseButton
|
|
[left 0 right 1 middle 2 side 3 extra 4 forward 5 back 6])
|
|
|
|
(defenum TraceLogLevel
|
|
[all 0 trace 1 debug 2 info 3 warning 4 error 5 fatal 6 none 7])
|
|
|
|
;; ── Window ──────────────────────────────────────────────────────────
|
|
|
|
(declare init-window [width i32 height i32 title string] "flan_rl_init_window")
|
|
(declare close-window [] "flan_rl_close_window")
|
|
(declare window-should-close? [] bool "flan_rl_window_should_close")
|
|
(declare set-target-fps [fps i32] "flan_rl_set_target_fps")
|
|
(declare set-trace-log-level [level TraceLogLevel] "flan_rl_set_trace_log_level")
|
|
|
|
;; ── Input ───────────────────────────────────────────────────────────
|
|
|
|
(declare key-pressed? [key Key] bool "flan_rl_is_key_pressed")
|
|
(declare key-down? [key Key] bool "flan_rl_is_key_down")
|
|
(declare key-released? [key Key] bool "flan_rl_is_key_released")
|
|
|
|
(declare mouse-button-pressed? [button MouseButton] bool
|
|
"flan_rl_is_mouse_button_pressed")
|
|
(declare mouse-button-down? [button MouseButton] bool
|
|
"flan_rl_is_mouse_button_down")
|
|
(declare mouse-button-released? [button MouseButton] bool
|
|
"flan_rl_is_mouse_button_released")
|
|
|
|
(declare get-mouse-position-raw [out (Ptr Vector2)] "flan_rl_get_mouse_position")
|
|
|
|
(defn get-mouse-position [] Vector2
|
|
(let [v (Vector2 {})]
|
|
(get-mouse-position-raw (addr v))
|
|
v))
|
|
|
|
;; ── Colours ─────────────────────────────────────────────────────────
|
|
;;
|
|
;; A Color is four bytes in RGBA order, so it is *not* the little-endian
|
|
;; reading of the packed 0xRRGGBBAA integer — that is why get-color is a real
|
|
;; call and not a reinterpretation.
|
|
|
|
(declare get-color-raw [hex u32 out (Ptr Color)] "flan_rl_get_color")
|
|
|
|
(defn get-color [hex u32] Color
|
|
(let [c (Color {})]
|
|
(get-color-raw hex (addr c))
|
|
c))
|
|
|
|
(defconst black (Color {:r 0 :g 0 :b 0 :a 255}))
|
|
(defconst white (Color {:r 255 :g 255 :b 255 :a 255}))
|
|
|
|
;; ── Drawing ─────────────────────────────────────────────────────────
|
|
|
|
(declare begin-drawing [] "flan_rl_begin_drawing")
|
|
(declare end-drawing [] "flan_rl_end_drawing")
|
|
(declare draw-fps [x i32 y i32] "flan_rl_draw_fps")
|
|
|
|
(declare clear-background-raw [color (Ptr Color)] "flan_rl_clear_background")
|
|
|
|
(defn clear-background [color Color]
|
|
;; The copy is not ceremony: a parameter is not an assignable place
|
|
;; (spec-memory.md), so there is no address to take without one.
|
|
(let [c color]
|
|
(clear-background-raw (addr c))))
|
|
|
|
(declare draw-rectangle-raw
|
|
[x i32 y i32 width i32 height i32 color (Ptr Color)]
|
|
"flan_rl_draw_rectangle")
|
|
|
|
(defn draw-rectangle [x i32 y i32 width i32 height i32 color Color]
|
|
(let [c color]
|
|
(draw-rectangle-raw x y width height (addr c))))
|