Created
June 10, 2025 07:07
-
-
Save routevegetable/46c60c0a60bfaece080738f3a54a6ec2 to your computer and use it in GitHub Desktop.
Primitives for deterministic sequencing of wavy things
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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