Trigonometry functions
GPC has no floating-point type. These six built-ins are the integer equivalents of the usual trigonometric functions: instead of returning a float, they work in a fixed-point domain scaled by 10000. That scaling is what separates them from the float-based versions elsewhere — and the reason the ranges below matter more than the maths itself, which is standard trigonometry.
sin(degrees)
degrees
0..360
integer degrees
sin × 10000
cos(degrees)
degrees
0..360
integer degrees
cos × 10000
tan(degrees)
degrees
0..360
integer degrees
tan × 10000, clamped at 90°/270°
asin(value)
value
-10000..10000
value × 10000
degrees
acos(value)
value
-10000..10000
value × 10000
degrees
atan2(y, x)
y, x
VALUE_MIN..VALUE_MAX
unscaled int
degrees, -180..180
Note the direction of the scaling: sin, cos, and tan take plain degrees and return a scaled value. asin and acos do the reverse — they take a scaled value and return plain degrees. atan2 takes two unscaled integers.
sin and cos are the pair used most in controller work: circular motion, smooth oscillation, vector rotation, and converting an angle and radius into X/Y components. Both are documented in full below.
sin
Compiler category: Math Functions
Backing opcode: sin
Returns the sine of an angle. In controller work, sin() commonly supplies the vertical component of circular movement or produces a smooth back-and-forth wave.
Syntax
result = sin(degrees);Parameters
degrees
An integer angle in whole degrees. The documented static range is 0..360.
On verified current firmware, runtime angles wrap correctly — sin(361) behaves like sin(1), and negative runtime angles work correctly.
Returns
An integer from -10000 to 10000. This is the real sine value multiplied by 10000.
sin(0)
0
0.0000
sin(30)
5000
0.5000
sin(45)
7071
0.7071
sin(90)
10000
1.0000
sin(180)
0
0.0000
sin(270)
-10000
-1.0000
sin(360)
0
0.0000
Example
The result is 5000 because the actual sine of 30 degrees is 0.5, and GPC represents it as 0.5 * 10000.
Scaling an effect
With a strength of 2500, the resulting offset ranges from -2500 to 2500.
Preserve fixed-point precision. Multiply first and divide last. Integer division truncates, so sin(angle) / 10000 * strength destroys nearly all useful precision.
cos
Compiler category: Math Functions
Backing opcode: cos
Returns the cosine of an angle. cos() is commonly paired with sin() to supply the horizontal component of circular movement or rotated vectors.
Syntax
Parameters
degrees
An integer angle in whole degrees. The documented static range is 0..360.
On verified current firmware, runtime angles wrap correctly.
Returns
An integer from -10000 to 10000. This is the real cosine value multiplied by 10000.
cos(0)
10000
1.0000
cos(30)
8660
0.8660
cos(45)
7071
0.7071
cos(90)
0
0.0000
cos(180)
-10000
-1.0000
cos(270)
0
0.0000
cos(360)
10000
1.0000
Example
Scaling an effect
With a strength of 2500, the resulting offset ranges from -2500 to 2500.
Using sin and cos together
For a point on a circle, cosine normally supplies X and sine supplies Y:
Angle
X from cos
Y from sin
Direction
0
positive
0
Right
90
0
positive
Down
180
negative
0
Left
270
0
negative
Up
Controller Y axes normally use positive values for down and negative values for up. If you want traditional mathematical angles where 90 degrees points upward, invert Y:
Example: circular right-stick movement
This moves the right stick around a circle with a radius of 20 percent. Its speed depends on the VM interval. If the real-world speed must remain constant when the VM rate changes, advance the angle using elapsed time from get_rtime().
High-resolution output. The trig results are already in the ±10000 domain, and the modern analog output stage accepts that domain natively:
This skips the divide-by-100 conversion and its quantization to 1-percent steps (100x finer resolution). The PS5_RX form above is shown for clarity on the standard ±100 axes; prefer ANALOG_RX/ANALOG_RY when smoothness matters.
Example: smooth back-and-forth movement
The value moves smoothly from 0 to 1500, through 0 to -1500, and back to 0 without abrupt direction changes.
Example: rotating an existing vector
For large inputs, check both intermediate products and their sum or difference. The final result may be small while an intermediate expression still exceeds the signed 32-bit range.
Important notes and common mistakes
The functions use integer degrees. Fractional angles such as 12.5 degrees cannot be passed directly.
The return value is fixed-point data scaled by 10000, not an ordinary controller percentage.
A result of 10000 means 1.0, 5000 means 0.5, and -10000 means -1.0.
Multiply by the desired radius or strength before dividing by 10000.
A radius of 10000 is safe with these results because 10000 * 10000 is within signed 32-bit range. Larger custom scales require a fresh overflow check.
Runtime angles wrap on verified current firmware, but periodically keeping a long-running accumulator near
0..359prevents eventual integer overflow.These are newer firmware-backed functions. A current Zen firmware and compatible Zen Studio Live compiler are required.
When several systems write the same stick axes, the last output writer wins. Place the intended final stick output after earlier transformations.
Quick formula. To turn an angle and strength into a controller-space vector, use x = cos(angle) * strength / 10000 and y = sin(angle) * strength / 10000. Invert Y when your angle convention treats upward as positive.
Last updated

