abs := fn($Expr: type, x: Expr): Expr { mask := x >> @intcast(@sizeof(Expr) - 1) return (x ^ mask) - mask } min := fn($Expr: type, a: Expr, b: Expr): Expr { c := a - b return b + (c & c >> @intcast(@sizeof(Expr) - 1)) } max := fn($Expr: type, a: Expr, b: Expr): Expr { c := a - b return a - (c & c >> @intcast(@sizeof(Expr) - 1)) } signum := fn($Expr: type, x: Expr): int { if x > @as(Expr, @intcast(0)) { return 1 } else if x < @as(Expr, @intcast(0)) { return -1 } else { return 0 } } signincl := fn($Expr: type, x: Expr): int { if x > @as(Expr, @intcast(0)) { return 1 } return -1 } Vec2 := fn($Expr: type): type { return struct {x: Expr, y: Expr} } SIN_TABLE := @as([int; 91], @bitcast(@embed("./assets/sin_table"))) sin := fn(theta: int, amplitude: uint): int { if theta < 0 { theta += (-theta / 360 + 1) * 360 } else if theta >= 360 { theta -= theta / 360 * 360 } quadrant := theta / 90 index := theta % 90 if @as(u8, @intcast(quadrant)) == @as(u8, 1) { index = 90 - index } value := SIN_TABLE[@bitcast(index)] if quadrant >= 2 { value = -value } return (value * @bitcast(amplitude) + 5000) / 10000 } cos := fn(theta: int, amplitude: uint): int { return @inline(sin, theta + 90, amplitude) }