Math Functions
Math functions are used heavily in deadzones, stick calibration, trigger thresholds, smoothing, response curves, diagnostics, and value safety checks.
Use fix32 for fractional analog math and int for counters, indexes, flags, and millisecond values. Integer inputs generally return integer-style results; fix32 inputs are used for fractional math.
Quick Reference
| Function | Signature | Returns | Use |
|---|---|---|---|
abs |
abs(x) |
Magnitude of x |
Deadzones and sign-independent checks |
min |
min(a, b) |
Lower value | Limits and comparisons |
max |
max(a, b) |
Higher value | Limits and comparisons |
clamp |
clamp(x, min, max) |
x inside range |
Keep output valid |
mod |
fix32 mod(fix32 a, fix32 b) |
Numeric remainder | Cycling indexes and modes |
sqrt |
fix32 sqrt(fix32 x) |
Square root | Magnitudes and distances |
sq |
fix32 sq(fix32 x) |
x * x |
Magnitudes and curves |
pow |
fix32 pow(fix32 base, fix32 exponent) |
Power result | Response curves |
inv |
inv(x) |
Negated value | Invert a value's sign |
lerp |
fix32 lerp(fix32 a, fix32 b, fix32 t) |
Interpolated value | Smoothing |
rand |
fix32 rand() |
Decimal from 0.0 up to but not including 1.0 |
Fractional variation |
random |
int random(int min, int max) |
Inclusive integer range | Whole-number variation |
isqrt |
int isqrt(int x) |
Integer square root | Whole-number calculations |
sin, cos, tan |
fix32 fn(fix32 radians) |
Trig result | Angle math |
asin, acos, atan |
fix32 fn(fix32 x) |
Angle in radians | Inverse trig |
atan2 |
fix32 atan2(fix32 y, fix32 x) |
Angle in radians | Direction from X/Y |
floor, ceil, round |
fix32 fn(fix32 x) |
Rounded value | Numeric conversion |
log, log2, exp |
fix32 fn(fix32 x) |
Log/exponential result | Advanced shaping |
deg2rad, rad2deg |
fix32 fn(fix32 angle) |
Converted angle | Degree/radian conversion |
clamp
fix32 clamp(fix32 x, fix32 min_value, fix32 max_value);Constrains a value to a range. Use it before writing analog output when scaling or response curves could exceed normal controller limits.
fix32 scale = 1.35;
main {
fix32 rx = get_val(STICK_1_X) * scale;
set_val(STICK_1_X, clamp(rx, -100.0, 100.0));
}abs, min, and max
fix32 abs(fix32 x);
fix32 min(fix32 a, fix32 b);
fix32 max(fix32 a, fix32 b);Use these for simple value shaping and safety checks.
function fix32 apply_deadzone(fix32 value, fix32 zone) {
if (abs(value) < zone) {
return 0.0;
}
return value;
}sqrt, sq, and pow
fix32 sqrt(fix32 x);
fix32 sq(fix32 x);
fix32 pow(fix32 base, fix32 exponent);Use these for stick magnitude checks and response curves.
function fix32 stick_magnitude(fix32 x, fix32 y) {
return sqrt(sq(x) + sq(y));
}
function fix32 curve_axis(fix32 value, fix32 curve) {
fix32 sign = 1.0;
if (value < 0.0) {
sign = -1.0;
}
fix32 normalized = abs(value) / 100.0;
return clamp(pow(normalized, curve) * 100.0 * sign, -100.0, 100.0);
}lerp
fix32 lerp(fix32 a, fix32 b, fix32 t);Linearly interpolates from a toward b. A t value near 0.0 moves slowly; a value near 1.0 moves quickly.
fix32 smooth_rx = 0.0;
fix32 smooth_ry = 0.0;
main {
smooth_rx = lerp(smooth_rx, get_val(STICK_1_X), 0.25);
smooth_ry = lerp(smooth_ry, get_val(STICK_1_Y), 0.25);
set_val(STICK_1_X, smooth_rx);
set_val(STICK_1_Y, smooth_ry);
}Random Values
rand() takes no arguments and returns a fix32 value from 0.0 up to, but not including, 1.0. random(min, max) returns an integer and includes both endpoints.
int min_sample_ms = 100;
int max_sample_ms = 500;
main {
if (event_active(BUTTON_11)) {
int sample_interval = random(min_sample_ms, max_sample_ms);
printf("Diagnostic interval: %d ms", sample_interval);
}
}Trigonometry
fix32 sin(fix32 radians);
fix32 cos(fix32 radians);
fix32 tan(fix32 radians);
fix32 asin(fix32 x);
fix32 acos(fix32 x);
fix32 atan(fix32 x);
fix32 atan2(fix32 y, fix32 x);
fix32 deg2rad(fix32 degrees);
fix32 rad2deg(fix32 radians);Trigonometry functions use radians. Use deg2rad() and rad2deg() when your script logic is easier to express in degrees.
main {
fix32 x = get_val(STICK_1_X);
fix32 y = get_val(STICK_1_Y);
fix32 angle_degrees = rad2deg(atan2(y, x));
if (abs(x) > 5.0 || abs(y) > 5.0) {
printf("Stick angle: %f", angle_degrees);
}
}Rounding and Advanced Helpers
fix32 floor(fix32 x);
fix32 ceil(fix32 x);
fix32 round(fix32 x);
fix32 log(fix32 x);
fix32 log2(fix32 x);
fix32 exp(fix32 x);
fix32 inv(fix32 x);
fix32 mod(fix32 a, fix32 b);Use rounding when converting analog calculations to whole-number values. inv(x) returns -x. Use mod() for a remainder, such as cycling through modes or profiles.
int profile = 0;
int profile_count = 3;
main {
if (event_active(BUTTON_5)) {
profile = mod(profile + 1, profile_count);
printf("Profile: %d", profile);
}
}Notes
- Clamp analog output before
set_val()when math can exceed normal ranges. sqrt()returns0for negative input.mod(a, b)returns0whenbis0, so guard the divisor when0would hide a logic bug.- Trigonometry uses radians.
rand()takes no arguments; userandom(min, max)for an inclusive integer range.- Guard your own calculations when a denominator or range could be zero.