Skip to content

Instantly share code, notes, and snippets.

@routevegetable
Created June 10, 2025 07:07
Show Gist options
  • Save routevegetable/46c60c0a60bfaece080738f3a54a6ec2 to your computer and use it in GitHub Desktop.
Save routevegetable/46c60c0a60bfaece080738f3a54a6ec2 to your computer and use it in GitHub Desktop.
Primitives for deterministic sequencing of wavy things
#pragma once
#include <stdint.h>
/**
* msecs
*/
typedef uint32_t when_t;
/**
* msecs
*/
typedef uint32_t period_t;
typedef when_t event_t;
typedef when_t frame_t;
/**
* -32767 - 32767
*/
typedef int16_t value_t;
typedef int32_t wide_value_t;
const wide_value_t VALUE_MAX = (value_t)32767;
const event_t EVENT_ZERO = 0;
when_t hash(when_t x) {
x = ((x >> 16) ^ x) * 0x45d9f3bu;
x = ((x >> 16) ^ x) * 0x45d9f3bu;
x = (x >> 16) ^ x;
return x;
}
event_t event_delay(event_t when, period_t len) {
return when + len;
}
event_t event_or(frame_t frame, event_t a, event_t b) {
if(a > frame) {
/* a didn't happen yet */
return b;
} else if(b > frame) {
/* b didn't happen yet */
return a;
} else if (a > b) {
/* a and b happened - a most recent */
return a;
} else {
/* a and b happened - b most recent */
return b;
}
}
frame_t create_frame(when_t now) {
return now;
}
event_t periodic_event(frame_t frame, period_t period) {
when_t period_num = frame / period;
return period_num * period;
}
value_t sweep(frame_t frame, event_t trigger, period_t period, value_t start, value_t end, value_t wait) {
if(frame < trigger) {
return wait;
} else {
wide_value_t d = end - start;
wide_value_t offset = frame - trigger;
if(offset > period) {
/* Sweep finished */
return end;
} else {
/* In sweep - calculate fraction */
return (wide_value_t)start + (value_t)((offset * d) / (wide_value_t)period);
}
}
}
value_t basic_sweep(frame_t frame, event_t trigger, period_t period) {
return sweep(frame, trigger, period, 0, VALUE_MAX, VALUE_MAX);
}
value_t basic_sweep_cycle(frame_t frame, period_t period) {
event_t ev = periodic_event(frame, period);
return basic_sweep(frame, ev, period);
}
event_t random_event(frame_t frame, period_t period, value_t likelihood) {
when_t period_num = frame / period;
value_t h = hash(period_num) & VALUE_MAX;
if(h <= likelihood) {
return period_num * period;
} else {
/* Not happened yet */
return frame + 1;
}
}
value_t sequence(frame_t frame, event_t trigger, period_t period, value_t start, value_t end) {
return sweep(frame, trigger, period * (end - start), start, end, end);
}
value_t sequence_cycle(frame_t frame, period_t period, value_t start, value_t end) {
event_t ev = periodic_event(frame, period * (end - start + 1));
return sequence(frame, ev, period, start, end);
}
void sequence_pair(frame_t frame, event_t trigger, period_t period, value_t start, value_t end, value_t *a, value_t *b) {
*b = sweep(frame, trigger, period * (end - start), start, end, end);
*a = (*b - 1) % (end - start);
}
void sequence_pair_cycle(frame_t frame, period_t period, value_t start, value_t end, value_t *a, value_t *b) {
event_t ev = periodic_event(frame, period * (end - start + 1));
*b = sweep(frame, ev, period * (end - start), start, end, end);
*a = (*b - 1) % (end - start);
}
value_t random_sequence(frame_t frame, period_t period, value_t min, value_t max) {
when_t period_num = frame / period;
wide_value_t h = hash(period_num) & VALUE_MAX;
return (wide_value_t)min + (h * (wide_value_t)(max - min)) / VALUE_MAX;
}
void random_sequence_pair(frame_t frame, period_t period, value_t min, value_t max, value_t *a, value_t *b) {
when_t period_num = frame / period;
wide_value_t ha = hash(period_num - 1) & VALUE_MAX;
wide_value_t hb = hash(period_num) & VALUE_MAX;
*a = (wide_value_t)min + (ha * (wide_value_t)(max - min) / VALUE_MAX);
*b = (wide_value_t)min + (hb * (wide_value_t)(max - min) / VALUE_MAX);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment