summaryrefslogtreecommitdiff
path: root/util.h
diff options
context:
space:
mode:
Diffstat (limited to 'util.h')
-rw-r--r--util.h226
1 files changed, 62 insertions, 164 deletions
diff --git a/util.h b/util.h
index aba98bc..6e243d8 100644
--- a/util.h
+++ b/util.h
@@ -20,13 +20,6 @@
#define PIf 3.14159265358979f
-#define HALF_PIf 1.5707963267948966f
-#define TAUf 6.283185307179586f
-#define SQRT2f 1.4142135623730951f
-#define HALF_SQRT2f 0.7071067811865476f
-#define SQRT3f 1.7320508075688772f
-#define HALF_SQRT3f 0.8660254037844386f
-
typedef struct {
float x, y;
@@ -36,7 +29,7 @@ typedef struct {
} vec4;
typedef struct {
double x, y;
-} vec2d;
+} dvec2;
typedef struct {
vec2 pos, size;
@@ -49,19 +42,27 @@ typedef struct {
} String32;
-/// ctype functions for 32-bit chars.
+/// `isword` for 32-bit chars.
bool is32_word(char32_t c);
+/// `isspace` for 32-bit chars.
bool is32_space(char32_t c);
+/// `isalpha` for 32-bit chars.
bool is32_alpha(char32_t c);
+/// `isalnum` for 32-bit chars.
bool is32_alnum(char32_t c);
+/// `isdigit` for 32-bit chars.
bool is32_digit(char32_t c);
+/// `isgraph` for 32-bit chars.
bool is32_graph(char32_t c);
+/// cross-platform `isatty`
bool is_a_tty(FILE *out);
-/// terminal colors. if `out` is a TTY, these will return the appropriate escape sequences.
-/// if `out` is not a TTY, these will return "".
+/// returns terminal escape sequence for italics, or `""` if `out` is not a TTY.
const char *term_italics(FILE *out);
+/// returns terminal escape sequence for bold, or `""` if `out` is not a TTY.
const char *term_bold(FILE *out);
+/// returns terminal escape sequence for yellow, or `""` if `out` is not a TTY.
const char *term_yellow(FILE *out);
+/// returns terminal escape sequence to clear, or `""` if `out` is not a TTY.
const char *term_clear(FILE *out);
/// number of 1 bits in x.
u8 util_popcount(u64 x);
@@ -119,6 +120,7 @@ bool streq_case_insensitive(const char *a, const char *b);
/// function to be passed into qsort for case insensitive sorting
int str_qsort_case_insensitive_cmp(const void *av, const void *bv);
/// the actual file name part of the path; get rid of the containing directory.
+///
/// NOTE: the returned string is part of path, so you don't need to free it or anything.
const char *path_filename(const char *path);
/// is this an absolute path?
@@ -126,12 +128,11 @@ bool path_is_absolute(const char *path);
/// assuming `dir` is an absolute path, returns the absolute path of `relpath`, relative to `dir`.
void path_full(const char *dir, const char *relpath, char *abspath, size_t abspath_size);
/// returns true if the paths are the same.
-/// handles the fact that paths are case insensitive on windows and that \ is the same as /.
+///
+/// handles the fact that paths are case insensitive on windows and that `\\` is the same as `/`.
/// a symbolic link is considered different from the file it points to, as are two hard
/// links to the same file.
bool paths_eq(const char *path1, const char *path2);
-/// equivalent to POSIX function chdir.
-void change_directory(const char *path);
/// copy file from src to dest
/// returns true on success
bool copy_file(const char *src, const char *dst);
@@ -139,44 +140,68 @@ bool copy_file(const char *src, const char *dst);
void qsort_with_context(void *base, size_t nmemb, size_t size,
int (*compar)(void *, const void *, const void *),
void *arg);
-float degrees(float r);
-float radians(float r);
+/// map x from the interval [0, 1] to the interval [a, b]. does NOT clamp.
+///
+/// note that the order is different from the usual convention because i like this order better.
float lerpf(float x, float a, float b);
+/// opposite of lerp; map x from the interval [a, b] to the interval [0, 1]. does NOT clamp.
float normf(float x, float a, float b);
+/// clamp `x` to the range [a, b].
float clampf(float x, float a, float b);
+/// clamp `x` to the range [a, b].
double clampd(double x, double a, double b);
+/// clamp `x` to the range [a, b].
int clampi(int x, int a, int b);
+/// clamp `x` to the range [a, b].
i16 clamp_i16(i16 x, i16 a, i16 b);
+/// clamp `x` to the range [a, b].
u16 clamp_u16(u16 x, u16 a, u16 b);
+/// clamp `x` to the range [a, b].
i32 clamp_i32(i32 x, i32 a, i32 b);
+/// clamp `x` to the range [a, b].
u32 clamp_u32(u32 x, u32 a, u32 b);
+/// number of digits in the decimal representation `x`
u8 ndigits_u64(u64 x);
+/// linearly remap `x` from the interval [`from_a`, `from_b`] to the interval [`to_a`, `to_b`]
float remapf(float x, float from_a, float from_b, float to_a, float to_b);
+/// minimum of `a` and `b`
float minf(float a, float b);
float maxf(float a, float b);
double maxd(double a, double b);
+/// minimum of `a` and `b`
double mind(double a, double b);
+/// minimum of `a` and `b`
u32 min_u32(u32 a, u32 b);
+/// maximum of `a` and `b`
u32 max_u32(u32 a, u32 b);
+/// set `a` to the minimum of `a` and `b` and `b` to the maximum.
void sort2_u32(u32 *a, u32 *b);
+/// minimum of `a` and `b`
i32 min_i32(i32 a, i32 b);
+/// maximum of `a` and `b`
i32 max_i32(i32 a, i32 b);
+/// minimum of `a` and `b`
u64 min_u64(u64 a, u64 b);
+/// maximum of `a` and `b`
u64 max_u64(u64 a, u64 b);
+/// minimum of `a` and `b`
i64 min_i64(i64 a, i64 b);
+/// maximum of `a` and `b`
i64 max_i64(i64 a, i64 b);
+/// returns `a` modulo `b`. for `b > 0`, this will be between `0` and `b - 1`.
+///
+/// if `b <= 0`, the return value is unspecified.
i64 mod_i64(i64 a, i64 b);
+/// returns `a` modulo `b`. for `b > 0`, this will be between `0` and `b - 1`.
+///
+/// if `b <= 0`, the return value is unspecified.
i32 mod_i32(i32 a, i32 b);
+/// absolute value
i64 abs_i64(i64 x);
+/// `-1` if `x < 0`, `0` if `x == 0`, and `1` if `x > 0`
i64 sgn_i64(i64 x);
+/// `-1` if `x < 0`, `0` if `x == 0`, and `1` if `x > 0`
float sgnf(float x);
-float smoothstepf(float x);
-float randf(void);
-u32 rand_u32(void);
-float rand_uniform(float from, float to);
-float sigmoidf(float x);
-i32 ceildivi32(i32 x, i32 y);
-vec2 Vec2(float x, float y);
vec2 vec2_add(vec2 a, vec2 b);
vec2 vec2_add_const(vec2 a, float c);
vec2 vec2_sub(vec2 a, vec2 b);
@@ -184,20 +209,16 @@ vec2 vec2_scale(vec2 v, float s);
vec2 vec2_mul(vec2 a, vec2 b);
vec2 vec2_clamp(vec2 x, vec2 a, vec2 b);
float vec2_dot(vec2 a, vec2 b);
-float vec2_len(vec2 v);
+float vec2_norm(vec2 v);
vec2 vec2_lerp(float x, vec2 a, vec2 b);
vec2 vec2_rotate(vec2 v, float theta);
vec2 vec2_normalize(vec2 v);
-float vec2_dist(vec2 a, vec2 b);
-float vec2_dist_squared(vec2 a, vec2 b);
+float vec2_distance(vec2 a, vec2 b);
void vec2_print(vec2 v);
-vec2 vec2_rand_unit(void);
vec2 vec2_polar(float r, float theta);
-vec4 Vec4(float x, float y, float z, float w);
void rgba_u32_to_floats(u32 rgba, float floats[4]);
vec4 rgba_u32_to_vec4(u32 rgba);
u32 rgba_vec4_to_u32(vec4 color);
-float rgba_brightness(u32 color);
bool rect_contains_point_v2(vec2 pos, vec2 size, vec2 point);
bool centered_rect_contains_point(vec2 center, vec2 size, vec2 point);
Rect rect(vec2 pos, vec2 size);
@@ -209,150 +230,27 @@ vec2 rect_center(Rect r);
bool rect_contains_point(Rect r, vec2 point);
Rect rect_translate(Rect r, vec2 by);
void rect_coords(Rect r, float *x1, float *y1, float *x2, float *y2);
-void rect_print(Rect r);
-float rects_intersect(Rect r1, Rect r2);
-bool rect_clip_to_rect(Rect *clipped, Rect clipper);
-/// removes `amount` from all sides of r
-Rect rect_shrink(Rect r, float amount);
-/// removes `amount` from the left side of r
-Rect rect_shrink_left(Rect r, float amount);
-/// removes `amount` from the top side of r
-Rect rect_shrink_top(Rect r, float amount);
-/// removes `amount` from the right side of r
-Rect rect_shrink_right(Rect r, float amount);
-/// removes `amount` from the bottom side of r
-Rect rect_shrink_bottom(Rect r, float amount);
-/// adds `amount` to all sides of r
-Rect rect_grow(Rect r, float amount);
-vec4 color_rgba_to_hsva(vec4 rgba);
-vec4 color_hsva_to_rgba(vec4 hsva);
-u32 color_interpolate(float x, u32 color1, u32 color2);
-int timespec_cmp(struct timespec a, struct timespec b);
-bool timespec_eq(struct timespec a, struct timespec b);
-struct timespec timespec_max(struct timespec a, struct timespec b);
-double timespec_to_seconds(struct timespec ts);
-bool is32_word(char32_t c);
-bool is32_space(char32_t c);
-bool is32_alpha(char32_t c);
-bool is32_alnum(char32_t c);
-bool is32_digit(char32_t c);
-bool is32_graph(char32_t c);
-bool is_a_tty(FILE *out);
-const char *term_italics(FILE *out);
-const char *term_bold(FILE *out);
-const char *term_yellow(FILE *out);
-const char *term_clear(FILE *out);
-u8 util_popcount(u64 x);
-u8 util_count_leading_zeroes32(u32 x);
-bool util_is_power_of_2(u64 x);
-char32_t *util_mem32chr(char32_t *s, char32_t c, size_t n);
-const char32_t *util_mem32chr_const(const char32_t *s, char32_t c, size_t n);
-bool str_has_prefix(const char *str, const char *prefix);
-bool str_has_path_prefix(const char *path, const char *prefix);
-bool streq(const char *a, const char *b);
-size_t strn_len(const char *src, size_t n);
-char *strn_dup(const char *src, size_t n);
-char *str_dup(const char *src);
-void strn_cat(char *dst, size_t dst_sz, const char *src, size_t src_len);
-void str_cat(char *dst, size_t dst_sz, const char *src);
-void strn_cpy(char *dst, size_t dst_sz, const char *src, size_t src_len);
-void str_cpy(char *dst, size_t dst_sz, const char *src);
-char *a_sprintf(const char *fmt, ...);
-char *strstr_case_insensitive(const char *haystack, const char *needle);
-void print_bytes(const u8 *bytes, size_t n);
-int strcmp_case_insensitive(const char *a, const char *b);
-int str_qsort_case_insensitive_cmp(const void *av, const void *bv);
-int qsort_with_context_cmp(const void *a, const void *b, void *context);
-const char *path_filename(const char *path);
-bool path_is_absolute(const char *path);
-void path_full(const char *dir, const char *relpath, char *abspath, size_t abspath_size);
-bool paths_eq(const char *path1, const char *path2);
-void change_directory(const char *path);
-bool copy_file(const char *src, const char *dst);
-float degrees(float r);
-float radians(float r);
-float lerpf(float x, float a, float b);
-float normf(float x, float a, float b);
-float clampf(float x, float a, float b);
-int clampi(int x, int a, int b);
-i16 clamp_i16(i16 x, i16 a, i16 b);
-u16 clamp_u16(u16 x, u16 a, u16 b);
-i32 clamp_i32(i32 x, i32 a, i32 b);
-u32 clamp_u32(u32 x, u32 a, u32 b);
-u8 ndigits_u64(u64 x);
-float remapf(float x, float from_a, float from_b, float to_a, float to_b);
-float minf(float a, float b);
-float maxf(float a, float b);
-double maxd(double a, double b);
-double mind(double a, double b);
-u32 min_u32(u32 a, u32 b);
-u32 max_u32(u32 a, u32 b);
-void sort2_u32(u32 *a, u32 *b);
-i32 min_i32(i32 a, i32 b);
-i32 max_i32(i32 a, i32 b);
-u64 min_u64(u64 a, u64 b);
-u64 max_u64(u64 a, u64 b);
-i64 min_i64(i64 a, i64 b);
-i64 max_i64(i64 a, i64 b);
-i64 mod_i64(i64 a, i64 b);
-i32 mod_i32(i32 a, i32 b);
-i64 abs_i64(i64 x);
-i64 sgn_i64(i64 x);
-float sgnf(float x);
-float smoothstepf(float x);
-float randf(void);
-float rand_gauss(void);
-u32 rand_u32(void);
-float rand_uniform(float from, float to);
-float sigmoidf(float x);
-i32 ceildivi32(i32 x, i32 y);
-vec2 Vec2(float x, float y);
-vec2 vec2_add(vec2 a, vec2 b);
-vec2 vec2_add_const(vec2 a, float c);
-vec2 vec2_sub(vec2 a, vec2 b);
-vec2 vec2_scale(vec2 v, float s);
-vec2 vec2_mul(vec2 a, vec2 b);
-vec2 vec2_clamp(vec2 x, vec2 a, vec2 b);
-float vec2_dot(vec2 a, vec2 b);
-float vec2_len(vec2 v);
-vec2 vec2_lerp(float x, vec2 a, vec2 b);
-vec2 vec2_rotate(vec2 v, float theta);
-vec2 vec2_normalize(vec2 v);
-float vec2_dist(vec2 a, vec2 b);
-float vec2_dist_squared(vec2 a, vec2 b);
-void vec2_print(vec2 v);
-vec2 vec2_rand_unit(void);
-vec2 vec2_polar(float r, float theta);
-vec4 Vec4(float x, float y, float z, float w);
-vec2d Vec2d(double x, double y);
-void rgba_u32_to_floats(u32 rgba, float floats[4]);
-vec4 rgba_u32_to_vec4(u32 rgba);
-u32 rgba_vec4_to_u32(vec4 color);
-float rgba_brightness(u32 color);
-bool rect_contains_point_v2(vec2 pos, vec2 size, vec2 point);
-bool centered_rect_contains_point(vec2 center, vec2 size, vec2 point);
-Rect rect(vec2 pos, vec2 size);
-Rect rect_endpoints(vec2 e1, vec2 e2);
-Rect rect4(float x1, float y1, float x2, float y2);
-Rect rect_xywh(float x, float y, float w, float h);
-Rect rect_centered(vec2 center, vec2 size);
float rect_x1(Rect r);
float rect_y1(Rect r);
float rect_x2(Rect r);
float rect_y2(Rect r);
float rect_xmid(Rect r);
float rect_ymid(Rect r);
-vec2 rect_center(Rect r);
-bool rect_contains_point(Rect r, vec2 point);
-Rect rect_translate(Rect r, vec2 by);
-void rect_coords(Rect r, float *x1, float *y1, float *x2, float *y2);
void rect_print(Rect r);
float rects_intersect(Rect r1, Rect r2);
bool rect_clip_to_rect(Rect *clipped, Rect clipper);
-Rect rect_shrink(Rect r, float amount);
-Rect rect_grow(Rect r, float amount);
-vec4 color_rgba_to_hsva(vec4 rgba);
-vec4 color_hsva_to_rgba(vec4 hsva);
+/// removes `amount` from all sides of r
+void rect_shrink(Rect *r, float amount);
+/// removes `amount` from the left side of r
+void rect_shrink_left(Rect *r, float amount);
+/// removes `amount` from the top side of r
+void rect_shrink_top(Rect *r, float amount);
+/// removes `amount` from the right side of r
+void rect_shrink_right(Rect *r, float amount);
+/// removes `amount` from the bottom side of r
+void rect_shrink_bottom(Rect *r, float amount);
+/// adds `amount` to all sides of r
+void rect_grow(Rect *r, float amount);
u32 color_interpolate(float x, u32 color1, u32 color2);
int timespec_cmp(struct timespec a, struct timespec b);
bool timespec_eq(struct timespec a, struct timespec b);