core-2d-camera, core-scissor-test, core-window-flags, core-world-screen
and core-window-should-close, ported from raylib 5.5's examples/core.
What each one asked of vendor/raylib:
2d-camera nothing. A whole Camera2D by value, per frame, into the
call that actually draws with it — the layout the
acceptance table pins through arithmetic, now going
through the path it was bound for.
scissor-test begin-scissor-mode / end-scissor-mode, hand-written.
window-flags twelve more ConfigFlags constants; raylib.flan carried
the four sand.flan sets and this reads eleven.
world-screen the 3D surface did not exist: no Vector3, no Camera3D,
and the importer refused every 3D function in raylib.h
by name for want of them. Two defstructs, two defenums,
begin/end-mode-3d, update-camera, get-world-to-screen,
draw-cube, draw-cube-wires, draw-grid — and 24 more 3D
lines the importer can generate now that the types are
described.
window-should-close set-exit-key, and Key/null to pass it.
The hand-written/generated line, written down in vendor/raylib/bindings:
a drawing pair inside a frame is hand-written, and so is anything whose
Flan face is not the C signature — set-exit-key takes a Key, update-camera
takes a (Ptr Camera3D) and a CameraMode. The window-state family and
get-mouse-x/y stay generated: plain scalars in and bool out, with nothing
for a hand-written line to add.
Camera3D's projection field stays i32, because the header says int and the
layout check holds this file to that; rl/camera-projection is the
conversion, and still takes a keyword.
180 lines
8.2 KiB
Plaintext
180 lines
8.2 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 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)
|
|
|
|
(defvar ball-pos rl/Vector2)
|
|
(defvar ball-speed rl/Vector2)
|
|
(defvar 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? :f) (rl/toggle-fullscreen))
|
|
(when (rl/key-pressed? :r) (toggle-flag rl/flag-window-resizable))
|
|
(when (rl/key-pressed? :d) (toggle-flag rl/flag-window-undecorated))
|
|
(when (rl/key-pressed? :u) (toggle-flag rl/flag-window-unfocused))
|
|
(when (rl/key-pressed? :t) (toggle-flag rl/flag-window-topmost))
|
|
(when (rl/key-pressed? :a) (toggle-flag rl/flag-window-always-run))
|
|
(when (rl/key-pressed? :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? :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? :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? :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/begin-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)
|
|
|
|
(rl/end-drawing)))
|