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

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

gpc
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

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

gpc
function fix32 apply_deadzone(fix32 value, fix32 zone) {
    if (abs(value) < zone) {
        return 0.0;
    }

    return value;
}

sqrt, sq, and pow

gpc
fix32 sqrt(fix32 x);
fix32 sq(fix32 x);
fix32 pow(fix32 base, fix32 exponent);

Use these for stick magnitude checks and response curves.

gpc
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

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

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

gpc
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

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

gpc
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

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

gpc
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() returns 0 for negative input.
  • mod(a, b) returns 0 when b is 0, so guard the divisor when 0 would hide a logic bug.
  • Trigonometry uses radians.
  • rand() takes no arguments; use random(min, max) for an inclusive integer range.
  • Guard your own calculations when a denominator or range could be zero.