Banjo API 1.0.0-rc.2
Low-level C99 game development API
Loading...
Searching...
No Matches
System

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)

Detailed Description

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.

Loading a shared library at runtime

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.

bj_error* err = NULL;
void* lib = bj_load_library("libfoo.so.1", &err);
if (lib) {
int (*foo_init)(void) = bj_library_symbol(lib, "foo_init", &err);
if (foo_init) foo_init();
}
struct bj_error bj_error
Definition api.h:333
void bj_clear_error(struct bj_error **error)
Frees an error and sets the pointer to NULL.
void * bj_load_library(const char *path, struct bj_error **error)
Load the provided dynamic library and returns and opaque handle to it.
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.
void bj_unload_library(void *handle)
Unload a library loaded with bj_load_library from memory.

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.

Enumeration Type Documentation

◆ bj_system

enum bj_system
Enumerator
BJ_NO_SYSTEM 
BJ_AUDIO_SYSTEM 
BJ_VIDEO_SYSTEM 
BJ_NETWORK_SYSTEM 

Definition at line 78 of file system.h.

Function Documentation

◆ bj_begin()

bj_bool bj_begin ( int systems,
struct bj_error ** error )

Initialises the system.

Parameters
systemsAn OR combination of bj_system to initialise.
errorAn 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.

Returns
true if the system is properly initialised, BJ_FALSE otherswise.
Examples
audio_pcm.c, bitmap_blit.c, bitmap_blit_colorkey.c, drawing_2d.c, drawing_text.c, event_callbacks.c, event_polling.c, interpolation.c, load_bmp.c, net_tcp_client.c, net_tcp_nonblocking.c, net_tcp_server.c, net_tcp_timeout.c, net_udp_broadcast_recv.c, net_udp_broadcast_send.c, net_udp_client.c, net_udp_server.c, physics_kinematics.c, physics_particle.c, pong.c, random_distribution.c, shaders.c, sprite_animation.c, start.c, stopwatch.c, template.c, template_callbacks.c, time.c, and window.c.

Referenced by main(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), setup(), and setup().

◆ bj_begin_system()

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:

bj_begin_system(BJ_VIDEO_SYSTEM, "fake", 0); // pins fake
bj_begin(BJ_VIDEO_SYSTEM | BJ_AUDIO_SYSTEM, 0);// video refcount bumps, audio inits
bj_bool bj_begin(int systems, struct bj_error **error)
Initialises the system.
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.
@ BJ_VIDEO_SYSTEM
Definition system.h:81
@ BJ_AUDIO_SYSTEM
Definition system.h:80

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).

Parameters
systemA single bj_system value.
backend_nameBackend to pin on the 0→1 transition, or NULL to auto-select. Ignored for systems without backend selection (network).
errorOptional location to receive error information.
Returns
BJ_TRUE if the system is successfully retained, BJ_FALSE otherwise (unknown backend name, init failure).
See also
bj_end_system, bj_begin, bj_video_backends

◆ bj_end()

◆ bj_end_system()

void bj_end_system ( enum bj_system system,
struct bj_error ** error )

De-initialises a single system with reference counting.

Parameters
systemA single bj_system value to release.
errorAn 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.

See also
bj_begin_system, bj_end

◆ bj_library_symbol()

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.

Parameters
handleA library handle provided by bj_load_library.
nameC-String name of the function to retrieve
errorOptional pointer to receive error information on failure.
Returns
0 or the address of the retrieved function.
Behaviour
  • On Unix platforms, handle and name are passed to dlsym().
  • On Windows, handle and name are passed to GetProcAddress().
Memory Management

The caller is responsible for release the loaded function using bj_unload_library with handle.

Error Codes
  • BJ_ERROR_SYSTEM: Symbol could not be found in the library.
See also
bj_load_library, bj_unload_library
dlsym(), GetProcAddress()

◆ bj_load_library()

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.

Parameters
pathA C-string path to the library to load.
errorOptional pointer to receive error information on failure.
Returns
0 or a handle to the loaded library.
Behaviour
  • On Unix platforms, path is passed to dlopen() with RTLD_LAZY and RTLD_LOCAL flags.
  • On Windows, path is passed to LoadLibraryA().
Memory Management

The caller is responsible for release the loaded library using bj_unload_library.

Error Codes
  • BJ_ERROR_SYSTEM: Library could not be loaded (not found, wrong arch, etc.)
See also
bj_library_symbol, bj_unload_library
dlopen(), LoadLibraryA()

◆ 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.

Parameters
handleThe library to unload.
Behaviour
  • On Unix platforms, handle is passed to dlclose().
  • On Windows, path is passed to FreeLibrary().
Memory Management

The caller is responsible for release the loaded library using bj_unload_library.

See also
bj_library_symbol, bj_unload_library
dlclose(), FreeLibrary()

◆ bj_video_backends()

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.

size_t n = bj_video_backends(0, 0); // count
const char** names = bj_malloc(n * sizeof *names);
bj_video_backends(names, n); // fill
void * bj_malloc(size_t size)
Allocate size bytes of memory.
size_t bj_video_backends(const char **p_names, size_t cap)
Enumerate the video backends compiled into this build.

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.

Parameters
p_namesNULL to just count; otherwise an array of at least cap slots to fill.
capCapacity of p_names (ignored when p_names is NULL).
Returns
The total number of backends (when p_names is NULL) or the number of entries actually written (capped at cap).
See also
bj_begin_system
Examples
banjo-info.c.

Referenced by print_all(), and print_combined().