diff --git a/FIX.org b/FIX.org index dbc5214..62fd0f8 100644 --- a/FIX.org +++ b/FIX.org @@ -4462,3 +4462,88 @@ sand-dependent tests (test_flan's parse pin, test_session's create, test_acceptance's "a package's main is not visible") are red here and turn green when those seven lines say ~defonce~ (or ~def~, where the author wants the initialiser to follow the source — ~colors~ was the motivating one). + +* The enum prefix goes uniform, 2026-09-21 + +** The ruling, author's words +"I think the prefix reads better, keep it." So it stays, and it stops being +a thing two enums have: two prefixed out of eleven was the inconsistency, +not the prefix. This closes the survey left open under "Enum keyword +prefixes, 2026-09-20" — every enum on that list now has a ruling. + +** The table, as applied +| Key | KEY_ | ~key-~ | +| MouseButton | MOUSE_BUTTON_ | ~mouse-~ | +| TraceLogLevel | LOG_ | ~log-~ | +| CameraProjection | CAMERA_ | ~projection-~ | +| CameraMode | CAMERA_ | ~camera-~ | +| GamepadButton | GAMEPAD_BUTTON_ | ~button-~ | +| GamepadAxis | GAMEPAD_AXIS_ | ~axis-~ | +| Gesture | GESTURE_ | ~gesture-~ | +| MouseCursor | MOUSE_CURSOR_ | ~cursor-~ | +| TextureFilter | TEXTURE_FILTER_ | ~filter-~ | +| PixelFormat | PIXELFORMAT_ | ~pixel-~ | + +Two of those are judgement rather than transcription, and both were checked +against the real member lists before being taken: + +- CameraProjection and CameraMode share raylib's CAMERA_ and do *not* share a + Flan prefix. They are two different questions asked of the same struct, and + ~:projection-perspective~ beside ~:camera-orbital~ says which one is being + answered where a shared ~camera-~ would have left the reader to work it out. +- GamepadButton and GamepadAxis take ~button-~ and ~axis-~ rather than a + shared ~gamepad-~ stem. The two are never in the same position, and the + shorter prefix is what keeps ~:button-left-face-up~ and + ~:axis-left-trigger~ readable — ~gamepad-~ on both would have said the part + the surrounding call already says. MouseButton keeping ~mouse-~ is the same + call from the other side: a mouse button and a pad button are different + sets, and the prefix is where a reader is told which. + +~log-~ rather than ~trace-~ for TraceLogLevel: the C names are LOG_, ~trace~ +is itself a member, and ~:log-warning~ is what the call reads as. + +** It is a reading choice, not a collision fix +Worth writing down because the next reader will otherwise assume it was +necessary. A keyword at a call site resolves against the expected type and +against nothing else (lib/check.ml, the ~enums~ table), so two enums may +share a member spelling with no consequence at all — ~:point~ at a +TextureFilter site could never have meant anything else. What the prefix buys +is the call site read on its own: ~(rl/set-texture-filter t :filter-bilinear)~ +says which closed set the name came out of, where ~:bilinear~ asked the reader +to know the signature first. docs/BUILT.md says so in the bindings section. + +** The round trip, actually run +~flan generate-c vendor/raylib~ is green against raylib-5.5.h with all eleven +third columns in place: 267 declarations, and every defstruct, hand-written +declare-c and mapped constant agrees. The check was confirmed non-vacuous by +breaking it on purpose — ~filter-trilinear~ spelled ~filter-trilinearr~ was +reported as "the header has no constant named TEXTURE_FILTER_TRILINEARR", +which is the prefix being stripped and reapplied rather than a name passing +unexamined. + +The three ~constant~ exception lines are keyed on the member's full Flan +spelling, so they moved with it: ~Gesture/gesture-double-tap~, +~PixelFormat/pixel-compressed-astc-4x4-rgba~ and its 8x8 twin. + +test/test_flan.ml pins one member of each of the eleven against the C name +the rule reaches, read out of the real vendor/raylib/bindings, plus the claim +that every mapped enum declares a prefix at all. + +** sand.flan, and the alias that is standing in for it — author's to remove +sand.flan line 121 is ~(rl/set-trace-log-level :warning)~, and the file is +the author's live WIP, so this lane did not touch it. The default suite +compiles sand.flan (test_session evaluates it whole), so the rename would +have left that red. + +Instead TraceLogLevel carries ~warning 4~ beside ~log-warning 4~ — a defenum +allows the same value twice — with ~constant TraceLogLevel/warning +LOG_WARNING~ in ~bindings~ so the header check still reaches it. It is the +one member in the package that does not carry its enum's prefix, and it +exists only for that one call. + +To remove it, three edits together: +1. sand.flan:121 → ~(rl/set-trace-log-level :log-warning)~ +2. vendor/raylib/raylib.flan — delete ~warning 4~ from the TraceLogLevel + defenum, and the paragraph above it that explains the alias +3. vendor/raylib/bindings — delete the ~constant TraceLogLevel/warning~ line + and its comment diff --git a/NEXT.md b/NEXT.md index eae09e3..aeded27 100644 --- a/NEXT.md +++ b/NEXT.md @@ -766,7 +766,7 @@ why they are here and not in a binding list. 2. ~~**An enum-typed `defstruct` field is refused by the layout check.**~~ **Closed.** The layout check now accepts an enum where the header says `int`, symmetrically, and still refuses anything that is not four bytes. `Camera3D.projection` is a `CameraProjection` again and the - `rl/camera-projection` helper is gone; `.projection :perspective` resolves at the construction + `rl/camera-projection` helper is gone; `.projection :projection-perspective` resolves at the construction site, so the keyword half of the problem went away with it. See docs/BUILT.md. 3. ~~**The header check does not reach `defconst` or `defenum`.**~~ **Closed.** It reaches both. diff --git a/docs/BUILT.md b/docs/BUILT.md index bc4af64..65287e6 100644 --- a/docs/BUILT.md +++ b/docs/BUILT.md @@ -35,7 +35,7 @@ only a regression test if the sequence is byte-identical on native and wasm32 (p the state. This is what the bitwise operators were added for. **Enums and keywords.** `(defenum Name [member value? ...])` gives a type that is an `i32` at run time and its own type -in the checker, so `:space` at a call site resolves against the parameter's enum and a typo is an error there rather +in the checker, so `:key-space` at a call site resolves against the parameter's enum and a typo is an error there rather than a wrong number later. A keyword means nothing where no enum is expected — there is no keyword type to fall back on. A member's value may be left out, and then it is the one above it plus one, starting at 0 — C's rule, because these enums are as often a transcription of a header as they are original. A value written twice is an alias and is allowed; @@ -121,7 +121,7 @@ that calls an existing binding is unaffected. 34 51 68`, four separate bytes — a `Color` is *not* the little-endian reading of the packed integer, so an identity would have passed a weaker test. That case is in the acceptance table, skipped if `libraylib` is not installed. -The bindings are 171 calls across thirteen structs: window, keyboard and mouse; drawing (rectangles, circles, lines, triangles, rings, ellipses, text); the eleven `collision-*` predicates; textures; the Image family; `Camera2D`; `RenderTexture2D`; the whole audio surface (device, `Wave`, `Sound`, `Music`); fonts and glyphs; and gamepads, touch and gestures — plus the `Key`, `MouseButton`, `TraceLogLevel`, `GamepadButton`, `GamepadAxis` and `Gesture` enums, raylib's own named colour palette, and the `FLAG_` window hints. Adding one is a single `declare-c` line; there is no C to write. +The bindings are 171 calls across thirteen structs: window, keyboard and mouse; drawing (rectangles, circles, lines, triangles, rings, ellipses, text); the eleven `collision-*` predicates; textures; the Image family; `Camera2D`; `RenderTexture2D`; the whole audio surface (device, `Wave`, `Sound`, `Music`); fonts and glyphs; and gamepads, touch and gestures — plus eleven enums — `Key`, `MouseButton`, `TraceLogLevel`, `CameraProjection`, `CameraMode`, `GamepadButton`, `GamepadAxis`, `Gesture`, `MouseCursor`, `TextureFilter` and `PixelFormat` — raylib's own named colour palette, and the `FLAG_` window hints. Every one of the eleven carries a Flan-side prefix on its members, so a call site reads `:key-r`, `:filter-bilinear`, `:axis-left-trigger`; see the `bindings` section below for why that is a reading choice and not a collision fix. Adding a call is a single `declare-c` line; there is no C to write. Two things the ported examples in `examples/` wanted and could not have, both refused for reasons that are right. `GetGamepadName` returns a `char *` into raylib's static storage: *the return type of get-gamepad-name is a string, and a string only crosses as a parameter — a C function that* returns *one returns something Flan has no owner for*. And an enum parameter cannot be indexed — `GetGamepadAxisMovement` takes a `GamepadAxis`, a loop variable is an `i32`, *expected rl/GamepadAxis, found i32*, and a second `declare-c` of the same symbol with an `i32` face is refused too: *one declare-c per C function, and another Flan name for it is a defn* — which cannot help, because a wrapper renames and does not retype. The caller spells the loop as a `cond` over the members it knows. @@ -376,7 +376,7 @@ a `defconst` or a `defenum` member — and **a wrong flag bit or a wrong enum member is completely silent.** No link error, no type error; a window that does not open, or a key that never fires. That is the class the header read exists to catch and the class hardest to see by reading, and raylib's package carries -sixteen `ConfigFlags` bits and eight enums that were all transcribed by hand. +sixteen `ConfigFlags` bits and eleven enums that were all transcribed by hand. **A Flan constant has no C spelling stored anywhere, so one has to be built.** A function never needs this: `declare-c` keeps the C symbol verbatim, so the @@ -386,11 +386,30 @@ has no declaration to keep it in. So the rule is uppercase-and-underscore — *prefix*, which is nowhere in the Flan name, is declared in `bindings`: ``` -enum Key KEY_ -const flag- FLAG_ -constant Gesture/double-tap GESTURE_DOUBLETAP +enum Key KEY_ key- +const flag- FLAG_ +constant Gesture/gesture-double-tap GESTURE_DOUBLETAP ``` +An `enum` line's third column is the prefix the members carry on the *Flan* +side. It is stripped before the C prefix is applied, so `key-r` checks against +`KEY_R` and not `KEY_KEY_R`, and a member that does not carry the declared +prefix is reported rather than checked under a guessed name. All eleven of +raylib's enums declare one — `key-`, `mouse-`, `log-`, `projection-`, +`camera-`, `button-`, `axis-`, `gesture-`, `cursor-`, `filter-`, `pixel-` — +and the uniformity is the point: two prefixed enums out of eleven was the +inconsistency, not the prefix. + +**The prefix is a reading choice and not a collision fix.** A keyword resolves +against the expected type and against nothing else, so two enums may share a +member spelling with no consequence at all — a bare `:point` at a +`TextureFilter` site could never have resolved anywhere else, whatever else in +the package spelled a member that way. What the prefix buys is the call +site read on its own — `(rl/set-texture-filter t :filter-bilinear)` says which +closed set the name came out of, where `:bilinear` asked the reader to know the +signature first. A future reader should not infer that the names had to be +disambiguated; they did not. + **Nothing goes quiet, in either direction, and that is most of the design.** A name the rule builds and the header does not have is *reported*, because a mapping that silently matched nothing would read as coverage and provide none @@ -441,10 +460,10 @@ are four, every field after it moves, and it reads as plausible numbers rather than as a link error. An enum against an `i16` or an `i64` is a real disagreement and stays one. -What it buys is at the construction site. `.projection :perspective` resolves -against the enum's members and a typo is a compile error there — a keyword -resolves only where an enum type is expected, so an `i32` field would have -taken any number at all. Fixing the layout check is therefore the whole of that +What it buys is at the construction site. `.projection :projection-perspective` +resolves against the enum's members and a typo is a compile error there — a +keyword resolves only where an enum type is expected, so an `i32` field would +have taken any number at all. Fixing the layout check is therefore the whole of that second problem for this case: make the field legal and the keyword follows. ### The bindings are committed now — `generated.flan`, `bindings`, `flan generate-c` diff --git a/examples/core-3d-picking.flan b/examples/core-3d-picking.flan index 4d125b7..ca97bc8 100644 --- a/examples/core-3d-picking.flan +++ b/examples/core-3d-picking.flan @@ -75,7 +75,7 @@ .target (rl/Vector3 {.x 0.0 .y 0.0 .z 0.0}) .up (rl/Vector3 {.x 0.0 .y 1.0 .z 0.0}) .fovy 45.0 - .projection :perspective})) + .projection :projection-perspective})) (set cube-position (rl/Vector3 {.x 0.0 .y 1.0 .z 0.0})) (set cube-size (rl/Vector3 {.x 2.0 .y 2.0 .z 2.0})) @@ -95,7 +95,7 @@ ;; Update. The first-person controls only run while the cursor is ;; captured, which is what the right button toggles — otherwise the mouse ;; could not be used to aim at anything. - (when (rl/cursor-hidden?) (rl/update-camera (addr camera) :first-person)) + (when (rl/cursor-hidden?) (rl/update-camera (addr camera) :camera-first-person)) (when (rl/mouse-button-pressed? :mouse-right) (if (rl/cursor-hidden?) (rl/enable-cursor) (rl/disable-cursor))) diff --git a/examples/core-input-gamepad.flan b/examples/core-input-gamepad.flan index 474167a..bee4bda 100644 --- a/examples/core-input-gamepad.flan +++ b/examples/core-input-gamepad.flan @@ -120,35 +120,35 @@ 0.5 16 rl/darkgray)) (defn draw-pad-buttons [] () - (when (rl/gamepad-button-down? gamepad :middle-left) + (when (rl/gamepad-button-down? gamepad :button-middle-left) (rl/draw-circle 365 170 10.0 rl/red)) - (when (rl/gamepad-button-down? gamepad :middle) + (when (rl/gamepad-button-down? gamepad :button-middle) (rl/draw-circle 405 170 10.0 rl/green)) - (when (rl/gamepad-button-down? gamepad :middle-right) + (when (rl/gamepad-button-down? gamepad :button-middle-right) (rl/draw-circle 445 170 10.0 rl/blue)) - (when (rl/gamepad-button-down? gamepad :right-face-left) + (when (rl/gamepad-button-down? gamepad :button-right-face-left) (rl/draw-circle 516 191 15.0 rl/gold)) - (when (rl/gamepad-button-down? gamepad :right-face-down) + (when (rl/gamepad-button-down? gamepad :button-right-face-down) (rl/draw-circle 551 227 15.0 rl/blue)) - (when (rl/gamepad-button-down? gamepad :right-face-right) + (when (rl/gamepad-button-down? gamepad :button-right-face-right) (rl/draw-circle 587 191 15.0 rl/green)) - (when (rl/gamepad-button-down? gamepad :right-face-up) + (when (rl/gamepad-button-down? gamepad :button-right-face-up) (rl/draw-circle 551 155 15.0 rl/red)) - (when (rl/gamepad-button-down? gamepad :left-face-up) + (when (rl/gamepad-button-down? gamepad :button-left-face-up) (rl/draw-rectangle 247 147 24 29 rl/red)) - (when (rl/gamepad-button-down? gamepad :left-face-down) + (when (rl/gamepad-button-down? gamepad :button-left-face-down) (rl/draw-rectangle 247 201 24 30 rl/red)) - (when (rl/gamepad-button-down? gamepad :left-face-left) + (when (rl/gamepad-button-down? gamepad :button-left-face-left) (rl/draw-rectangle 217 176 30 25 rl/red)) - (when (rl/gamepad-button-down? gamepad :left-face-right) + (when (rl/gamepad-button-down? gamepad :button-left-face-right) (rl/draw-rectangle 271 176 30 25 rl/red)) - (when (rl/gamepad-button-down? gamepad :left-trigger-1) + (when (rl/gamepad-button-down? gamepad :button-left-trigger-1) (rl/draw-rectangle-rounded (rl/Rectangle {.x 215.0 .y 98.0 .width 100.0 .height 10.0}) 0.5 16 rl/red)) - (when (rl/gamepad-button-down? gamepad :right-trigger-1) + (when (rl/gamepad-button-down? gamepad :button-right-trigger-1) (rl/draw-rectangle-rounded (rl/Rectangle {.x 495.0 .y 98.0 .width 100.0 .height 10.0}) 0.5 16 rl/red))) @@ -197,26 +197,26 @@ (+ x (d/draw-int gamepad x 10 10 rl/black)) 10 10 rl/black)) - (let [lx (deadzone (rl/get-gamepad-axis-movement gamepad :left-x) + (let [lx (deadzone (rl/get-gamepad-axis-movement gamepad :axis-left-x) stick-deadzone) - ly (deadzone (rl/get-gamepad-axis-movement gamepad :left-y) + ly (deadzone (rl/get-gamepad-axis-movement gamepad :axis-left-y) stick-deadzone) - rx (deadzone (rl/get-gamepad-axis-movement gamepad :right-x) + rx (deadzone (rl/get-gamepad-axis-movement gamepad :axis-right-x) stick-deadzone) - ry (deadzone (rl/get-gamepad-axis-movement gamepad :right-y) + ry (deadzone (rl/get-gamepad-axis-movement gamepad :axis-right-y) stick-deadzone) lt (trigger-deadzoned - (rl/get-gamepad-axis-movement gamepad :left-trigger)) + (rl/get-gamepad-axis-movement gamepad :axis-left-trigger)) rt (trigger-deadzoned - (rl/get-gamepad-axis-movement gamepad :right-trigger))] + (rl/get-gamepad-axis-movement gamepad :axis-right-trigger))] (draw-pad-background) (draw-pad-buttons) (draw-stick 345 260 lx ly - (rl/gamepad-button-down? gamepad :left-thumb)) + (rl/gamepad-button-down? gamepad :button-left-thumb)) (draw-stick 465 260 rx ry - (rl/gamepad-button-down? gamepad :right-thumb)) + (rl/gamepad-button-down? gamepad :button-right-thumb)) ;; The triggers as bars filling upward from a grey track. The +1 ;; and the halving turn raylib's [-1, 1] into [0, 1]. diff --git a/examples/core-input-gestures-testbed.flan b/examples/core-input-gestures-testbed.flan index 136b6ab..540bbf0 100644 --- a/examples/core-input-gestures-testbed.flan +++ b/examples/core-input-gestures-testbed.flan @@ -28,9 +28,9 @@ ;;;; named, and it is at the site. The rule was "an integer must not arrive ;;;; silently", not "an integer is dangerous". ;;;; -;;;; The `!= 4` stays a keyword comparison, `(not (= g :hold))`. That one was -;;;; never a range test; it is a single member, and the C's 4 is a magic -;;;; number the keyword reads better than. +;;;; The `!= 4` stays a keyword comparison, `(not (= g :gesture-hold))`. That +;;;; one was never a range test; it is a single member, and the C's 4 is a +;;;; magic number the keyword reads better than. ;;;; ;;;; **No sin or cos.** The prelude has sqrt-f32 — one `declare` over libm, ;;;; with a comment explaining why it is not a builtin — and nothing else @@ -99,37 +99,37 @@ ;; Two orderings these impose, both of them the C's as well. A pinch is above ;; 255 and therefore above 15, so swipe? has to be asked after the pinches -;; rather than before; and tapish? admits :none, which is 0, so it belongs -;; under a :none guard. The C's switch over single members hides both; a range -;; test cannot. +;; rather than before; and tapish? admits :gesture-none, which is 0, so it +;; belongs under a :gesture-none guard. The C's switch over single members +;; hides both; a range test cannot. (defn gesture-name [g rl/Gesture] string (cond - (= g :none) "None" - (= g :tap) "Tap" - (= g :double-tap) "Double Tap" - (= g :hold) "Hold" - (= g :drag) "Drag" - (= g :swipe-right) "Swipe Right" - (= g :swipe-left) "Swipe Left" - (= g :swipe-up) "Swipe Up" - (= g :swipe-down) "Swipe Down" - (= g :pinch-in) "Pinch In" - (= g :pinch-out) "Pinch Out" - :else "Unknown")) + (= g :gesture-none) "None" + (= g :gesture-tap) "Tap" + (= g :gesture-double-tap) "Double Tap" + (= g :gesture-hold) "Hold" + (= g :gesture-drag) "Drag" + (= g :gesture-swipe-right) "Swipe Right" + (= g :gesture-swipe-left) "Swipe Left" + (= g :gesture-swipe-up) "Swipe Up" + (= g :gesture-swipe-down) "Swipe Down" + (= g :gesture-pinch-in) "Pinch In" + (= g :gesture-pinch-out) "Pinch Out" + :else "Unknown")) (defn gesture-color-of [g rl/Gesture] rl/Color (cond - (= g :tap) rl/blue - (= g :double-tap) rl/skyblue - (= g :drag) rl/lime + (= g :gesture-tap) rl/blue + (= g :gesture-double-tap) rl/skyblue + (= g :gesture-drag) rl/lime ;; The two pinches are above 255 and so are above 15 as well: swipe? is a ;; range test and has to be asked after them, not before. The C gets this ;; for free by being a switch over single members. - (= g :pinch-in) rl/violet - (= g :pinch-out) rl/orange - (swipe? g) rl/red - :else rl/black)) + (= g :gesture-pinch-in) rl/violet + (= g :gesture-pinch-out) rl/orange + (swipe? g) rl/red + :else rl/black)) ;; ── The log ───────────────────────────────────────────────────────── @@ -140,10 +140,10 @@ ;; 3 hides repeated events and hides hold (defn should-log? [g rl/Gesture] bool (cond - (= g :none) false - (= log-mode 3) (or (and (not (= g :hold)) (not (= g previous-gesture))) + (= g :gesture-none) false + (= log-mode 3) (or (and (not (= g :gesture-hold)) (not (= g previous-gesture))) (tapish? g)) - (= log-mode 2) (not (= g :hold)) + (= log-mode 2) (not (= g :gesture-hold)) (= log-mode 1) (not (= g previous-gesture)) :else true)) @@ -171,26 +171,26 @@ (rl/draw-text "Swipe Tap Pinch Touch" (+ last-x 17) (- last-y 18) 10 rl/black) - (swipe-box (+ last-x 20) last-y :swipe-up) - (swipe-box last-x (+ last-y 20) :swipe-left) - (swipe-box (+ last-x 40) (+ last-y 20) :swipe-right) - (swipe-box (+ last-x 20) (+ last-y 40) :swipe-down) + (swipe-box (+ last-x 20) last-y :gesture-swipe-up) + (swipe-box last-x (+ last-y 20) :gesture-swipe-left) + (swipe-box (+ last-x 40) (+ last-y 20) :gesture-swipe-right) + (swipe-box (+ last-x 20) (+ last-y 40) :gesture-swipe-down) (rl/draw-circle (+ last-x 80) (+ last-y 16) 10.0 - (if (= last-gesture :tap) rl/blue rl/lightgray)) + (if (= last-gesture :gesture-tap) rl/blue rl/lightgray)) ;; segments 0 lets raylib pick the count from the radius. (rl/draw-ring (rl/Vector2 {.x (f32 (+ last-x 103)) .y (f32 (+ last-y 16))}) 6.0 11.0 0.0 360.0 0 - (if (= last-gesture :drag) rl/lime rl/lightgray)) + (if (= last-gesture :gesture-drag) rl/lime rl/lightgray)) (rl/draw-circle (+ last-x 80) (+ last-y 43) 10.0 - (if (= last-gesture :double-tap) rl/skyblue rl/lightgray)) + (if (= last-gesture :gesture-double-tap) rl/skyblue rl/lightgray)) (rl/draw-circle (+ last-x 103) (+ last-y 43) 10.0 - (if (= last-gesture :double-tap) rl/skyblue rl/lightgray)) + (if (= last-gesture :gesture-double-tap) rl/skyblue rl/lightgray)) ;; The two pairs of arrowheads, pointing outward for pinch-out and inward ;; for pinch-in. Counter-clockwise winding, or raylib culls them. - (let [out-c (if (= last-gesture :pinch-out) rl/orange rl/lightgray) - in-c (if (= last-gesture :pinch-in) rl/violet rl/lightgray)] + (let [out-c (if (= last-gesture :gesture-pinch-out) rl/orange rl/lightgray) + in-c (if (= last-gesture :gesture-pinch-in) rl/violet rl/lightgray)] (rl/draw-triangle (rl/Vector2 {.x (f32 (+ last-x 122)) .y (f32 (+ last-y 16))}) (rl/Vector2 {.x (f32 (+ last-x 137)) .y (f32 (+ last-y 26))}) (rl/Vector2 {.x (f32 (+ last-x 137)) .y (f32 (+ last-y 6))}) @@ -294,7 +294,7 @@ ;; The C filters hold out of the "last gesture" display, because hold ;; repeats every frame and would drown everything else. - (when (and (and (not (= g :none)) (not (= g :hold))) + (when (and (and (not (= g :gesture-none)) (not (= g :gesture-hold))) (not (= g previous-gesture))) (set last-gesture g)) @@ -321,7 +321,7 @@ (cond (pinch? g) (set current-angle (rl/get-gesture-pinch-angle)) (swipe? g) (set current-angle (rl/get-gesture-drag-angle)) - (not (= g :none)) (set current-angle 0.0) + (not (= g :gesture-none)) (set current-angle 0.0) :else (do)) (dotimes [i touch-count] @@ -345,7 +345,7 @@ ;; The pointer itself: every live touch, or the mouse when there is no ;; touchscreen. The halo is the gesture colour faded, which is what ;; `fade` was bound for. - (unless (= g :none) + (unless (= g :gesture-none) (if (> touch-count 0) (do (dotimes [i touch-count] @@ -356,7 +356,7 @@ ;; out, which is the C's only use of the raw 512. (when (= touch-count 2) (rl/draw-line-ex (at touch-positions 0) (at touch-positions 1) - (if (= g :pinch-out) 8.0 12.0) gesture-color))) + (if (= g :gesture-pinch-out) 8.0 12.0) gesture-color))) (let [m (rl/get-mouse-position)] (rl/draw-circle-v m 35.0 (rl/fade gesture-color 0.5)) (rl/draw-circle-v m 5.0 gesture-color))))))))) diff --git a/examples/core-input-gestures.flan b/examples/core-input-gestures.flan index 26c69c0..282c8c6 100644 --- a/examples/core-input-gestures.flan +++ b/examples/core-input-gestures.flan @@ -13,9 +13,9 @@ ;;;; ;;;; The C's `switch (currentGesture)` over the ten gesture values is a `cond` ;;;; of keyword equalities. `get-gesture-detected` answers an `rl/Gesture` and -;;;; `(= g :tap)` compares against a member by name, checked at compile time — -;;;; so a typo here is an error and the C's `default: break` has nothing to -;;;; catch. +;;;; `(= g :gesture-tap)` compares against a member by name, checked at +;;;; compile time — so a typo here is an error and the C's `default: break` +;;;; has nothing to catch. ;;;; ;;;; A slot that has not been written yet holds a zero-length string, because a ;;;; `defonce` with no initialiser is all-bytes-zero and a string is ptr+len — @@ -40,17 +40,17 @@ ;; through the C's switch without a TextCopy leaves in the slot. (defn gesture-name [g rl/Gesture] string (cond - (= g :tap) "GESTURE TAP" - (= g :double-tap) "GESTURE DOUBLETAP" - (= g :hold) "GESTURE HOLD" - (= g :drag) "GESTURE DRAG" - (= g :swipe-right) "GESTURE SWIPE RIGHT" - (= g :swipe-left) "GESTURE SWIPE LEFT" - (= g :swipe-up) "GESTURE SWIPE UP" - (= g :swipe-down) "GESTURE SWIPE DOWN" - (= g :pinch-in) "GESTURE PINCH IN" - (= g :pinch-out) "GESTURE PINCH OUT" - :else "")) + (= g :gesture-tap) "GESTURE TAP" + (= g :gesture-double-tap) "GESTURE DOUBLETAP" + (= g :gesture-hold) "GESTURE HOLD" + (= g :gesture-drag) "GESTURE DRAG" + (= g :gesture-swipe-right) "GESTURE SWIPE RIGHT" + (= g :gesture-swipe-left) "GESTURE SWIPE LEFT" + (= g :gesture-swipe-up) "GESTURE SWIPE UP" + (= g :gesture-swipe-down) "GESTURE SWIPE DOWN" + (= g :gesture-pinch-in) "GESTURE PINCH IN" + (= g :gesture-pinch-out) "GESTURE PINCH OUT" + :else "")) (defn main [] () (rl/init-window screen-width screen-height @@ -69,7 +69,7 @@ (let [touch (rl/get-touch-position 0)] (when (and (rl/collision-point-rec? touch touch-area) - (not (= current-gesture :none)) + (not (= current-gesture :gesture-none)) (not (= current-gesture last-gesture))) (set (at gesture-log gestures-count) (gesture-name current-gesture)) (set gestures-count (+ gestures-count 1)) @@ -104,5 +104,5 @@ (rl/draw-rectangle-lines 10 29 200 (- screen-height 50) rl/gray) (rl/draw-text "DETECTED GESTURES" 50 15 10 rl/gray) - (unless (= current-gesture :none) + (unless (= current-gesture :gesture-none) (rl/draw-circle-v touch 30.0 rl/maroon))))))) diff --git a/examples/core-world-screen.flan b/examples/core-world-screen.flan index 8a2c717..3f795c5 100644 --- a/examples/core-world-screen.flan +++ b/examples/core-world-screen.flan @@ -25,9 +25,9 @@ ;;;; camera looking from the wrong place is a picture, not a number. The same ;;;; is true of Vector3's own x, y and z. Only the screen catches those. ;;;; -;;;; update-camera in :third-person mode also takes the mouse, which is why -;;;; the C calls DisableCursor: the cursor is locked to the window and its -;;;; movement becomes camera rotation rather than a pointer. disable-cursor +;;;; update-camera in :camera-third-person mode also takes the mouse, which +;;;; is why the C calls DisableCursor: the cursor is locked to the window and +;;;; its movement becomes camera rotation rather than a pointer. disable-cursor ;;;; comes from the generated half — it is called once, before the loop. ;;;; ;;;; The C's two TextFormats go through examples/digits.flan, as in the other @@ -56,7 +56,7 @@ .target (rl/Vector3 {.x 0.0 .y 0.0 .z 0.0}) .up (rl/Vector3 {.x 0.0 .y 1.0 .z 0.0}) .fovy 45.0 - .projection :perspective})) + .projection :projection-perspective})) (set cube (rl/Vector3 {.x 0.0 .y 0.0 .z 0.0})) @@ -68,7 +68,7 @@ (until (rl/window-should-close?) ;; Update. The camera is passed by address because update-camera writes ;; to it — a global is an assignable place, so it has an address to take. - (rl/update-camera (addr camera) :third-person) + (rl/update-camera (addr camera) :camera-third-person) ;; Where the point 2.5 units above the cube lands on the screen. This is ;; the whole example: the same transform raylib is about to draw with, diff --git a/examples/models-box-collisions.flan b/examples/models-box-collisions.flan index 4910a8c..165af22 100644 --- a/examples/models-box-collisions.flan +++ b/examples/models-box-collisions.flan @@ -76,7 +76,7 @@ .target (rl/Vector3 {.x 0.0 .y 0.0 .z 0.0}) .up (rl/Vector3 {.x 0.0 .y 1.0 .z 0.0}) .fovy 45.0 - .projection :perspective})) + .projection :projection-perspective})) (set player-position (rl/Vector3 {.x 0.0 .y 1.0 .z 2.0})) (set player-size (rl/Vector3 {.x 1.0 .y 2.0 .z 1.0})) diff --git a/examples/text-codepoints-loading.flan b/examples/text-codepoints-loading.flan index 856db04..26a509d 100644 --- a/examples/text-codepoints-loading.flan +++ b/examples/text-codepoints-loading.flan @@ -204,8 +204,8 @@ (defer (rl/unload-font font)) ;; Bilinear, so the 36-pixel atlas still reads when it is drawn at 48. The - ;; default is :point and the kana come out with stepped edges. - (rl/set-texture-filter (.texture font) :bilinear) + ;; default is :filter-point and the kana come out with stepped edges. + (rl/set-texture-filter (.texture font) :filter-bilinear) ;; Line spacing for the newlines the text contains. draw-text-ex honours it; ;; nothing else in this program does. diff --git a/examples/text-input-box.flan b/examples/text-input-box.flan index d5d3508..6a1ac28 100644 --- a/examples/text-input-box.flan +++ b/examples/text-input-box.flan @@ -81,7 +81,7 @@ (if mouse-on-text (do - (rl/set-mouse-cursor :ibeam) + (rl/set-mouse-cursor :cursor-ibeam) ;; Drain the character queue: more than one character can arrive in ;; a single frame — holding a key with the platform's repeat on is @@ -103,7 +103,7 @@ (when (rl/key-pressed? :key-backspace) (set letter-count (- letter-count 1)) (when (< letter-count 0) (set letter-count 0)))) - (rl/set-mouse-cursor :default)) + (rl/set-mouse-cursor :cursor-default)) ;; The blink phase only runs while the box has focus, so the underscore is ;; always visible on the frame the pointer arrives. diff --git a/examples/textures-fog-of-war.flan b/examples/textures-fog-of-war.flan index f5e5e5c..ac86c6d 100644 --- a/examples/textures-fog-of-war.flan +++ b/examples/textures-fog-of-war.flan @@ -5,15 +5,15 @@ ;;;; rather than a detail. The fog is drawn into a render texture one pixel ;;;; per tile — 25 by 15 — and then stretched to 800x450 on the way to the ;;;; screen, and the smooth edge between seen and unseen is entirely the -;;;; bilinear sampler doing the interpolation. With the default :point filter -;;;; the same program draws 32-pixel squares. +;;;; bilinear sampler doing the interpolation. With the default +;;;; :filter-point the same program draws 32-pixel squares. ;;;; ;;;; That is what needed adding: `TextureFilter`, a new defenum in ;;;; vendor/raylib/raylib.flan, with set-texture-filter moved from the ;;;; generated half to the hand-written one and mapped in `bindings` so its ;;;; six members are checked against raylib.h. The header says `int filter` ;;;; and there is nothing in an `int` to say that 1 is the interesting value; -;;;; `:bilinear` says it. +;;;; `:filter-bilinear` says it. ;;;; ;;;; The three other things it exercises, none of which needed a line: ;;;; @@ -91,7 +91,7 @@ (set fog-of-war (rl/load-render-texture tiles-x tiles-y)) (defer (rl/unload-render-texture fog-of-war)) - (rl/set-texture-filter (.texture fog-of-war) :bilinear) + (rl/set-texture-filter (.texture fog-of-war) :filter-bilinear) (rl/set-target-fps 60) diff --git a/examples/textures-image-processing.flan b/examples/textures-image-processing.flan index 9104fd8..bdd448e 100644 --- a/examples/textures-image-processing.flan +++ b/examples/textures-image-processing.flan @@ -179,7 +179,7 @@ ;; because making one needs the GL context init-window creates. The image ;; underneath it does not — nothing above this line touches the GPU. (set im-origin (make-source-image)) - (rl/image-format (addr im-origin) :uncompressed-r8g8b8a8) + (rl/image-format (addr im-origin) :pixel-uncompressed-r8g8b8a8) (set texture (rl/load-texture-from-image im-origin)) (set im-copy (rl/image-copy im-origin)) diff --git a/examples/textures-mouse-painting.flan b/examples/textures-mouse-painting.flan index d55553f..f3e0f33 100644 --- a/examples/textures-mouse-painting.flan +++ b/examples/textures-mouse-painting.flan @@ -153,7 +153,7 @@ ;; Paint. The gesture test is what makes the example work on a ;; touchscreen, where there is no mouse button to hold. (when (or (rl/mouse-button-down? :mouse-left) - (= (rl/get-gesture-detected) :drag)) + (= (rl/get-gesture-detected) :gesture-drag)) (rl/with-texture-mode target ;; Above y=50 is the palette strip, and a stroke there would paint ;; under the toolbar where it could never be seen. diff --git a/test/programs/raylib-audio.flan b/test/programs/raylib-audio.flan index ac60569..6be8658 100644 --- a/test/programs/raylib-audio.flan +++ b/test/programs/raylib-audio.flan @@ -125,7 +125,7 @@ (show-bool name (near? (frame-at w i) want))) (defn main [] i32 - (rl/set-trace-log-level :warning) + (rl/set-trace-log-level :log-warning) (load-pcm) ;; ── The wave, built by hand ───────────────────────────────────────── diff --git a/test/programs/raylib-ffi.flan b/test/programs/raylib-ffi.flan index a8de1c9..1c0fa34 100644 --- a/test/programs/raylib-ffi.flan +++ b/test/programs/raylib-ffi.flan @@ -76,7 +76,7 @@ (println (if (and (near? (.x v) x) (near? (.y v) y)) " ok" " bad"))) (defn main [] i32 - (rl/set-trace-log-level :warning) + (rl/set-trace-log-level :log-warning) ;; A Color is four bytes in RGBA order, so 0x11223344 is 17 34 51 68 and not ;; the little-endian reading of the packed integer. An identity would pass a diff --git a/test/programs/raylib-font.flan b/test/programs/raylib-font.flan index 0a8c8a6..49b1ecd 100644 --- a/test/programs/raylib-font.flan +++ b/test/programs/raylib-font.flan @@ -102,7 +102,7 @@ (println "")) (defn main [] i32 - (rl/set-trace-log-level :warning) + (rl/set-trace-log-level :log-warning) (build-glyphs) ;; The font. `texture` is a lie in every field but `id`, and the id is 1 for diff --git a/test/programs/raylib-image-processing.flan b/test/programs/raylib-image-processing.flan index b90baa7..c0b5513 100644 --- a/test/programs/raylib-image-processing.flan +++ b/test/programs/raylib-image-processing.flan @@ -116,7 +116,7 @@ ;; The example formats the original before anything else touches it, and ;; so does this: a filter run over a differently-formatted buffer is a ;; different filter. - (rl/image-format (addr src) :uncompressed-r8g8b8a8) + (rl/image-format (addr src) :pixel-uncompressed-r8g8b8a8) (probe "source" src) (run "none" src 0) diff --git a/test/programs/raylib-image.flan b/test/programs/raylib-image.flan index 82811a5..e09d880 100644 --- a/test/programs/raylib-image.flan +++ b/test/programs/raylib-image.flan @@ -60,7 +60,7 @@ (show-color name (rl/get-image-color i x y))) (defn main [] i32 - (rl/set-trace-log-level :warning) + (rl/set-trace-log-level :log-warning) ;; ── The layout, from a struct raylib built ────────────────────────── ;; diff --git a/test/test_flan.ml b/test/test_flan.ml index ac1b82c..101baa8 100644 --- a/test/test_flan.ml +++ b/test/test_flan.ml @@ -4106,6 +4106,59 @@ let () = | exception Loc.Error { Loc.dmsg = m; _ } -> contains m "nothing to check Foo against"); + (* The package's own file, and the round trip the prefix exists for: a Flan + keyword a program writes, and the C name the rule reaches from it. All + eleven of raylib's enums declare a Flan prefix now — the uniformity is + the claim, so one member of each is pinned rather than a sample. The C + side of each row was read off vendor/raylib/raylib-5.5.h; `flan + generate-c vendor/raylib` is what re-checks that against the header, and + this is what keeps the *spellings* from drifting between times somebody + runs it. + + The prefix is a reading choice and not a collision fix: a keyword + resolves against the expected type and nothing else, so :point at a + TextureFilter site was never ambiguous. What is pinned here is that the + bindings file still says so uniformly. *) + let rl = Cimport.read_config "../vendor/raylib/bindings" in + let c_name enum member = + match + ( List.assoc_opt enum rl.Cimport.enum_prefixes, + List.assoc_opt enum rl.Cimport.enum_flan_prefixes ) + with + | Some cp, Some fp -> + (match Cimport.strip_prefix fp member with + | Some stem -> Some (cp ^ Cimport.screaming stem) + | None -> None) + | _ -> None + in + List.iter + (fun (enum, member, cname) -> + check + (Printf.sprintf "%s/%s is %s" enum member cname) + (c_name enum member = Some cname)) + [ ("Key", "key-left-shift", "KEY_LEFT_SHIFT"); + ("MouseButton", "mouse-left", "MOUSE_BUTTON_LEFT"); + ("TraceLogLevel", "log-warning", "LOG_WARNING"); + ("CameraProjection", "projection-perspective", "CAMERA_PERSPECTIVE"); + ("CameraMode", "camera-third-person", "CAMERA_THIRD_PERSON"); + ("GamepadButton", "button-left-face-up", "GAMEPAD_BUTTON_LEFT_FACE_UP"); + ("GamepadAxis", "axis-left-trigger", "GAMEPAD_AXIS_LEFT_TRIGGER"); + ("Gesture", "gesture-pinch-out", "GESTURE_PINCH_OUT"); + ("MouseCursor", "cursor-resize-nesw", "MOUSE_CURSOR_RESIZE_NESW"); + ("TextureFilter", "filter-bilinear", "TEXTURE_FILTER_BILINEAR"); + ("PixelFormat", "pixel-uncompressed-r8g8b8a8", + "PIXELFORMAT_UNCOMPRESSED_R8G8B8A8") ]; + (* And the other half of the same claim: every enum the file maps declares + a Flan prefix. A twelfth enum added with two columns would otherwise + reintroduce the split this closed. `enum Foo -` is exempt and has to be + — a line that says the header has nothing to check cannot carry a third + column at all, which is pinned a few rows above. *) + check "every mapped raylib enum declares a Flan-side member prefix" + (List.for_all + (fun (e, cp) -> + String.equal cp "-" || List.mem_assoc e rl.Cimport.enum_flan_prefixes) + rl.Cimport.enum_prefixes); + (* A refused name is a name that exists and cannot be had — Zig's failDecl, which Load.refuse_hidden already implements for main. Nothing may be in both lists, or asking for a name that works would report that it does diff --git a/vendor/raylib/bindings b/vendor/raylib/bindings index a896d39..fa897c1 100644 --- a/vendor/raylib/bindings +++ b/vendor/raylib/bindings @@ -212,41 +212,53 @@ name ImageDrawTriangleStrip image-draw-triangle-strip-raw # skipped; a mapping that quietly matched nothing would read as coverage and # provide none. # -# An enum line's optional third column is a prefix the members carry on the -# *Flan* side. Key and MouseButton spell their members `key-r` and -# `mouse-left`, because the bare names collide — across the two enums and -# with a user's own — and without the column the rule above would double the -# prefix: KEY_KEY_R. The declared Flan prefix is stripped first and the C one -# applied to what is left, so `key-r` checks against KEY_R and `mouse-left` -# against MOUSE_BUTTON_LEFT. A member that does not carry the declared prefix -# is reported, not checked under a guessed name. +# An enum line's third column is a prefix the members carry on the *Flan* +# side, and all eleven now declare one. The declared Flan prefix is stripped +# first and the C one applied to what is left, so `key-r` checks against KEY_R +# rather than KEY_KEY_R, and `filter-point` against TEXTURE_FILTER_POINT. A +# member that does not carry the declared prefix is reported, not checked +# under a guessed name. +# +# The prefix is a READING choice and not a collision fix. A keyword at a call +# site resolves against the expected type and against nothing else, so two +# enums may share a member spelling with no consequence at all — `:point` in +# a TextureFilter position could never have meant anything else. What the +# prefix buys is the call site read on its own: `(rl/set-texture-filter t +# :filter-bilinear)` says which closed set the name came out of, where +# `:bilinear` asked the reader to know the signature. # # Every defenum needs a line, including one the header cannot check, which # says so with `-`. That is the same rule one level up: an enum nobody mapped # would be silently unchecked, which is the hole this closes. -enum Key KEY_ key- -enum MouseButton MOUSE_BUTTON_ mouse- -enum TraceLogLevel LOG_ -enum CameraProjection CAMERA_ -enum CameraMode CAMERA_ -enum GamepadButton GAMEPAD_BUTTON_ -enum GamepadAxis GAMEPAD_AXIS_ -enum Gesture GESTURE_ -enum MouseCursor MOUSE_CURSOR_ -enum TextureFilter TEXTURE_FILTER_ -enum PixelFormat PIXELFORMAT_ +enum Key KEY_ key- +enum MouseButton MOUSE_BUTTON_ mouse- +enum TraceLogLevel LOG_ log- +enum CameraProjection CAMERA_ projection- +enum CameraMode CAMERA_ camera- +enum GamepadButton GAMEPAD_BUTTON_ button- +enum GamepadAxis GAMEPAD_AXIS_ axis- +enum Gesture GESTURE_ gesture- +enum MouseCursor MOUSE_CURSOR_ cursor- +enum TextureFilter TEXTURE_FILTER_ filter- +enum PixelFormat PIXELFORMAT_ pixel- # raylib writes GESTURE_DOUBLETAP as one word where every other member of that # enum is underscored. This is the narrow exception and not a general escape # hatch: one name the prefix rule gets wrong, said once. -constant Gesture/double-tap GESTURE_DOUBLETAP +constant Gesture/gesture-double-tap GESTURE_DOUBLETAP + +# TraceLogLevel's members are `log-`, and `warning` beside `log-warning` is +# the one member that is not. It is an alias kept for sand.flan's one call, +# which this lane is not allowed to edit; both it and this line go when that +# call becomes `:log-warning`. +constant TraceLogLevel/warning LOG_WARNING # And the second such pair, for the same kind of reason. The rule uppercases # the Flan member name, and raylib spells the two ASTC block sizes with a # lowercase `x` — PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA — where every other # letter in that enum is upper. Two names the rule gets wrong, said once each. -constant PixelFormat/compressed-astc-4x4-rgba PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA -constant PixelFormat/compressed-astc-8x8-rgba PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA +constant PixelFormat/pixel-compressed-astc-4x4-rgba PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA +constant PixelFormat/pixel-compressed-astc-8x8-rgba PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA # The 16 ConfigFlags bits. These are the values sand.flan and the ported # window-flags example pass to set-config-flags, set-window-state and diff --git a/vendor/raylib/raylib.flan b/vendor/raylib/raylib.flan index 027ef15..ec29ff9 100644 --- a/vendor/raylib/raylib.flan +++ b/vendor/raylib/raylib.flan @@ -71,9 +71,14 @@ ;; 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. ;; -;; Every member carries the `key-` prefix, and MouseButton's carry `mouse-`, -;; because the bare names collide — :left would mean a key here and a button -;; there, and a plain word like :space is one a user's own enum wants too. +;; Every member carries the `key-` prefix, as every member of every other +;; enum in this file carries its own — the prefix is uniform across all +;; eleven. It is there to be READ and not to avoid a clash: a keyword +;; resolves against the expected type and nothing else, so :left could +;; already mean a key here and a button there with no trouble at all. What it +;; buys is a call site that says which closed set the name came from without +;; the reader having to know the signature. +;; ;; The prefix is declared in `bindings` (the enum line's third column), which ;; is what keeps :key-r checking against KEY_R rather than KEY_KEY_R. (defenum Key @@ -92,13 +97,27 @@ ;; key closes the window", which is the only thing that ever passes it. key-null 0]) -;; `mouse-` and not `button-`: gamepads have buttons too. +;; `mouse-` and not `button-`, which GamepadButton has: a mouse button and a +;; pad button are different sets and the prefix is where a reader is told +;; which one a keyword came out of. (defenum MouseButton [mouse-left 0 mouse-right 1 mouse-middle 2 mouse-side 3 mouse-extra 4 mouse-forward 5 mouse-back 6]) +;; `log-` rather than `trace-`: the enum is TraceLogLevel but the C names are +;; LOG_, `trace` is itself a member, and :log-warning is what the call reads +;; as. +;; +;; `warning` beside `log-warning` is the same value twice, which a defenum +;; allows, and it is the one member in this file that does not carry its +;; enum's prefix. It is an alias for sand.flan's single +;; `(rl/set-trace-log-level :warning)` — the file this lane was told not to +;; touch — and goes, with its `constant` line in `bindings`, when that call +;; is respelled. (defenum TraceLogLevel - [all 0 trace 1 debug 2 info 3 warning 4 error 5 fatal 6 none 7]) + [log-all 0 log-trace 1 log-debug 2 log-info 3 log-warning 4 + log-error 5 log-fatal 6 log-none 7 + warning 4]) ;; ── Window ────────────────────────────────────────────────────────── @@ -238,16 +257,19 @@ ;; The shape the pointer takes. raylib's SetMouseCursor says `int` and means ;; one of these eleven, so the Flan face is the enum for the same reason ;; set-exit-key takes a Key: the call is made every frame from a hover test, -;; and `(rl/set-mouse-cursor :ibeam)` is checked against the members where an -;; i32 would take any number at all — including the one off-by-one that picks -;; the arrow instead of the I-beam and looks like nothing at all went wrong. +;; and `(rl/set-mouse-cursor :cursor-ibeam)` is checked against the members +;; where an i32 would take any number at all — including the one off-by-one +;; that picks the arrow instead of the I-beam and looks like nothing at all +;; went wrong. ;; ;; All eleven are here and not a subset, unlike Key: the enum is closed and ;; eleven members is the whole of it. (defenum MouseCursor - [default 0 arrow 1 ibeam 2 crosshair 3 pointing-hand 4 - resize-ew 5 resize-ns 6 resize-nwse 7 resize-nesw 8 resize-all 9 - not-allowed 10]) + [cursor-default 0 cursor-arrow 1 cursor-ibeam 2 cursor-crosshair 3 + cursor-pointing-hand 4 + cursor-resize-ew 5 cursor-resize-ns 6 cursor-resize-nwse 7 + cursor-resize-nesw 8 cursor-resize-all 9 + cursor-not-allowed 10]) (declare-c set-mouse-cursor [cursor MouseCursor] "SetMouseCursor") @@ -403,15 +425,21 @@ ;; a struct field exactly as it does in a parameter, and the layout check ;; knows that, so it accepts an enum where the header says `int` and still ;; refuses an `f64` where the header says `float`. What it buys is at the -;; construction site — `.projection :perspective` resolves against the members -;; below and a typo is a compile error there, where an i32 field would have -;; taken any number at all. -(defenum CameraProjection [perspective 0 orthographic 1]) +;; construction site — `.projection :projection-perspective` resolves against +;; the members below and a typo is a compile error there, where an i32 field +;; would have taken any number at all. +;; +;; `projection-` and not `camera-`, though both map onto raylib's CAMERA_: +;; the two enums are different questions asked of the same struct, and +;; :projection-perspective beside :camera-orbital says which one is being +;; answered where a shared prefix would not. +(defenum CameraProjection [projection-perspective 0 projection-orthographic 1]) -;; UpdateCamera's mode. :custom means it does nothing and the program moves -;; the camera itself. +;; UpdateCamera's mode. :camera-custom means it does nothing and the program +;; moves the camera itself. (defenum CameraMode - [custom 0 free 1 orbital 2 first-person 3 third-person 4]) + [camera-custom 0 camera-free 1 camera-orbital 2 camera-first-person 3 + camera-third-person 4]) (defstruct Camera3D [position Vector3 target Vector3 up Vector3 fovy f32 projection CameraProjection]) @@ -641,16 +669,16 @@ ;; The value of the enum face here is not a typo caught at the call site so ;; much as a *readable* one: the fog-of-war example renders its fog into a ;; 25x15 render texture and scales it to 800x450, and the entire visual point -;; of the example is that `:bilinear` smooths the tile edges where the -;; default `:point` would show 32-pixel squares. A bare `1` in that call says -;; nothing; the member name says the whole thing. +;; of the example is that `:filter-bilinear` smooths the tile edges where the +;; default `:filter-point` would show 32-pixel squares. A bare `1` in that +;; call says nothing; the member name says the whole thing. ;; ;; TEXTURE_FILTER_ANISOTROPIC_* are the mipmapped modes and need a texture ;; with mipmaps generated, which nothing here makes — they are listed because ;; the enum is closed, not because anything calls them. (defenum TextureFilter - [point 0 bilinear 1 trilinear 2 - anisotropic-4x 3 anisotropic-8x 4 anisotropic-16x 5]) + [filter-point 0 filter-bilinear 1 filter-trilinear 2 + filter-anisotropic-4x 3 filter-anisotropic-8x 4 filter-anisotropic-16x 5]) (declare-c set-texture-filter [texture Texture2D filter TextureFilter] @@ -719,36 +747,36 @@ ;; raylib's own ImageFormat only moves between the uncompressed formats — so ;; the compressed half is for reading rather than for asking. ;; -;; `uncompressed-r8g8b8a8` is 7, the one GenImageColor makes and the one +;; `pixel-uncompressed-r8g8b8a8` is 7, the one GenImageColor makes and the one ;; LoadTextureFromImage and UpdateTexture want. The `x` in the two ASTC names ;; is lowercase in raylib.h where every other letter in that enum is upper, so ;; those two are mapped by name in `bindings` — the same narrow exception ;; GESTURE_DOUBLETAP already has, and for the same reason. (defenum PixelFormat - [uncompressed-grayscale 1 - uncompressed-gray-alpha 2 - uncompressed-r5g6b5 3 - uncompressed-r8g8b8 4 - uncompressed-r5g5b5a1 5 - uncompressed-r4g4b4a4 6 - uncompressed-r8g8b8a8 7 - uncompressed-r32 8 - uncompressed-r32g32b32 9 - uncompressed-r32g32b32a32 10 - uncompressed-r16 11 - uncompressed-r16g16b16 12 - uncompressed-r16g16b16a16 13 - compressed-dxt1-rgb 14 - compressed-dxt1-rgba 15 - compressed-dxt3-rgba 16 - compressed-dxt5-rgba 17 - compressed-etc1-rgb 18 - compressed-etc2-rgb 19 - compressed-etc2-eac-rgba 20 - compressed-pvrt-rgb 21 - compressed-pvrt-rgba 22 - compressed-astc-4x4-rgba 23 - compressed-astc-8x8-rgba 24]) + [pixel-uncompressed-grayscale 1 + pixel-uncompressed-gray-alpha 2 + pixel-uncompressed-r5g6b5 3 + pixel-uncompressed-r8g8b8 4 + pixel-uncompressed-r5g5b5a1 5 + pixel-uncompressed-r4g4b4a4 6 + pixel-uncompressed-r8g8b8a8 7 + pixel-uncompressed-r32 8 + pixel-uncompressed-r32g32b32 9 + pixel-uncompressed-r32g32b32a32 10 + pixel-uncompressed-r16 11 + pixel-uncompressed-r16g16b16 12 + pixel-uncompressed-r16g16b16a16 13 + pixel-compressed-dxt1-rgb 14 + pixel-compressed-dxt1-rgba 15 + pixel-compressed-dxt3-rgba 16 + pixel-compressed-dxt5-rgba 17 + pixel-compressed-etc1-rgb 18 + pixel-compressed-etc2-rgb 19 + pixel-compressed-etc2-eac-rgba 20 + pixel-compressed-pvrt-rgb 21 + pixel-compressed-pvrt-rgba 22 + pixel-compressed-astc-4x4-rgba 23 + pixel-compressed-astc-8x8-rgba 24]) ;; Reformats the pixels in place, reallocating the buffer, so the Image's ;; `data`, `format` and — for a compressed source — its size all change under @@ -1102,20 +1130,26 @@ ;; `pad` is an index from 0, not an enum: raylib's own parameter is an int and ;; how many are attached is a run-time question. +;; `button-` and `axis-` rather than a shared `gamepad-` stem. The two enums +;; are never in the same position, the shorter prefix is the one that keeps +;; :button-left-face-up and :axis-left-trigger readable, and `gamepad-` on +;; both would have said the part the surrounding call already says. (defenum GamepadButton - [unknown 0 - left-face-up 1 left-face-right 2 left-face-down 3 left-face-left 4 - right-face-up 5 right-face-right 6 right-face-down 7 right-face-left 8 - left-trigger-1 9 left-trigger-2 10 - right-trigger-1 11 right-trigger-2 12 - middle-left 13 middle 14 middle-right 15 - left-thumb 16 right-thumb 17]) + [button-unknown 0 + button-left-face-up 1 button-left-face-right 2 + button-left-face-down 3 button-left-face-left 4 + button-right-face-up 5 button-right-face-right 6 + button-right-face-down 7 button-right-face-left 8 + button-left-trigger-1 9 button-left-trigger-2 10 + button-right-trigger-1 11 button-right-trigger-2 12 + button-middle-left 13 button-middle 14 button-middle-right 15 + button-left-thumb 16 button-right-thumb 17]) ;; The triggers read -1 at rest and 1 fully pressed, unlike the sticks, which ;; are centred at 0. raylib does not normalise that and neither does this. (defenum GamepadAxis - [left-x 0 left-y 1 right-x 2 right-y 3 - left-trigger 4 right-trigger 5]) + [axis-left-x 0 axis-left-y 1 axis-right-x 2 axis-right-y 3 + axis-left-trigger 4 axis-right-trigger 5]) (declare-c gamepad-available? [pad i32] bool "IsGamepadAvailable") @@ -1190,11 +1224,16 @@ ;; A bitfield, not an ordinary enum: set-gestures-enabled takes the OR of ;; several and gesture-detected? tests against one. That is why the enabling ;; call below takes a u32 and not a Gesture — a keyword can only ever name one -;; member, and `all` is spelled out here so the common case still reads. +;; member, and `gesture-all` is spelled out below so the common case still +;; reads. The defconst and the members now share the `gesture-` stem, which +;; is the prefix reading its way out of the enum and into the constant beside +;; it. (defenum Gesture - [none 0 tap 1 double-tap 2 hold 4 drag 8 - swipe-right 16 swipe-left 32 swipe-up 64 swipe-down 128 - pinch-in 256 pinch-out 512]) + [gesture-none 0 gesture-tap 1 gesture-double-tap 2 gesture-hold 4 + gesture-drag 8 + gesture-swipe-right 16 gesture-swipe-left 32 + gesture-swipe-up 64 gesture-swipe-down 128 + gesture-pinch-in 256 gesture-pinch-out 512]) (defconst gesture-all u32 1023)