|
Banjo API 1.0.0-rc.2
Low-level C99 game development API
|
Enumerations | |
| enum | bj_system { BJ_NO_SYSTEM = 0x00 , BJ_AUDIO_SYSTEM = 0x01 , BJ_VIDEO_SYSTEM = 0x02 , BJ_NETWORK_SYSTEM = 0x04 } |
Functions | |
| bj_bool | bj_begin (int systems, struct bj_error **error) |
| size_t | bj_video_backends (const char **p_names, size_t cap) |
| void | bj_end (void) |
| bj_bool | bj_begin_system (enum bj_system system, const char *backend_name, struct bj_error **error) |
| void | bj_end_system (enum bj_system system, struct bj_error **error) |
| void * | bj_load_library (const char *path, struct bj_error **error) |
| void | bj_unload_library (void *handle) |
| void * | bj_library_symbol (void *handle, const char *name, struct bj_error **error) |
Turn Banjo's subsystems on and off, and load shared libraries at runtime.
Banjo is split into subsystems: video (windows + drawing), audio, and network. Each one needs to be initialised before you use it and torn down before your program exits. The startup allocates resources, opens connections to the OS, picks the platform backend (see Windows / Audio for what that means); the teardown does the reverse. You ask Banjo to start a subsystem with one of two APIs.
The simple one: bj_begin takes an OR'd combination of bj_system flags (e.g. BJ_VIDEO_SYSTEM | BJ_AUDIO_SYSTEM) and turns them all on. At program exit, bj_end shuts everything down. Most of the examples and tutorials use this.
The reference-counted one: bj_begin_system / bj_end_system turn one subsystem on or off at a time, and Banjo keeps a counter of how many _begins are outstanding. The subsystem only actually shuts down when the counter reaches zero. Use this if you're building a library on top of Banjo and your callers might also call bj_begin themselves: your _begin and their _begin cooperate, and whoever calls _end last is the one that triggers the real teardown.
Time and event support is always retained internally as a dependency of the others, so you never need to start them explicitly.
The second half of this header is a portable wrapper around the OS-specific calls that load a shared library from disk into the running program: dlopen and friends on Linux/macOS, LoadLibrary and friends on Windows. The Banjo wrappers are bj_load_library, bj_library_symbol, and bj_unload_library. You hand in a path or library name, get an opaque handle back, ask for function addresses by name through the handle, and eventually unload it. The same code works on every platform Banjo supports.
Banjo's own optional backends (X11, ALSA, etc.) use this same API to pull in their platform libraries at runtime, so the libbanjo binary itself never has a hard link-time dependency on them. See Building Banjo for the rationale.
When loading function pointers in your own code, the C standard technically forbids casting a void* (what bj_library_symbol returns) to a function pointer. The LOAD_SYM + memcpy pattern in src/x11/video_x11.c shows the standard workaround.
| enum bj_system |
Initialises the system.
| systems | An OR combination of bj_system to initialise. |
| error | An optional location to an error object. |
The initialisation process will iteratively try to initialise a subsystem among the ones available and returns on the first that succeeded.
Referenced by main(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), and setup().
| bj_bool bj_begin_system | ( | enum bj_system | system, |
| const char * | backend_name, | ||
| struct bj_error ** | error ) |
Initialise one subsystem (refcounted), optionally pinning a backend.
Increments the subsystem's reference count. The 0→1 transition is where the backend is actually picked: pass backend_name as one of the strings from bj_video_backends (or NULL to auto-select). Subsequent retain calls (including via bj_begin) are pure refcount bumps and ignore backend_name: the backend chosen at the 0→1 transition wins for the lifetime of the subsystem.
Typical use is forcing a backend (e.g. "fake" for tests, or "x11" on a host that has both X11 and Wayland) by calling bj_begin_system before any bj_begin call:
Time and event subsystems are retained as dependencies. Calls must be balanced with bj_end_system (or torn down all at once by bj_end).
| system | A single bj_system value. |
| backend_name | Backend to pin on the 0→1 transition, or NULL to auto-select. Ignored for systems without backend selection (network). |
| error | Optional location to receive error information. |
BJ_TRUE if the system is successfully retained, BJ_FALSE otherwise (unknown backend name, init failure).| void bj_end | ( | void | ) |
De-initialises the system.
This function forcefully shuts down all subsystems and resets all reference counts to zero, regardless of how many times they were retained. Errors during shutdown are ignored.
Referenced by main(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), teardown(), and teardown().
De-initialises a single system with reference counting.
| system | A single bj_system value to release. |
| error | An optional location to an error object. |
This function releases the specified system, decrementing its reference count. Time and event subsystems are also released. When a system's reference count reaches zero, it is fully shut down.
| void * bj_library_symbol | ( | void * | handle, |
| const char * | name, | ||
| struct bj_error ** | error ) |
Get the address of a function exported by handle given its name.
This function is an abstraction over the platform specific function like dlsym and GetProcAddress.
| handle | A library handle provided by bj_load_library. |
| name | C-String name of the function to retrieve |
| error | Optional pointer to receive error information on failure. |
The caller is responsible for release the loaded function using bj_unload_library with handle.
| void * bj_load_library | ( | const char * | path, |
| struct bj_error ** | error ) |
Load the provided dynamic library and returns and opaque handle to it.
This function is an abstraction over the platform specific function like dlopen and LoadLibrary. The provided pointer can be used with bj_library_symbol to get a function from the loaded library.
| path | A C-string path to the library to load. |
| error | Optional pointer to receive error information on failure. |
The caller is responsible for release the loaded library using bj_unload_library.
| void bj_unload_library | ( | void * | handle | ) |
Unload a library loaded with bj_load_library from memory.
This function is an abstraction over the platform specific function like dlclose and FreeLibrary.
| handle | The library to unload. |
The caller is responsible for release the loaded library using bj_unload_library.
| size_t bj_video_backends | ( | const char ** | p_names, |
| size_t | cap ) |
Enumerate the video backends compiled into this build.
Two-call enumeration: first call with p_names = NULL to learn the count, then allocate and call again to fill the array.
Names are stable string literals owned by the library; the caller doesn't free them. Ordering matches Banjo's auto-selection priority (most-native first, "fake" last). Known names include "wayland", "x11", "win32", "cocoa", "emscripten", and "fake"; only those compiled in are listed.
| p_names | NULL to just count; otherwise an array of at least cap slots to fill. |
| cap | Capacity of p_names (ignored when p_names is NULL). |
p_names is NULL) or the number of entries actually written (capped at cap).Referenced by print_all(), and print_combined().