|
Banjo API 1.0.0-rc.2
Low-level C99 game development API
|
Typedefs | |
| typedef void(* | bj_window_draw_fn) (struct bj_window *window, struct bj_render_target *target, const struct bj_rect *dirty, void *user_data) |
| typedef void(* | bj_window_resize_fn) (struct bj_window *window, int width, int height, void *user_data) |
| typedef enum bj_window_flag | bj_window_flag |
Enumerations | |
| enum | bj_window_flag { BJ_WINDOW_FLAG_NONE = 0x00 , BJ_WINDOW_FLAG_CLOSE = 0x01 , BJ_WINDOW_FLAG_KEY_REPEAT = 0x02 , BJ_WINDOW_FLAG_RESIZABLE = 0x04 , BJ_WINDOW_FLAG_FULLSCREEN = 0x08 , BJ_WINDOW_FLAG_ALL = 0xFF } |
Open and manage the on-screen window, and read keyboard state.
This subsystem lets your program open a rectangular area on the user's screen, a window, that you can draw into and that receives keyboard and mouse input. Every graphical Banjo program starts by opening one with bj_bind_window and tearing it down with bj_unbind_window on exit.
A window has a title (the text in its top bar), a position and a size (both in pixels), and a set of flags that control behaviour such as "should this window close on the next frame?". You read those flags with bj_get_window_flags and query individual key states with bj_get_key. The actual keyboard and mouse events (press, release, motion, enter/leave) arrive through the separate Event subsystem; the window owns the keyboard focus, the event subsystem delivers what it sees.
Drawing into a window goes through the Bitmap subsystem. Every window owns a "framebuffer" (a bj_bitmap the size of the window) and you draw into it from a callback that banjo fires when the window has pending damage. Register the callback with bj_set_draw_callback and request the next paint with bj_invalidate_window or bj_invalidate_rect.
Windows are fixed-size by default. Pass BJ_WINDOW_FLAG_RESIZABLE to bj_bind_window to let the user resize one. When a resizable window changes size, banjo recreates its framebuffer at the new size and calls the callback you registered with bj_set_resize_callback, handing you the new width and height. What happens next is up to you: banjo imposes no scaling policy. A retro game typically keeps a fixed internal resolution and rescales it onto the framebuffer, while another program might recompute a projection or rebuild its layout.
Fullscreen is a separate switch: bj_set_window_fullscreen toggles it at runtime and BJ_WINDOW_FLAG_FULLSCREEN starts there. It is borderless desktop fullscreen (the display keeps its resolution) and it rides the same path as a resize: going in or out changes the drawable size, so your resize callback fires with the new size and you handle it exactly as above. A window need not be resizable to go fullscreen.
See start.c for the same shape wired up, and pong.c for the capstone version.
Windowing works on Linux, Windows, macOS, and WebAssembly. You don't pick the platform: bj_begin (called with BJ_VIDEO_SYSTEM) probes each one in priority order at startup and uses the first that initialises. A no-op fallback (the fake backend) means bj_bind_window can return a valid handle even on a headless host where no real window can be shown; in that case the framebuffer still exists in memory, just nothing is displayed. On success, startup logs video selected: <name>; on total failure bj_begin returns BJ_FALSE with BJ_ERROR_INITIALIZE.
| typedef void(* bj_window_draw_fn) (struct bj_window *window, struct bj_render_target *target, const struct bj_rect *dirty, void *user_data) |
Redraw callback signature.
Banjo invokes this when it decides "draw the window now." The user repaints target, typically by reaching the software bitmap with bj_render_target_bitmap and writing into it. The callback may also bail out (e.g. no model changes) without drawing anything.
| window | The window being drawn. |
| target | Render target valid only for this call. Don't cache. |
| dirty | Accumulated damage rect. NULL means "whole window
is dirty": repaint the entire surface. A non-NULL rect is in framebuffer pixels. |
| user_data | The pointer registered with bj_set_draw_callback. |
| typedef enum bj_window_flag bj_window_flag |
| typedef void(* bj_window_resize_fn) (struct bj_window *window, int width, int height, void *user_data) |
Window-resize callback signature.
Banjo invokes this when the window's drawable area changes size (the user drags a corner, the window is maximised, it enters or leaves fullscreen, etc.). By the time it fires Banjo has already recreated the window's framebuffer at the new size, so the next draw callback paints into a correctly-sized surface. This callback is your chance to react: recompute a projection or layout, resize your own off-screen surfaces, or do nothing. Banjo also delivers one initial call when you register the callback (see bj_set_resize_callback), so first-time layout belongs here too.
You do not reconfigure the framebuffer here. It is owned by Banjo and already matches width by height. A game that runs at a fixed internal resolution leaves its own bitmap untouched and simply recomputes how it scales that bitmap onto the framebuffer at draw time.
| window | The window that was resized. |
| width | New framebuffer width in pixels. |
| height | New framebuffer height in pixels. |
| user_data | The pointer registered with bj_set_resize_callback. |
| enum bj_window_flag |
A set of flags describing some properties of a bj_window.
These flags can be provided at window creation with bj_bind_window. The may also change during the window lifetime. You can use bj_get_window_flags to query the status of any flag on an active window instance.
| Enumerator | |
|---|---|
| BJ_WINDOW_FLAG_NONE | No Flag. |
| BJ_WINDOW_FLAG_CLOSE | Window should be closed by the application. |
| BJ_WINDOW_FLAG_KEY_REPEAT | Key repeat event is enabled (see bj_set_key_callback). |
| BJ_WINDOW_FLAG_RESIZABLE | User may resize the window. Off by default (see bj_set_resize_callback). |
| BJ_WINDOW_FLAG_FULLSCREEN | Start the window fullscreen (see bj_set_window_fullscreen). |
| BJ_WINDOW_FLAG_ALL | All flags set. |
| struct bj_window * bj_bind_window | ( | const char * | title, |
| uint16_t | x, | ||
| uint16_t | y, | ||
| uint16_t | width, | ||
| uint16_t | height, | ||
| uint8_t | flags, | ||
| struct bj_error ** | error ) |
Create a new struct bj_window with the specified attributes.
| title | Title of the window |
| x | Horizontal position of the window on-screen, expressed in pixels |
| y | Vertical position of the window on-screen, expressed in pixels |
| width | Width of the window. |
| height | Height of the window. |
| flags | A set of options flags. |
| error | Optional pointer to receive error information on failure. |
The caller is responsible for releasing the returned bj_window object with bj_unbind_window.
Referenced by setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), and setup().
| int bj_get_key | ( | const struct bj_window * | window, |
| int | key ) |
Query the current state of a key for a given window.
Returns the state of the specified key as either BJ_RELEASE or BJ_PRESS. If window is NULL or if key is outside the valid range [0, 0xFE], the function returns BJ_RELEASE.
| window | Pointer to the target window, or NULL |
| key | Key code in [0, 0xFE] |
Referenced by update().
| uint8_t bj_get_window_flags | ( | struct bj_window * | window, |
| uint8_t | flags ) |
Get window flags.
This function returns all the flag sets for window. flags is a filter to only get the flag you are interested into. It can be a single flag, an OR'd combination of multiple flags or even BJ_WINDOW_FLAG_ALL if you want to retrieve them all.
| window | The window handler. |
| flags | Filter flag set. |
| int bj_get_window_size | ( | const struct bj_window * | window, |
| int * | width, | ||
| int * | height ) |
Retrieve the size of the window.
| window | The window handler |
| width | A location to the destination width |
| height | A location to the destination height |
The function performs nothing if window is 0.
width and height can be 0 if you are only interested in retrieving one of the values.
You are responsible for the memory of width and height.
Mark a region of window as needing a repaint.
Unions rect into the window's pending damage. Banjo fires the draw callback (bj_set_draw_callback) on the next draw tick with the accumulated damage as the dirty argument, then resets damage to empty.
Passing rect = NULL promotes the pending damage to whole-window and keeps it whole-window until the callback fires (subsequent rect invalidations are absorbed).
Calling this from inside the draw callback accumulates into the next tick's damage; it does not retrigger the current one.
| window | The target window. NULL is a no-op. |
| rect | Region in framebuffer pixels, or NULL for whole window. |
Referenced by bj_invalidate_window().
|
inlinestatic |
Mark the whole window as needing a repaint.
Shorthand for bj_invalidate_rect(window, NULL).
| window | The target window. NULL is a no-op. |
Definition at line 470 of file window.h.
Referenced by roll(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), step(), step(), step(), step(), step(), and step().
Report whether window is currently fullscreen.
Convenience wrapper over bj_get_window_flags(window, BJ_WINDOW_FLAG_FULLSCREEN).
| window | The window to query. NULL reports BJ_FALSE. |
BJ_TRUE if the window is fullscreen, BJ_FALSE otherwise.| struct bj_bitmap * bj_render_target_bitmap | ( | struct bj_render_target * | target | ) |
Reach the software framebuffer behind a render target.
The draw callback (bj_set_draw_callback) receives a bj_render_target. For a software-rendered window this accessor returns the backing bj_bitmap so you can draw with the Bitmap and Drawing functions. Future hardware-backed targets will return NULL and offer their own accessor.
The returned bitmap is owned by Banjo and shares the render target's lifetime: it is valid only for the duration of the callback that received the target. Don't cache the pointer between callbacks.
| target | Render target handed to a draw callback. NULL is a silent no-op that returns NULL. |
NULL if this render target isn't software-backed.Referenced by on_draw(), on_draw(), on_draw(), on_draw(), on_draw(), on_draw(), on_draw(), on_draw(), on_draw(), on_draw(), on_draw(), on_draw(), and on_draw().
| void bj_set_draw_callback | ( | struct bj_window * | window, |
| bj_window_draw_fn | fn, | ||
| void * | user_data ) |
Register the redraw callback for window.
Banjo invokes fn when it decides the window should be repainted. What "decides" means depends on the backend: on Wayland the compositor signals via a frame callback, on X11 it's either an Expose event or a soft-paced timer, on Win32 it's WM_PAINT, and on Emscripten it's requestAnimationFrame. The user just invalidates a rect and draws when called back.
Replaces any previously-registered callback; pass fn = NULL to clear. Without a callback registered, banjo logs a one-time warning the first time it tries to call one and then stays silent.
| window | The target window. NULL is a no-op. |
| fn | The function to call, or NULL to clear. |
| user_data | Pointer forwarded to every callback invocation. |
Referenced by setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), and setup().
| void bj_set_resize_callback | ( | struct bj_window * | window, |
| bj_window_resize_fn | fn, | ||
| void * | user_data ) |
Register the resize callback for window.
Banjo invokes fn whenever the window's drawable size changes. By then it has already recreated the framebuffer at the new size and marked the whole window dirty (so a draw follows). Use the callback to recompute anything that depends on the window size; you never resize the framebuffer yourself.
Registering a callback also delivers one immediate call with the window's current size, before any drawing, so the same handler can do first-time layout and then react to later resizes. Platforms differ on whether they emit a resize at window creation; banjo makes that initial call uniform. Because the framebuffer already matches that size, the initial call only notifies; it recreates nothing.
Replaces any previously-registered callback; pass fn = NULL to clear (clearing does not fire). The current size is also available at any time from bj_get_window_size.
| window | The target window. NULL is a no-op. |
| fn | The function to call on resize, or NULL to clear. |
| user_data | Pointer forwarded to every callback invocation. |
Enter or leave fullscreen on window.
Fullscreen changes the window's drawable size (to the display and back). Banjo recreates the framebuffer and fires your bj_set_resize_callback with the new size, exactly like a user-driven resize, so a program that already handles resize handles fullscreen for free.
It is best-effort and platform dependent (a borderless desktop-sized window on some backends, a real display mode on others; on the web it needs a user gesture). Pass BJ_WINDOW_FLAG_FULLSCREEN to bj_bind_window to start fullscreen, and query the current state with bj_is_window_fullscreen.
Calling it with the state the window is already in is a no-op. A window does not need BJ_WINDOW_FLAG_RESIZABLE to go fullscreen.
| window | The target window. NULL is a no-op. |
| enable | BJ_TRUE to go fullscreen, BJ_FALSE to return to a normal window. |
| void bj_set_window_should_close | ( | struct bj_window * | window | ) |
Flag a given window to be closed.
Once flagged, the window is not automatically closed. Instead, call bj_unbind_window.
Note that it is not possible to remove a closed flag once set.
| window | Pointer to the window object to flag. |
This function effectively returns bj_get_window_flags(window, BJ_WINDOW_FLAG_CLOSE) > 0.
Referenced by key_callback(), and step().
Get the close flag state of a window.
| window | Pointer to the window object to flag. |
If window is 0, the function returns BJ_TRUE.
Referenced by step(), step(), step(), step(), step(), step(), step(), step(), step(), step(), step(), step(), step(), step(), step(), and step().
| void bj_unbind_window | ( | struct bj_window * | window | ) |
Deletes a struct bj_window object and releases associated memory.
| window | Pointer to the window object to delete. |
Referenced by teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), and teardown().