The trio the author decided on 2026-09-20 is now all built: def is CL's defparameter — its initialiser runs on every daemon re-run, unguarded, so an edited initialiser repaints the same storage on C-c C-c plus re-run — defonce (Clojure's name for CL's defvar, per the author) initialises once behind the .init~once. flag, and defconst stays the image. One parse arm reads both forms; the difference is Ast.reinit, carried to Tast.global's grerun. Emit.startup_plan gives a def no guard flag, and Check.check_global lifts every def initialiser — zero and literal included — into global/<n>, so the host's startup reaches it through the function cell and a re-evaluated def swaps it (Session's def_inits; Emit.redefinition declares the cell for a non-sibling target). The old defvar spelling is refused with the rename and both compiling spellings, and every program, test, doc and editor list is swept — except sand.flan, the author's live WIP, whose seven defvar lines are flagged in FIX.org and keep its three dependent tests red on this branch.
178 lines
8.3 KiB
Plaintext
178 lines
8.3 KiB
Plaintext
;;;; raylib [core] example - window flags
|
|
;;;;
|
|
;;;; examples/core/core_window_flags.c. The reason to port this one is the
|
|
;;;; flags themselves: raylib.flan carried four of ConfigFlags' sixteen
|
|
;;;; members — the four sand.flan sets before the window exists — and this
|
|
;;;; example reads and writes eleven of them after it exists. All sixteen are
|
|
;;;; in raylib.flan now, read off raylib.h 5.5, in the header's order and not
|
|
;;;; in bit order (FLAG_VSYNC_HINT is 0x40 and FLAG_FULLSCREEN_MODE is 0x02,
|
|
;;;; which is the kind of thing nobody remembers correctly).
|
|
;;;;
|
|
;;;; They are `defconst u32`s and not a `defenum` for the reason the file
|
|
;;;; already gives about gestures: raylib wants the OR of several and a
|
|
;;;; keyword can only ever name one member.
|
|
;;;;
|
|
;;;; window-state?, set-window-state, clear-window-state, toggle-fullscreen,
|
|
;;;; minimize-window, maximize-window and restore-window all come from the
|
|
;;;; generated half. That is the line drawn in vendor/raylib/bindings and it
|
|
;;;; is worth saying why it falls here: the rule in docs/PORTING.md §1 exists so
|
|
;;;; that a build with no header set can still draw, and generated.flan is
|
|
;;;; committed, so it can. What a hand-written line adds on top of that is a
|
|
;;;; Flan face the C signature does not have — a Key instead of an int, a
|
|
;;;; (Ptr Camera3D) instead of a raw pointer — and these seven have no such
|
|
;;;; face to add. They are u32 in and bool out in both languages.
|
|
;;;;
|
|
;;;; Not faithful in one place, deliberately: the C draws twelve lines of
|
|
;;;; on/off state through TextFormat and a two-branch if each time. Flan has
|
|
;;;; no TextFormat, so the pair is one helper here — which also removes the
|
|
;;;; C's own copy-paste bug, where the UNFOCUSED line says "[G]" when it is on
|
|
;;;; and "[U]" when it is off.
|
|
|
|
(import rl "vendor:raylib")
|
|
(import d "digits.flan")
|
|
|
|
(defconst screen-width 800)
|
|
(defconst screen-height 450)
|
|
|
|
;; Frames the window has been hidden or minimized for. H and N both put the
|
|
;; window somewhere it cannot be typed at, so the only way back is a count.
|
|
(defconst restore-after 240)
|
|
|
|
(defonce ball-pos rl/Vector2)
|
|
(defonce ball-speed rl/Vector2)
|
|
(defonce frames i32)
|
|
|
|
(defconst ball-radius f32 20.0)
|
|
|
|
;; One line of the state list: the label, then "on" or "off" in lime or
|
|
;; maroon, at the x the label ended. The C writes two whole DrawText calls per
|
|
;; flag with the text repeated; this says it once.
|
|
(defn draw-flag [label string flag u32 y i32] ()
|
|
(rl/draw-text label 10 y 10 rl/gray)
|
|
(let [x (+ 10 (rl/measure-text label 10))]
|
|
(if (rl/window-state? flag)
|
|
(rl/draw-text " on" x y 10 rl/lime)
|
|
(rl/draw-text " off" x y 10 rl/maroon))))
|
|
|
|
;; A flag the program owns: pressing the key turns it off if it is on and on
|
|
;; if it is off. Nine of the C's eleven key handlers are exactly this.
|
|
(defn toggle-flag [flag u32] ()
|
|
(if (rl/window-state? flag)
|
|
(rl/clear-window-state flag)
|
|
(rl/set-window-state flag)))
|
|
|
|
(defn main [] ()
|
|
;; The C leaves its SetConfigFlags call commented out, so that every flag
|
|
;; the list shows starts off. Kept that way: the point of the example is
|
|
;; which of them can be changed afterwards.
|
|
(rl/init-window screen-width screen-height
|
|
"raylib [core] example - window flags")
|
|
(defer (rl/close-window))
|
|
|
|
(set ball-pos (rl/Vector2 {.x (/ (f32 (rl/get-screen-width)) 2.0)
|
|
.y (/ (f32 (rl/get-screen-height)) 2.0)}))
|
|
(set ball-speed (rl/Vector2 {.x 5.0 .y 4.0}))
|
|
|
|
;; No set-target-fps, as in the C: with FLAG_VSYNC_HINT among the flags the
|
|
;; example toggles, a frame limiter on top of it would hide what V-Sync
|
|
;; does to the number draw-fps reports.
|
|
|
|
(until (rl/window-should-close?)
|
|
;; Update
|
|
(when (rl/key-pressed? :key-f) (rl/toggle-fullscreen))
|
|
(when (rl/key-pressed? :key-r) (toggle-flag rl/flag-window-resizable))
|
|
(when (rl/key-pressed? :key-d) (toggle-flag rl/flag-window-undecorated))
|
|
(when (rl/key-pressed? :key-u) (toggle-flag rl/flag-window-unfocused))
|
|
(when (rl/key-pressed? :key-t) (toggle-flag rl/flag-window-topmost))
|
|
(when (rl/key-pressed? :key-a) (toggle-flag rl/flag-window-always-run))
|
|
(when (rl/key-pressed? :key-v) (toggle-flag rl/flag-vsync-hint))
|
|
|
|
;; Hidden and minimized are not toggles: the window they hide is also the
|
|
;; window the key would have to be pressed in, so each comes back on a
|
|
;; timer instead.
|
|
(when (rl/key-pressed? :key-h)
|
|
(unless (rl/window-state? rl/flag-window-hidden)
|
|
(rl/set-window-state rl/flag-window-hidden))
|
|
(set frames 0))
|
|
|
|
(when (rl/window-state? rl/flag-window-hidden)
|
|
(set frames (+ frames 1))
|
|
(when (>= frames restore-after)
|
|
(rl/clear-window-state rl/flag-window-hidden)))
|
|
|
|
(when (rl/key-pressed? :key-n)
|
|
(unless (rl/window-state? rl/flag-window-minimized)
|
|
(rl/minimize-window))
|
|
(set frames 0))
|
|
|
|
(when (rl/window-state? rl/flag-window-minimized)
|
|
(set frames (+ frames 1))
|
|
(when (>= frames restore-after) (rl/restore-window)))
|
|
|
|
;; Maximize needs FLAG_WINDOW_RESIZABLE first, which is what R is for.
|
|
(when (rl/key-pressed? :key-m)
|
|
(if (rl/window-state? rl/flag-window-maximized)
|
|
(rl/restore-window)
|
|
(rl/maximize-window)))
|
|
|
|
;; The ball bounces off whatever the window is right now, so resizing,
|
|
;; maximizing and going fullscreen all show up in its path.
|
|
(set (.x ball-pos) (+ (.x ball-pos) (.x ball-speed)))
|
|
(set (.y ball-pos) (+ (.y ball-pos) (.y ball-speed)))
|
|
(when (or (>= (.x ball-pos) (- (f32 (rl/get-screen-width)) ball-radius))
|
|
(<= (.x ball-pos) ball-radius))
|
|
(set (.x ball-speed) (* (.x ball-speed) -1.0)))
|
|
(when (or (>= (.y ball-pos) (- (f32 (rl/get-screen-height)) ball-radius))
|
|
(<= (.y ball-pos) ball-radius))
|
|
(set (.y ball-speed) (* (.y ball-speed) -1.0)))
|
|
|
|
;; Draw
|
|
(rl/with-drawing
|
|
|
|
;; A transparent framebuffer wants a transparent clear; anything else
|
|
;; paints over the desktop the flag exists to show.
|
|
(if (rl/window-state? rl/flag-window-transparent)
|
|
(rl/clear-background rl/blank)
|
|
(rl/clear-background rl/raywhite))
|
|
|
|
(rl/draw-circle-v ball-pos ball-radius rl/maroon)
|
|
(rl/draw-rectangle-lines-ex
|
|
(rl/Rectangle {.x 0.0 .y 0.0
|
|
.width (f32 (rl/get-screen-width))
|
|
.height (f32 (rl/get-screen-height))})
|
|
4.0 rl/raywhite)
|
|
|
|
(rl/draw-circle-v (rl/get-mouse-position) 10.0 rl/darkblue)
|
|
|
|
(rl/draw-fps 10 10)
|
|
|
|
;; The C's TextFormat("Screen Size: [%i, %i]", ...), reassembled out of
|
|
;; literals and examples/digits.flan the way the other ports do it: `x`
|
|
;; walks along the line, and draw-int hands back the width it drew.
|
|
(let [x 10]
|
|
(rl/draw-text "Screen Size: [" x 40 10 rl/green)
|
|
(set x (+ x (rl/measure-text "Screen Size: [" 10)))
|
|
(set x (+ x (d/draw-int (rl/get-screen-width) x 40 10 rl/green)))
|
|
(rl/draw-text ", " x 40 10 rl/green)
|
|
(set x (+ x (rl/measure-text ", " 10)))
|
|
(set x (+ x (d/draw-int (rl/get-screen-height) x 40 10 rl/green)))
|
|
(rl/draw-text "]" x 40 10 rl/green))
|
|
(rl/draw-text "Following flags can be set after window creation:"
|
|
10 60 10 rl/gray)
|
|
(draw-flag "[F] FLAG_FULLSCREEN_MODE:" rl/flag-fullscreen-mode 80)
|
|
(draw-flag "[R] FLAG_WINDOW_RESIZABLE:" rl/flag-window-resizable 100)
|
|
(draw-flag "[D] FLAG_WINDOW_UNDECORATED:" rl/flag-window-undecorated 120)
|
|
(draw-flag "[H] FLAG_WINDOW_HIDDEN:" rl/flag-window-hidden 140)
|
|
(draw-flag "[N] FLAG_WINDOW_MINIMIZED:" rl/flag-window-minimized 160)
|
|
(draw-flag "[M] FLAG_WINDOW_MAXIMIZED:" rl/flag-window-maximized 180)
|
|
(draw-flag "[U] FLAG_WINDOW_UNFOCUSED:" rl/flag-window-unfocused 200)
|
|
(draw-flag "[T] FLAG_WINDOW_TOPMOST:" rl/flag-window-topmost 220)
|
|
(draw-flag "[A] FLAG_WINDOW_ALWAYS_RUN:" rl/flag-window-always-run 240)
|
|
(draw-flag "[V] FLAG_VSYNC_HINT:" rl/flag-vsync-hint 260)
|
|
|
|
(rl/draw-text "Following flags can only be set before window creation:"
|
|
10 300 10 rl/gray)
|
|
(draw-flag "FLAG_WINDOW_HIGHDPI:" rl/flag-window-highdpi 320)
|
|
(draw-flag "FLAG_WINDOW_TRANSPARENT:" rl/flag-window-transparent 340)
|
|
(draw-flag "FLAG_MSAA_4X_HINT:" rl/flag-msaa-4x-hint 360))))
|