flan/vendor/raylib/bindings
Joseph Ferano d7ceec448e Ten more raylib examples, and the three small structs 3D needed
Three shapes, two text, three textures, one models and one core, picked for
binding surface rather than for how they look.

shapes-basic-shapes brings in six draw families nothing had called — the
circle and rectangle gradients, the triangles, all three poly draws — and is
the first call in the corpus to pass two Colors or three Vector2s at once.
shapes-collision-area is get-collision-rec, the only binding that takes two
Rectangles and answers a third, on a frame path. shapes-following-eyes is the
raymath gap measured rather than worked around: every line of it is vector
arithmetic written without a vector library, the way the C writes it.

text-input-box drains get-char-pressed's queue, which no example had read,
and needed a MouseCursor defenum for set-mouse-cursor. text-writing-anim
replaces TextSubtext — unbindable, it answers a pointer into a rotating
static buffer — with (string (slice b 0 n)), which is the same operation
without the shared state.

textures-image-generation runs nine Gen* calls and the
gen/upload/unload-image path, all procedural, no file on disk.
textures-fog-of-war needed a TextureFilter defenum: the smooth fog edge is
entirely :bilinear on a 25x15 render texture, and it is also the first
draw-texture-pro with a negative source height. textures-mouse-painting is
the same render texture used as a document rather than as scratch, plus the
round trip back off the GPU — load-image-from-texture, image-flip-vertical,
export-image — which nothing had run.

models-box-collisions is the counterexample to "a models example is a binding
exercise": nothing in it is a Model, and one BoundingBox defstruct un-refuses
four functions. core-3d-picking is the only caller anywhere for Ray and
RayCollision, and picking is the inverse of the get-world-to-screen the
corpus already had.

Added to vendor/raylib: defstructs BoundingBox, Ray and RayCollision;
defenums MouseCursor and TextureFilter with their mapping lines in bindings;
hand-written declare-c for SetMouseCursor, SetTextureFilter, DrawCubeV,
DrawSphere, DrawSphereWires, DrawRay and GetScreenToWorldRay, each excluded
from the generated half on the rule bindings already states. generated.flan
regenerated against raylib 5.5: 272 declarations, 117 refused, every
defstruct, hand-written declare-c and mapped constant agreeing with the
header.
2026-09-13 14:42:49 +07:00

189 lines
9.6 KiB
Plaintext

