169 lines
7.8 KiB
Plaintext
169 lines
7.8 KiB
Plaintext
;;;; raylib [core] example - window flags
|
|
;;;;
|
|
;;;; examples/core/core_window_flags.c. The reason to port this one is the
|
|
;;;; flags themselves: raylib.fln carried four of ConfigFlags' sixteen
|
|
;;;; members — the four sand.fln sets before the window exists — and this
|
|
;;;; example reads and writes eleven of them after it exists. All sixteen are
|
|
;;;; in raylib.fln 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 `const u32`s and not an `enum` for the reason the file
|
|
;;;; already gives about gestures: raylib wants the OR of several and a
|
|
;;;; keyword can only ever name one member.
|
|
;;;;
|
|
;;;; is-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.fln 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.fln"
|
|
|
|
const screen-width = 800
|
|
const 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.
|
|
const restore-after = 240
|
|
|
|
once ball-pos: rl/Vector2
|
|
once ball-speed: rl/Vector2
|
|
once frames: i32
|
|
|
|
const 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.
|
|
fn draw-flag(label: str, flag: u32, y: i32) -> ()
|
|
rl/draw-text(label, 10, y, 10, rl/gray)
|
|
let x = 10 + rl/measure-text(label, 10)
|
|
if rl/is-window-state(flag)
|
|
rl/draw-text(" on", x, y, 10, rl/lime)
|
|
else
|
|
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.
|
|
fn toggle-flag(flag: u32) -> ()
|
|
if rl/is-window-state(flag)
|
|
rl/clear-window-state(flag)
|
|
else
|
|
rl/set-window-state(flag)
|
|
|
|
fn 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()
|
|
ball-pos = rl/Vector2{.x f32(rl/get-screen-width()) / 2.0, .y f32(rl/get-screen-height()) / 2.0}
|
|
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
|
|
if rl/is-key-pressed(:key-f)
|
|
rl/toggle-fullscreen()
|
|
if rl/is-key-pressed(:key-r)
|
|
toggle-flag(rl/flag-window-resizable)
|
|
if rl/is-key-pressed(:key-d)
|
|
toggle-flag(rl/flag-window-undecorated)
|
|
if rl/is-key-pressed(:key-u)
|
|
toggle-flag(rl/flag-window-unfocused)
|
|
if rl/is-key-pressed(:key-t)
|
|
toggle-flag(rl/flag-window-topmost)
|
|
if rl/is-key-pressed(:key-a)
|
|
toggle-flag(rl/flag-window-always-run)
|
|
if rl/is-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.
|
|
if rl/is-key-pressed(:key-h)
|
|
unless(rl/is-window-state(rl/flag-window-hidden)):
|
|
rl/set-window-state(rl/flag-window-hidden)
|
|
frames = 0
|
|
if rl/is-window-state(rl/flag-window-hidden)
|
|
frames += 1
|
|
if frames >= restore-after
|
|
rl/clear-window-state(rl/flag-window-hidden)
|
|
if rl/is-key-pressed(:key-n)
|
|
unless(rl/is-window-state(rl/flag-window-minimized)):
|
|
rl/minimize-window()
|
|
frames = 0
|
|
if rl/is-window-state(rl/flag-window-minimized)
|
|
frames += 1
|
|
if frames >= restore-after
|
|
rl/restore-window()
|
|
;; Maximize needs FLAG_WINDOW_RESIZABLE first, which is what R is for.
|
|
if rl/is-key-pressed(:key-m)
|
|
if rl/is-window-state(rl/flag-window-maximized)
|
|
rl/restore-window()
|
|
else
|
|
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.
|
|
ball-pos.x += ball-speed.x
|
|
ball-pos.y += ball-speed.y
|
|
if ball-pos.x >= f32(rl/get-screen-width()) - ball-radius or ball-pos.x <= ball-radius
|
|
ball-speed.x *= -1.0
|
|
if ball-pos.y >= f32(rl/get-screen-height()) - ball-radius or ball-pos.y <= ball-radius
|
|
ball-speed.y *= -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/is-window-state(rl/flag-window-transparent)
|
|
rl/clear-background(rl/blank)
|
|
else
|
|
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.fln 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)
|
|
x += rl/measure-text("Screen Size: [", 10)
|
|
x += d/draw-int(rl/get-screen-width(), x, 40, 10, rl/green)
|
|
rl/draw-text(", ", x, 40, 10, rl/green)
|
|
x += rl/measure-text(", ", 10)
|
|
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)
|