41#ifndef RGBX_ANIMATION_H_
42#define RGBX_ANIMATION_H_
45#error "rgbx_animation.h is the C++ wrapper; C extensions should use rgbx_api.h directly"
49#include <zephyr/llext/symbol.h>
72 virtual void tick(uint32_t dt_ms) = 0;
108 void setPixel(
size_t x,
size_t y, uint8_t r, uint8_t g, uint8_t b) {
123 void fill(uint8_t r, uint8_t g, uint8_t b) {
125 for (
size_t i = 0; i < n; i++) {
169 __builtin_memcpy(&value, &bits,
sizeof(value));
188 for (
size_t p = 0; p < i; p++) {
308#define RGBX_ANIMATION(ClassName, DisplayName, W, H, ...) \
309 static_assert(std::is_trivially_destructible_v<ClassName>, \
310 "extension animation classes must be trivially destructible (no atexit in " \
312 extern "C" void __cxa_pure_virtual(void) { \
317 struct rgbx_inputs rgbx_inputs; \
318 uint8_t rgbx_framebuffer[(size_t)(W) * (size_t)(H) * 3u]; \
319 __VA_OPT__(static const struct rgbx_param_desc rgbx_wrapper_params_[] = {__VA_ARGS__};) \
320 const struct rgbx_manifest rgbx_manifest = { \
325 0u __VA_OPT__(+sizeof(rgbx_wrapper_params_) / sizeof(rgbx_wrapper_params_[0])), \
326 NULL __VA_OPT__(? NULL : rgbx_wrapper_params_), \
328 static ClassName rgbx_wrapper_instance_; \
329 uint8_t rgbx_good_moment; \
330 void rgbx_init(void) { rgbx_wrapper_instance_.init(); } \
331 void rgbx_tick(void) { \
332 rgbx_wrapper_instance_.tick(rgbx_inputs.dt_ms); \
333 rgbx_good_moment = rgbx_wrapper_instance_.goodMoment() ? 1u : 0u; \
335 EXPORT_SYMBOL(rgbx_manifest); \
336 EXPORT_SYMBOL(rgbx_inputs); \
337 EXPORT_SYMBOL(rgbx_framebuffer); \
338 EXPORT_SYMBOL(rgbx_init); \
339 EXPORT_SYMBOL(rgbx_tick); \
340 EXPORT_SYMBOL(rgbx_good_moment)
Extension-side analog of the firmware's BaseAnimation.
Definition rgbx_animation.h:59
static constexpr size_t numDisplayBuckets()
Number of fine-grained display buckets.
Definition rgbx_animation.h:242
static constexpr size_t numBands()
Number of coarse audio bands.
Definition rgbx_animation.h:227
float accelZ() const
Accelerometer Z for this tick.
Definition rgbx_animation.h:208
bool paramBool(size_t i) const
Value of BOOL parameter i.
Definition rgbx_animation.h:155
virtual bool goodMoment() const
Queried after every tick(): return true when the frame just rendered ended at a natural switch bounda...
Definition rgbx_animation.h:82
const char * paramString(size_t i) const
Value of STRING parameter i.
Definition rgbx_animation.h:182
void setPixel(size_t x, size_t y, uint8_t r, uint8_t g, uint8_t b)
Write one pixel (out-of-range coordinates are ignored).
Definition rgbx_animation.h:108
size_t height() const
Framebuffer height in pixels (manifest value).
Definition rgbx_animation.h:95
uint32_t param(size_t i) const
Alias of paramU32() kept for early extensions.
Definition rgbx_animation.h:145
float gyroY() const
Gyroscope Y for this tick.
Definition rgbx_animation.h:212
float displayBucket(size_t i) const
Energy of one fine-grained spectrum bucket, for bar-graph style visualisation.
Definition rgbx_animation.h:252
float paramF32(size_t i) const
Value of FLOAT parameter i.
Definition rgbx_animation.h:166
uint32_t paramColor(size_t i) const
Value of COLOR parameter i.
Definition rgbx_animation.h:150
void fill(uint8_t r, uint8_t g, uint8_t b)
Fill the whole framebuffer with one color.
Definition rgbx_animation.h:123
float bandEnergy(size_t b) const
Smoothed energy of one coarse band.
Definition rgbx_animation.h:231
bool buttonWasPressed(size_t id) const
Whether one button was pressed since the previous tick.
Definition rgbx_animation.h:273
float accelY() const
Accelerometer Y for this tick.
Definition rgbx_animation.h:206
virtual void tick(uint32_t dt_ms)=0
Called once per frame; render into the framebuffer via setPixel()/fill().
float accelX() const
Accelerometer X for this tick.
Definition rgbx_animation.h:204
uint32_t buttonsPressed() const
Raw pressed-since-last-tick bitmask.
Definition rgbx_animation.h:269
bool isBeat(size_t b) const
Whether a beat fired in one band this frame.
Definition rgbx_animation.h:237
float gyroX() const
Gyroscope X for this tick.
Definition rgbx_animation.h:210
uint32_t paramU32(size_t i) const
Value of UINT32 parameter i.
Definition rgbx_animation.h:138
size_t width() const
Framebuffer width in pixels (manifest value).
Definition rgbx_animation.h:92
virtual void init()
Called once, on the sandboxed thread, after every (re)load and before the first tick.
Definition rgbx_animation.h:63
float gyroZ() const
Gyroscope Z for this tick.
Definition rgbx_animation.h:214
SPDX-License-Identifier: MIT Copyright (c) 2026 Stuart Alldritt.
#define RGBX_MAX_PARAMS
Fixed capacity of the per-extension parameter block.
Definition rgbx_api.h:48
#define RGBX_PIXEL_INDEX(w, x, y)
Byte offset of pixel (x, y) in rgbx_framebuffer for a display w pixels wide.
Definition rgbx_api.h:237
#define RGBX_MAX_STRING_PARAMS
Maximum number of RGBX_PARAM_STRING parameters per extension.
Definition rgbx_api.h:51
#define RGBX_AUDIO_NUM_BANDS
Number of coarse audio bands (energy + beat flag each).
Definition rgbx_api.h:59
uint8_t rgbx_framebuffer[]
The scratch framebuffer the extension renders into, sized exactly width * height * 3 bytes (see RGBX_...
#define RGBX_AUDIO_NUM_DISPLAY_BUCKETS
Number of fine-grained audio display buckets (bar-graph style).
Definition rgbx_api.h:62
@ RGBX_PARAM_STRING
UTF-8 string, at most RGBX_PARAM_STRING_MAX-1 bytes (text field in the companion app)
Definition rgbx_api.h:74
Extension self-description.
Definition rgbx_api.h:128
uint32_t width
framebuffer width the extension renders at; must match the host display (40 on proto0)
Definition rgbx_api.h:131
const struct rgbx_param_desc * params
NULL iff param_count == 0.
Definition rgbx_api.h:137
uint32_t param_count
entries in params, <= RGBX_MAX_PARAMS; at most RGBX_MAX_STRING_PARAMS of them may be RGBX_PARAM_STRIN...
Definition rgbx_api.h:134
uint32_t height
framebuffer height (12 on proto0)
Definition rgbx_api.h:133
enum rgbx_param_type type
value type.
Definition rgbx_api.h:115