# How the generated bindings in generated.flan are shaped. One directive per
# line, `#` comments, blank lines ignored. A line that is neither directive is
# an error rather than a line quietly skipped.
#
# exclude <C symbol or pattern> do not generate a binding for this
# name <C symbol> <flan-name> call it this instead of the kebab rule's
#
# `*` in an exclude pattern stands for any run of characters, and nothing else
# does anything.
#
# Why this file exists. generated.flan is committed, so it is not a build
# artefact anybody can hand-correct: the next `flan generate-c vendor/raylib`
# overwrites it, and an edit made there is destroyed without anybody being
# told. This file is read *while* those lines are made, so it is the edit that
# survives regeneration. A postprocessing pass over the generated text was the
# alternative and was rejected — a second program to understand, applied to
# output the generator had already committed to.
#
# What does NOT belong here. Anything neither directive can express is a
# hand-written `declare-c` in raylib.flan, which wins over the generated file
# and is left alone by the importer. That is the escape hatch for a signature
# the importer gets wrong and for a Flan face the header cannot describe —
# load-font-ex-raw and load-image-from-memory-raw are both that, each wrapped
# by a Flan defn of the same name without the suffix.
# ── raylib's allocator ──────────────────────────────────────────────
#
# raylib exports malloc, realloc and free under its own names. Flan's memory
# model is explicit — plan.org's rule is that an operation never falls back to
# a hidden allocator — so binding these would put a second, untracked heap
# behind three innocuous-looking Flan names, and a pointer from one freed by
# the other is the kind of bug that does not point at itself. Nothing in the
# package needs them: raylib's own Load*/Unload* pairs own everything raylib
# allocates.
exclude MemAlloc
exclude MemRealloc
exclude MemFree
# ── Predicates read as questions ────────────────────────────────────
#
# The kebab rule gives `is-window-ready`, which is C's phrasing wearing Flan's
# punctuation. The hand-written bindings in raylib.flan settled the convention
# years of Lisp settled first — a predicate ends in `?` and does not begin with
# `is` — and these are the generated half of the same set, so they follow it.
# key-pressed? and window-ready? being spelled differently would be the split
# this whole change exists to remove.
#
# The C symbol is kept verbatim in the declaration either way, so nothing here
# is lost: the name is the Flan face and `IsWindowReady` is still what is
# called and still what the check compares against.
name IsWindowReady window-ready?
name IsWindowFullscreen window-fullscreen?
name IsWindowHidden window-hidden?
name IsWindowMinimized window-minimized?
name IsWindowMaximized window-maximized?
name IsWindowFocused window-focused?
name IsWindowResized window-resized?
name IsWindowState window-state?
name IsCursorOnScreen cursor-on-screen?
name IsKeyUp key-up?
name IsKeyPressedRepeat key-pressed-repeat?
name IsMouseButtonUp mouse-button-up?
name IsFileDropped file-dropped?
name IsFileExtension file-extension?
name IsFileNameValid file-name-valid?
name IsPathFile path-file?
name IsAudioStreamValid audio-stream-valid?
name IsAudioStreamPlaying audio-stream-playing?
name IsAudioStreamProcessed audio-stream-processed?
# Hand-written in raylib.flan, so excluded here: a second declare-c for one C
# symbol is refused for the whole program. These three are on a game's
# per-frame path (PORTING.md), and a hand-written line is what the signature
# check has to compare against -- generated output agrees with the header by
# construction, so it can only check the hand-written half.
exclude DrawTexturePro
exclude ImageFromImage
exclude IsWindowReady
# The scissor pair and the 3D surface the ported examples in examples/ draw
# through, excluded here for the same two reasons in different proportions.
#
# - BeginScissorMode/EndScissorMode, BeginMode3D/EndMode3D, DrawCube,
# DrawCubeWires, DrawGrid are inside a frame. The rule above is about the
# per-frame path, and a begin/end pair is taken together: hand-writing one
# half and generating the other is the asymmetry that reads as a mistake.
# - SetExitKey, UpdateCamera and GetWorldToScreen are excluded because their
# Flan face is not the C signature. SetExitKey takes a Key and not an int,
# UpdateCamera takes a CameraMode, and both of those refuse a typo the
# generated i32 would take. GetWorldToScreen goes with BeginMode3D
# because they read the same camera.
#
# What this line splits, and deliberately: draw-cube is here and draw-cube-v
# is generated, get-world-to-screen is here and get-world-to-screen-ex is
# generated, update-camera is here and update-camera-pro is generated. Every
# other family in raylib.flan — the texture draws, the circle draws — sits
# together, so the split is worth naming: what is hand-written is what the
# ported examples call, and hand-writing the variants as well would widen the
# half that has to be maintained by hand for nothing the examples ask for.
#
# What is deliberately NOT here: the window-state family (IsWindowState,
# SetWindowState, ClearWindowState, ToggleFullscreen, Minimize/Maximize/
# RestoreWindow), GetMouseX/GetMouseY and GetRandomValue. Those are called
# per frame by the examples too, but their Flan face IS the C one — plain
# scalars, nothing an enum or a pointer improves — and generated.flan is
# committed, so the default build has them with no header set either way.
exclude BeginScissorMode
exclude EndScissorMode
exclude BeginMode3D
exclude EndMode3D
exclude DrawCube
exclude DrawCubeWires
exclude DrawGrid
exclude SetExitKey
exclude UpdateCamera
exclude GetWorldToScreen
# The second batch of ported examples widened both halves of that split, and
# each of these is here for one of the two reasons above and no new one.
#
# - SetMouseCursor and SetTextureFilter take an `int` in the header and one
# of a closed set of names in fact, so their Flan face is a defenum and
# not the C signature — the same trade SetExitKey makes.
# - DrawCubeV, DrawSphere, DrawSphereWires and DrawRay are inside a frame,
# in examples/models-box-collisions.flan and examples/core-3d-picking.flan.
# draw-cube-v moving here is the one place this batch *narrows* the split
# the paragraph above names: it was generated because nothing called it,
# and something calls it now.
# - GetScreenToWorldRay goes with GetWorldToScreen for the reason given
# there. They are inverses over the same camera.
exclude SetMouseCursor
exclude SetTextureFilter
exclude DrawCubeV
exclude DrawSphere
exclude DrawSphereWires
exclude DrawRay
exclude GetScreenToWorldRay
# ── What the package's constants are called in C ────────────────────
#
# enum <FlanEnum> <C_PREFIX> every member of that defenum
# const <flan-prefix> <C_PREFIX> every defconst whose name starts so
# constant <flan-name> <C_NAME> one name, exactly
#
# Why any of this is needed. `generate-c` used to claim only that every
# defstruct and every hand-written declare-c agreed with raylib.h. It said
# nothing about a defconst or a defenum member — so a wrong flag bit or a
# wrong enum value was *silent*: no link error, no type error, just a window
# that does not open. These lines are what let the check reach them.
#
# The Flan member name becomes the C one by uppercasing and turning `-` into
# `_`, which gets KEY_LEFT_SHIFT out of `left-shift` and FLAG_MSAA_4X_HINT out
# of `msaa-4x-hint`. What it cannot get is the prefix, because the prefix is
# nowhere in the Flan name — so the prefix is said here rather than guessed. A
# name the rule builds and the header does not have is REPORTED and not
# skipped; a mapping that quietly matched nothing would read as coverage and
# provide none.
#
# 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_
enum MouseButton MOUSE_BUTTON_
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_
# 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
# 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
# clear-window-state, and each is a single bit read off raylib.h by hand —
# exactly the transcription this check exists to second-guess.
const flag- FLAG_
# What is deliberately NOT mapped: the 26 colours (a Color is a struct, not an
# enumerator), the examples' screen sizes, and `gesture-all`. That last one is
# 1023, the OR of all ten Gesture members, and raylib has no enumerator with
# that value — there is nothing in the header to compare it against, so
# nothing claims to.