From a22560c3ccaf19261b5c40fdcab36d2d22426986 Mon Sep 17 00:00:00 2001
From: Tavian Barnes <tavianator@tavianator.com>
Date: Sat, 7 Jun 2014 16:58:20 -0400
Subject: Use // comments when possible.

---
 libdimension/bench/array.c            |  22 ++--
 libdimension/bench/future.c           |   4 +-
 libdimension/bench/geometry.c         |  46 ++++-----
 libdimension/bench/polynomial.c       |  10 +-
 libdimension/bench/prtree.c           |   6 +-
 libdimension/bench/triangle.c         |   4 +-
 libdimension/bvh.c                    |  74 +++++++-------
 libdimension/bvh.h                    |  36 +++----
 libdimension/camera.c                 |   6 +-
 libdimension/canvas.c                 |  16 +--
 libdimension/canvas_pigment.c         |   6 +-
 libdimension/checker.c                |   6 +-
 libdimension/cone.c                   |  31 +++---
 libdimension/csg.c                    |  60 +++++------
 libdimension/cube.c                   |  12 +--
 libdimension/dictionary.c             |  42 ++++----
 libdimension/dimension-internal.h     |   2 +-
 libdimension/error.c                  |  36 +++----
 libdimension/future-internal.h        |  36 +++----
 libdimension/future.c                 |  38 +++----
 libdimension/geometry.c               | 186 +++++++++++++++-------------------
 libdimension/gl.c                     |  12 +--
 libdimension/gradient.c               |   4 +-
 libdimension/inline.c                 |  14 +--
 libdimension/interior.c               |   4 +-
 libdimension/lambertian.c             |   4 +-
 libdimension/leopard.c                |   4 +-
 libdimension/light.c                  |   4 +-
 libdimension/map.c                    |  10 +-
 libdimension/object.c                 |  16 +--
 libdimension/perspective.c            |   4 +-
 libdimension/phong.c                  |   6 +-
 libdimension/pigment.c                |   8 +-
 libdimension/pigment_map.c            |   8 +-
 libdimension/plane.c                  |  10 +-
 libdimension/platform.c               |  12 +--
 libdimension/png.c                    | 118 ++++++++++-----------
 libdimension/point_light.c            |   8 +-
 libdimension/polynomial.c             | 106 +++++++++----------
 libdimension/pool.c                   |  24 ++---
 libdimension/profile.c                |  20 ++--
 libdimension/prtree.c                 |  48 ++++-----
 libdimension/prtree.h                 |   2 +-
 libdimension/ray_trace.c              | 112 ++++++++++----------
 libdimension/reflection.c             |   4 +-
 libdimension/rgba.h                   |   8 +-
 libdimension/scene.c                  |   2 +-
 libdimension/solid_pigment.c          |   2 +-
 libdimension/sphere.c                 |  14 +--
 libdimension/tests/custom-error-fn.c  |   2 +-
 libdimension/tests/cxx.cpp            |   4 +-
 libdimension/tests/dictionary.c       |   4 +-
 libdimension/tests/display.c          |  14 +--
 libdimension/tests/error.c            |   2 +-
 libdimension/tests/gl.c               |  16 +--
 libdimension/tests/png.c              |  14 +--
 libdimension/tests/polynomial.c       |  22 ++--
 libdimension/tests/pool.c             |   2 +-
 libdimension/tests/prtree.c           |   2 +-
 libdimension/tests/render.c           |  24 ++---
 libdimension/tests/tests.h            |  14 +--
 libdimension/tests/unit-test.c        |  12 +--
 libdimension/tests/warning-as-error.c |   2 +-
 libdimension/tests/warning.c          |   2 +-
 libdimension/threads.c                |  10 +-
 libdimension/threads.h                |  10 +-
 libdimension/torus.c                  |  20 ++--
 libdimension/triangle.c               |  28 +++--
 libdimension/triangle_fan.c           |  16 +--
 69 files changed, 726 insertions(+), 761 deletions(-)

(limited to 'libdimension')

diff --git a/libdimension/bench/array.c b/libdimension/bench/array.c
index 3fe0c83..b48a03f 100644
--- a/libdimension/bench/array.c
+++ b/libdimension/bench/array.c
@@ -34,7 +34,7 @@ main(void)
     return EXIT_FAILURE;
   }
 
-  /* Benchmark allocation and deallocation */
+  // Benchmark allocation and deallocation
   dmnsn_array *array;
   sandglass_bench_fine(&sandglass, {
     array = dmnsn_new_array(sizeof(object));
@@ -42,10 +42,10 @@ main(void)
   });
   printf("dmnsn_new_array() + dmnsn_delete_array(): %ld\n", sandglass.grains);
 
-  /* Create our test array */
+  // Create our test array
   array = dmnsn_new_array(sizeof(object));
 
-  /* dmnsn_array_push() */
+  // dmnsn_array_push()
 
   printf("dmnsn_array_push():");
 
@@ -55,25 +55,25 @@ main(void)
   }
   printf("\n");
 
-  /* dmnsn_array_get() */
+  // dmnsn_array_get()
   sandglass_bench_fine(&sandglass, dmnsn_array_get(array, count/2, &object));
   printf("dmnsn_array_get(): %ld\n", sandglass.grains);
 
-  /* dmnsn_array_set() */
+  // dmnsn_array_set()
   sandglass_bench_fine(&sandglass, dmnsn_array_set(array, count/2, &object));
   printf("dmnsn_array_set(): %ld\n", sandglass.grains);
 
-  /* dmnsn_array_at() */
+  // dmnsn_array_at()
   void *ptr;
   sandglass_bench_fine(&sandglass, ptr = dmnsn_array_at(array, count/2));
   printf("dmnsn_array_at() = %p: %ld\n", ptr, sandglass.grains);
 
-  /* dmnsn_array_size() */
+  // dmnsn_array_size()
   size_t size;
   sandglass_bench_fine(&sandglass, size = dmnsn_array_size(array));
   printf("dmnsn_array_size() = %zu: %ld\n", size, sandglass.grains);
 
-  /* dmnsn_array_resize() */
+  // dmnsn_array_resize()
   dmnsn_array_resize(array, count);
   sandglass_bench_noprecache(&sandglass, dmnsn_array_resize(array, count * 2));
   printf("dmnsn_array_resize(): %ld", sandglass.grains);
@@ -81,7 +81,7 @@ main(void)
   sandglass_bench_noprecache(&sandglass, dmnsn_array_resize(array, count));
   printf(" %ld\n", sandglass.grains);
 
-  /* dmnsn_array_insert() */
+  // dmnsn_array_insert()
 
   printf("dmnsn_array_insert():");
 
@@ -92,7 +92,7 @@ main(void)
   }
   printf("\n");
 
-  /* dmnsn_array_remove() */
+  // dmnsn_array_remove()
 
   printf("dmnsn_array_remove():");
 
@@ -103,7 +103,7 @@ main(void)
   }
   printf("\n");
 
-  /* dmnsn_array_pop() */
+  // dmnsn_array_pop()
 
   printf("dmnsn_array_pop():");
 
diff --git a/libdimension/bench/future.c b/libdimension/bench/future.c
index f42430e..fd26363 100644
--- a/libdimension/bench/future.c
+++ b/libdimension/bench/future.c
@@ -37,7 +37,7 @@ dmnsn_bench_future_increment(void)
     exit(EXIT_FAILURE);
   }
 
-  /* Benchmark the increment operation. */
+  // Benchmark the increment operation.
   sandglass_bench_fine(&sandglass, dmnsn_future_increment(future));
   printf("dmnsn_future_increment(): %ld\n", sandglass.grains);
 
@@ -62,7 +62,7 @@ dmnsn_bench_future_thread(void *ptr)
   size_t nthreads = 2*dmnsn_ncpus();
   dmnsn_future_set_total(future, nthreads*ITERATIONS);
 
-  /* Now run a bunch of increments concurrently. */
+  // Now run a bunch of increments concurrently.
   return dmnsn_execute_concurrently(future, dmnsn_bench_future_ccthread,
                                     future, nthreads);
 }
diff --git a/libdimension/bench/geometry.c b/libdimension/bench/geometry.c
index 4b8c12a..56c8b58 100644
--- a/libdimension/bench/geometry.c
+++ b/libdimension/bench/geometry.c
@@ -35,13 +35,13 @@ main(void)
     return EXIT_FAILURE;
   }
 
-  /* dmnsn_new_vector() */
+  // dmnsn_new_vector()
   sandglass_bench_fine(&sandglass, {
     vector = dmnsn_new_vector(1.0, 2.0, 3.0);
   });
   printf("dmnsn_new_vector(): %ld\n", sandglass.grains);
 
-  /* dmnsn_matrix_construct() */
+  // dmnsn_matrix_construct()
   sandglass_bench_fine(&sandglass, {
     matrix = dmnsn_new_matrix(1.0, 1.0, 0.0, 0.0,
                               1.0, 1.0, 1.0, 0.0,
@@ -49,92 +49,92 @@ main(void)
   });
   printf("dmnsn_new_matrix(): %ld\n", sandglass.grains);
 
-  /* dmnsn_identity_matrix() */
+  // dmnsn_identity_matrix()
   sandglass_bench_fine(&sandglass, {
     matrix = dmnsn_identity_matrix();
   });
   printf("dmnsn_identity_matrix(): %ld\n", sandglass.grains);
 
-  /* dmnsn_scale_matrix() */
+  // dmnsn_scale_matrix()
   sandglass_bench_fine(&sandglass, {
     matrix = dmnsn_scale_matrix(vector);
   });
   printf("dmnsn_scale_matrix(): %ld\n", sandglass.grains);
 
-  /* dmnsn_identity_matrix() */
+  // dmnsn_identity_matrix()
   sandglass_bench_fine(&sandglass, {
     matrix = dmnsn_translation_matrix(vector);
   });
   printf("dmnsn_translation_matrix(): %ld\n", sandglass.grains);
 
-  /* dmnsn_rotation_matrix() */
+  // dmnsn_rotation_matrix()
   sandglass_bench_fine(&sandglass, {
     matrix = dmnsn_rotation_matrix(vector);
   });
   printf("dmnsn_rotation_matrix(): %ld\n", sandglass.grains);
 
-  /* dmnsn_new_line() */
+  // dmnsn_new_line()
   vector2 = dmnsn_new_vector(3.0, 2.0, 1.0);
   sandglass_bench_fine(&sandglass, {
     line = dmnsn_new_line(vector, vector2);
   });
   printf("dmnsn_new_line(): %ld\n", sandglass.grains);
 
-  /* dmnsn_vector_add() */
+  // dmnsn_vector_add()
   sandglass_bench_fine(&sandglass, {
     vector = dmnsn_vector_add(vector, vector2);
   });
   printf("dmnsn_vector_add(): %ld\n", sandglass.grains);
 
-  /* dmnsn_vector_sub() */
+  // dmnsn_vector_sub()
   sandglass_bench_fine(&sandglass, {
     vector = dmnsn_vector_sub(vector, vector2);
   });
   printf("dmnsn_vector_sub(): %ld\n", sandglass.grains);
 
-  /* dmnsn_vector_mul() */
+  // dmnsn_vector_mul()
   sandglass_bench_fine(&sandglass, {
     vector = dmnsn_vector_mul(2.0, vector);
   });
   printf("dmnsn_vector_mul(): %ld\n", sandglass.grains);
 
-  /* dmnsn_vector_div() */
+  // dmnsn_vector_div()
   sandglass_bench_fine(&sandglass, {
     vector = dmnsn_vector_div(vector, 2.0);
   });
   printf("dmnsn_vector_div(): %ld\n", sandglass.grains);
 
-  /* dmnsn_vector_cross() */
+  // dmnsn_vector_cross()
   sandglass_bench_fine(&sandglass, {
     vector = dmnsn_vector_cross(vector, vector2);
   });
   printf("dmnsn_vector_cross(): %ld\n", sandglass.grains);
 
-  /* dmnsn_vector_dot() */
+  // dmnsn_vector_dot()
   sandglass_bench_fine(&sandglass, {
     result = dmnsn_vector_dot(vector, vector2);
   });
   printf("dmnsn_vector_dot(): %ld\n", sandglass.grains);
 
-  /* dmnsn_vector_norm() */
+  // dmnsn_vector_norm()
   sandglass_bench_fine(&sandglass, {
     result = dmnsn_vector_norm(vector);
   });
   printf("dmnsn_vector_norm(): %ld\n", sandglass.grains);
 
-  /* dmnsn_vector_normalized() */
+  // dmnsn_vector_normalized()
   sandglass_bench_fine(&sandglass, {
     vector = dmnsn_vector_normalized(vector);
   });
   printf("dmnsn_vector_normalized(): %ld\n", sandglass.grains);
 
-  /* dmnsn_matrix_inverse() */
+  // dmnsn_matrix_inverse()
   sandglass_bench_fine(&sandglass, {
     matrix = dmnsn_matrix_inverse(matrix);
   });
   printf("dmnsn_matrix_inverse(): %ld\n", sandglass.grains);
 
-  /* dmnsn_matrix_inverse(HARD) */
+  // dmnsn_matrix_inverse(HARD)
   matrix2 = dmnsn_new_matrix(1.0, 1.0, 0.0, 0.0,
                              1.0, 1.0, 1.0, 0.0,
                              0.0, 1.0, 1.0, 0.0);
@@ -143,37 +143,37 @@ main(void)
   });
   printf("dmnsn_matrix_inverse(HARD): %ld\n", sandglass.grains);
 
-  /* dmnsn_matrix_mul() */
+  // dmnsn_matrix_mul()
   sandglass_bench_fine(&sandglass, {
     matrix = dmnsn_matrix_mul(matrix, matrix2);
   });
   printf("dmnsn_matrix_mul(): %ld\n", sandglass.grains);
 
-  /* dmnsn_transform_point() */
+  // dmnsn_transform_point()
   sandglass_bench_fine(&sandglass, {
     vector = dmnsn_transform_point(matrix, vector);
   });
   printf("dmnsn_transform_point(): %ld\n", sandglass.grains);
 
-  /* dmnsn_transform_direction() */
+  // dmnsn_transform_direction()
   sandglass_bench_fine(&sandglass, {
     vector = dmnsn_transform_direction(matrix, vector);
   });
   printf("dmnsn_transform_direction(): %ld\n", sandglass.grains);
 
-  /* dmnsn_transform_normal() */
+  // dmnsn_transform_normal()
   sandglass_bench_fine(&sandglass, {
     vector = dmnsn_transform_normal(matrix, vector);
   });
   printf("dmnsn_transform_normal(): %ld\n", sandglass.grains);
 
-  /* dmnsn_transform_line() */
+  // dmnsn_transform_line()
   sandglass_bench_fine(&sandglass, {
     line = dmnsn_transform_line(matrix, line);
   });
   printf("dmnsn_transform_line(): %ld\n", sandglass.grains);
 
-  /* dmnsn_line_point() */
+  // dmnsn_line_point()
   sandglass_bench_fine(&sandglass, {
     vector = dmnsn_line_point(line, result);
   });
diff --git a/libdimension/bench/polynomial.c b/libdimension/bench/polynomial.c
index b66648c..bf3d2b0 100644
--- a/libdimension/bench/polynomial.c
+++ b/libdimension/bench/polynomial.c
@@ -27,29 +27,29 @@ main(void)
 #define NPOLY 5
   double p[NPOLY][NPOLY + 1], x[NPOLY];
 
-  /* p[0][] = x - 0.5; */
+  // p[0][] = x - 0.5;
   p[0][1] =  1.0;
   p[0][0] = -0.5;
 
-  /* p[1][] = (x + 0.5)*(x - 0.5) */
+  // p[1][] = (x + 0.5)*(x - 0.5)
   p[1][2] =  1.0;
   p[1][1] =  0.0;
   p[1][0] = -0.25;
 
-  /* p[2][] = (x + 1)*(x - 1.2345)*(x - 100) */
+  // p[2][] = (x + 1)*(x - 1.2345)*(x - 100)
   p[2][3] =  1.0;
   p[2][2] = -100.2345;
   p[2][1] =  22.2155;
   p[2][0] =  123.45;
 
-  /* p[3][] = (x + 1)*(x - 1.2345)*(x - 5)*(x - 100) */
+  // p[3][] = (x + 1)*(x - 1.2345)*(x - 5)*(x - 100)
   p[3][4] =  1.0;
   p[3][3] = -105.2345;
   p[3][2] =  523.388;
   p[3][1] =  12.3725;
   p[3][0] = -617.25;
 
-  /* p[4][] = (x + 1)*(x - 1.2345)*(x - 2.3456)*(x - 5)*(x - 100) */
+  // p[4][] = (x + 1)*(x - 1.2345)*(x - 2.3456)*(x - 5)*(x - 100)
   p[4][5] =  1.0;
   p[4][4] = -107.5801;
   p[4][3] =  770.2260432;
diff --git a/libdimension/bench/prtree.c b/libdimension/bench/prtree.c
index dc5a90d..6c5d3ef 100644
--- a/libdimension/bench/prtree.c
+++ b/libdimension/bench/prtree.c
@@ -98,7 +98,7 @@ main(void)
   });
   printf("dmnsn_new_bvh(DMNSN_BVH_PRTREE): %ld\n", sandglass.grains);
 
-  /* dmnsn_bvh_intersection() */
+  // dmnsn_bvh_intersection()
   dmnsn_line ray = dmnsn_new_line(
     dmnsn_new_vector( 1.0,  1.0, -2.0),
     dmnsn_new_vector(-0.5, -0.5,  1.0)
@@ -115,13 +115,13 @@ main(void)
   });
   printf("dmnsn_bvh_intersection(nocache): %ld\n", sandglass.grains);
 
-  /* dmnsn_bvh_inside() */
+  // dmnsn_bvh_inside()
   sandglass_bench_fine(&sandglass, {
     dmnsn_bvh_inside(bvh, dmnsn_zero);
   });
   printf("dmnsn_bvh_inside(): %ld\n", sandglass.grains);
 
-  /* Cleanup */
+  // Cleanup
   dmnsn_delete_bvh(bvh);
   dmnsn_delete_pool(pool);
   return EXIT_SUCCESS;
diff --git a/libdimension/bench/triangle.c b/libdimension/bench/triangle.c
index 05b8f47..b2b91d0 100644
--- a/libdimension/bench/triangle.c
+++ b/libdimension/bench/triangle.c
@@ -46,7 +46,7 @@ main(void)
   dmnsn_line line;
   bool intersected;
 
-  /* Intersecting case */
+  // Intersecting case
   line = dmnsn_new_line(dmnsn_new_vector(2.0, 1.0, -1.0), dmnsn_z);
   sandglass_bench_fine(&sandglass, {
     intersected = dmnsn_object_intersection(triangle, line, &intersection);
@@ -54,7 +54,7 @@ main(void)
   dmnsn_assert(intersected, "Didn't intersect");
   printf("dmnsn_triangle_intersection(true): %ld\n", sandglass.grains);
 
-  /* Non-intersecting case */
+  // Non-intersecting case
   line = dmnsn_new_line(dmnsn_new_vector(3.0, 3.0, -1.0), dmnsn_z);
   sandglass_bench_fine(&sandglass, {
     intersected = dmnsn_object_intersection(triangle, line, &intersection);
diff --git a/libdimension/bvh.c b/libdimension/bvh.c
index 0a31662..462cbee 100644
--- a/libdimension/bvh.c
+++ b/libdimension/bvh.c
@@ -25,7 +25,7 @@
 
 #include "dimension-internal.h"
 
-/** Implementation for DMNSN_BVH_NONE: just stick all objects in one node. */
+/// Implementation for DMNSN_BVH_NONE: just stick all objects in one node.
 static dmnsn_bvh_node *
 dmnsn_new_stupid_bvh(const dmnsn_array *objects)
 {
@@ -39,21 +39,21 @@ dmnsn_new_stupid_bvh(const dmnsn_array *objects)
   return root;
 }
 
-/* Implementation of opaque dmnsn_bvh type. */
+// Implementation of opaque dmnsn_bvh type.
 struct dmnsn_bvh {
-  dmnsn_array *unbounded;           /**< The unbounded objects. */
-  dmnsn_array *bounded;             /**< The BVH of the bounded objects. */
-  pthread_key_t intersection_cache; /**< The thread-local intersection cache. */
+  dmnsn_array *unbounded;           ///< The unbounded objects.
+  dmnsn_array *bounded;             ///< The BVH of the bounded objects.
+  pthread_key_t intersection_cache; ///< The thread-local intersection cache.
 };
 
-/** A flat BVH node for storing in an array for fast pre-order traversal. */
+/// A flat BVH node for storing in an array for fast pre-order traversal.
 typedef struct dmnsn_flat_bvh_node {
-  dmnsn_bounding_box bounding_box; /* The bounding box of this node. */
-  dmnsn_object *object;            /* The referenced object, for leaf nodes. */
-  ptrdiff_t skip;                  /* Displacement to the next sibling. */
+  dmnsn_bounding_box bounding_box; // The bounding box of this node.
+  dmnsn_object *object;            // The referenced object, for leaf nodes.
+  ptrdiff_t skip;                  // Displacement to the next sibling.
 } dmnsn_flat_bvh_node;
 
-/** Add an object or its children, if any, to an array. */
+/// Add an object or its children, if any, to an array.
 static void
 dmnsn_split_add_object(dmnsn_array *objects, const dmnsn_object *object)
 {
@@ -66,7 +66,7 @@ dmnsn_split_add_object(dmnsn_array *objects, const dmnsn_object *object)
   }
 }
 
-/** Split unions to create the input for the BVH. */
+/// Split unions to create the input for the BVH.
 static dmnsn_array *
 dmnsn_split_objects(const dmnsn_array *objects)
 {
@@ -77,7 +77,7 @@ dmnsn_split_objects(const dmnsn_array *objects)
   return split;
 }
 
-/** Split unbounded objects into a new array. */
+/// Split unbounded objects into a new array.
 static dmnsn_array *
 dmnsn_split_unbounded(dmnsn_array *objects)
 {
@@ -98,7 +98,7 @@ dmnsn_split_unbounded(dmnsn_array *objects)
   return unbounded;
 }
 
-/** Recursively flatten a BVH into an array of flat nodes. */
+/// Recursively flatten a BVH into an array of flat nodes.
 static void
 dmnsn_flatten_bvh_recursive(dmnsn_bvh_node *node, dmnsn_array *flat)
 {
@@ -113,12 +113,12 @@ dmnsn_flatten_bvh_recursive(dmnsn_bvh_node *node, dmnsn_array *flat)
     dmnsn_flatten_bvh_recursive(node->children[i], flat);
   }
 
-  /* Array could have been realloc()'d somewhere else above */
+  // Array could have been realloc()'d somewhere else above
   flatnode = dmnsn_array_at(flat, currenti);
   flatnode->skip = dmnsn_array_size(flat) - currenti;
 }
 
-/** Flatten a BVH into an array of flat nodes. */
+/// Flatten a BVH into an array of flat nodes.
 static dmnsn_array *
 dmnsn_flatten_bvh(dmnsn_bvh_node *root)
 {
@@ -171,13 +171,13 @@ dmnsn_delete_bvh(dmnsn_bvh *bvh)
   }
 }
 
-/** A line with pre-calculated reciprocals to avoid divisions. */
+/// A line with pre-calculated reciprocals to avoid divisions.
 typedef struct dmnsn_optimized_line {
-  dmnsn_vector x0;    /**< The origin of the line. */
-  dmnsn_vector n_inv; /**< The inverse of each component of the line's slope .*/
+  dmnsn_vector x0;    ///< The origin of the line.
+  dmnsn_vector n_inv; ///< The inverse of each component of the line's slope
 } dmnsn_optimized_line;
 
-/** Precompute inverses for faster ray-box intersection tests. */
+/// Precompute inverses for faster ray-box intersection tests.
 static inline dmnsn_optimized_line
 dmnsn_optimize_line(dmnsn_line line)
 {
@@ -188,19 +188,17 @@ dmnsn_optimize_line(dmnsn_line line)
   return optline;
 }
 
-/** Ray-AABB intersection test, by the slab method.  Highly optimized. */
+/// Ray-AABB intersection test, by the slab method.  Highly optimized.
 static inline bool
 dmnsn_ray_box_intersection(dmnsn_optimized_line optline,
                            dmnsn_bounding_box box, double t)
 {
-  /*
-   * This is actually correct, even though it appears not to handle edge cases
-   * (line.n.{x,y,z} == 0).  It works because the infinities that result from
-   * dividing by zero will still behave correctly in the comparisons.  Lines
-   * which are parallel to an axis and outside the box will have tmin == inf
-   * or tmax == -inf, while lines inside the box will have tmin and tmax
-   * unchanged.
-   */
+  // This is actually correct, even though it appears not to handle edge cases
+  // (line.n.{x,y,z} == 0).  It works because the infinities that result from
+  // dividing by zero will still behave correctly in the comparisons.  Lines
+  // which are parallel to an axis and outside the box will have tmin == inf
+  // or tmax == -inf, while lines inside the box will have tmin and tmax
+  // unchanged.
 
   double tx1 = (box.min.x - optline.x0.x)*optline.n_inv.x;
   double tx2 = (box.max.x - optline.x0.x)*optline.n_inv.x;
@@ -223,10 +221,10 @@ dmnsn_ray_box_intersection(dmnsn_optimized_line optline,
   return tmax >= dmnsn_max(0.0, tmin) && tmin < t;
 }
 
-/** The number of intersections to cache. */
+/// The number of intersections to cache.
 #define DMNSN_INTERSECTION_CACHE_SIZE 32
 
-/** An array of cached intersections. */
+/// An array of cached intersections.
 typedef struct dmnsn_intersection_cache {
   size_t i;
   dmnsn_object *objects[DMNSN_INTERSECTION_CACHE_SIZE];
@@ -250,7 +248,7 @@ dmnsn_get_intersection_cache(const dmnsn_bvh *bvh)
   return cache;
 }
 
-/** Test for a closer object intersection than we've found so far. */
+/// Test for a closer object intersection than we've found so far.
 static inline bool
 dmnsn_closer_intersection(dmnsn_object *object, dmnsn_line ray,
                           dmnsn_intersection *intersection, double *t)
@@ -272,15 +270,15 @@ dmnsn_bvh_intersection(const dmnsn_bvh *bvh, dmnsn_line ray,
 {
   double t = INFINITY;
 
-  /* Search the unbounded objects */
+  // Search the unbounded objects
   DMNSN_ARRAY_FOREACH (dmnsn_object **, object, bvh->unbounded) {
     dmnsn_closer_intersection(*object, ray, intersection, &t);
   }
 
-  /* Precalculate 1.0/ray.n.{x,y,z} to save time in intersection tests */
+  // Precalculate 1.0/ray.n.{x,y,z} to save time in intersection tests
   dmnsn_optimized_line optline = dmnsn_optimize_line(ray);
 
-  /* Search the intersection cache */
+  // Search the intersection cache
   dmnsn_intersection_cache *cache = dmnsn_get_intersection_cache(bvh);
   if (dmnsn_unlikely(reset)) {
     cache->i = 0;
@@ -295,7 +293,7 @@ dmnsn_bvh_intersection(const dmnsn_bvh *bvh, dmnsn_line ray,
     }
   }
 
-  /* Search the bounded objects */
+  // Search the bounded objects
   dmnsn_flat_bvh_node *node = dmnsn_array_first(bvh->bounded);
   dmnsn_flat_bvh_node *last = dmnsn_array_last(bvh->bounded);
   while (node <= last) {
@@ -311,7 +309,7 @@ dmnsn_bvh_intersection(const dmnsn_bvh *bvh, dmnsn_line ray,
     }
   }
 
-  /* Update the cache */
+  // Update the cache
   if (dmnsn_likely(cache->i < DMNSN_INTERSECTION_CACHE_SIZE)) {
     cache->objects[cache->i] = found;
     ++cache->i;
@@ -323,13 +321,13 @@ dmnsn_bvh_intersection(const dmnsn_bvh *bvh, dmnsn_line ray,
 DMNSN_HOT bool
 dmnsn_bvh_inside(const dmnsn_bvh *bvh, dmnsn_vector point)
 {
-  /* Search the unbounded objects */
+  // Search the unbounded objects
   DMNSN_ARRAY_FOREACH (dmnsn_object **, object, bvh->unbounded) {
     if (dmnsn_object_inside(*object, point))
       return true;
   }
 
-  /* Search the bounded objects */
+  // Search the bounded objects
   dmnsn_flat_bvh_node *node = dmnsn_array_first(bvh->bounded);
   dmnsn_flat_bvh_node *last = dmnsn_array_last(bvh->bounded);
   while (node <= last) {
diff --git a/libdimension/bvh.h b/libdimension/bvh.h
index 2c3a8a4..27652c1 100644
--- a/libdimension/bvh.h
+++ b/libdimension/bvh.h
@@ -27,50 +27,50 @@
 
 #include <stdbool.h>
 
-/** A bounding volume hierarchy. */
+/// A bounding volume hierarchy.
 typedef struct dmnsn_bvh dmnsn_bvh;
 
-/** Available BVH implementations. */
+/// Available BVH implementations.
 typedef enum dmnsn_bvh_kind {
   DMNSN_BVH_NONE,
   DMNSN_BVH_PRTREE,
 } dmnsn_bvh_kind;
 
-/** Create a BVH. */
+/// Create a BVH.
 DMNSN_INTERNAL dmnsn_bvh *dmnsn_new_bvh(const dmnsn_array *objects,
                                         dmnsn_bvh_kind kind);
-/** Delete a BVH. */
+/// Delete a BVH.
 DMNSN_INTERNAL void dmnsn_delete_bvh(dmnsn_bvh *bvh);
 
-/** Find the closest ray-object intersection in the tree. */
+/// Find the closest ray-object intersection in the tree.
 DMNSN_INTERNAL bool dmnsn_bvh_intersection(const dmnsn_bvh *bvh,
                                            dmnsn_line ray,
                                            dmnsn_intersection *intersection,
                                            bool reset);
-/** Determine whether a point is inside any object in the tree. */
+/// Determine whether a point is inside any object in the tree.
 DMNSN_INTERNAL bool dmnsn_bvh_inside(const dmnsn_bvh *bvh, dmnsn_vector point);
-/** Return the bounding box of the whole hierarchy. */
+/// Return the bounding box of the whole hierarchy.
 DMNSN_INTERNAL dmnsn_bounding_box dmnsn_bvh_bounding_box(const dmnsn_bvh *bvh);
 
-/** A non-flat BVH representation, used by BVH implementations. */
+/// A non-flat BVH representation, used by BVH implementations.
 typedef struct dmnsn_bvh_node {
-  dmnsn_bounding_box bounding_box;   /** The bounding box of this node. */
-  dmnsn_object *object;              /** The object, for leaf nodes. */
-  int data;                          /** Extra field for implementation use. */
-  size_t nchildren;                  /** How many children this node has. */
-  size_t max_children;               /** Maximum number of children. */
-  struct dmnsn_bvh_node *children[]; /** Flexible array of children. */
+  dmnsn_bounding_box bounding_box;   /// The bounding box of this node.
+  dmnsn_object *object;              /// The object, for leaf nodes.
+  int data;                          /// Extra field for implementation use.
+  size_t nchildren;                  /// How many children this node has.
+  size_t max_children;               /// Maximum number of children.
+  struct dmnsn_bvh_node *children[]; /// Flexible array of children.
 } dmnsn_bvh_node;
 
-/** Create a BVH node. */
+/// Create a BVH node.
 DMNSN_INTERNAL dmnsn_bvh_node *dmnsn_new_bvh_node(size_t max_children);
 
-/** Create a BVH leaf node. */
+/// Create a BVH leaf node.
 DMNSN_INTERNAL dmnsn_bvh_node *dmnsn_new_bvh_leaf_node(dmnsn_object *object);
 
-/** Delete a BVH node. */
+/// Delete a BVH node.
 DMNSN_INTERNAL void dmnsn_delete_bvh_node(dmnsn_bvh_node *node);
 
-/** Add a child to a BVH node. */
+/// Add a child to a BVH node.
 DMNSN_INTERNAL void dmnsn_bvh_node_add(dmnsn_bvh_node *parent,
                                        dmnsn_bvh_node *child);
diff --git a/libdimension/camera.c b/libdimension/camera.c
index 3db9f2c..550b41c 100644
--- a/libdimension/camera.c
+++ b/libdimension/camera.c
@@ -26,7 +26,7 @@
 #include "dimension-internal.h"
 #include <stdlib.h>
 
-/* Allocate a new dummy camera */
+// Allocate a new dummy camera
 dmnsn_camera *
 dmnsn_new_camera(dmnsn_pool *pool)
 {
@@ -35,14 +35,14 @@ dmnsn_new_camera(dmnsn_pool *pool)
   return camera;
 }
 
-/* Initialize a camera */
+// Initialize a camera
 void
 dmnsn_init_camera(dmnsn_camera *camera)
 {
   camera->trans = dmnsn_identity_matrix();
 }
 
-/* Invoke the camera ray function */
+// Invoke the camera ray function
 dmnsn_line
 dmnsn_camera_ray(const dmnsn_camera *camera, double x, double y)
 {
diff --git a/libdimension/canvas.c b/libdimension/canvas.c
index cb7e5ce..b605108 100644
--- a/libdimension/canvas.c
+++ b/libdimension/canvas.c
@@ -25,7 +25,7 @@
 
 #include "dimension-internal.h"
 
-/** cleanup_fn for canvases. */
+/// cleanup_fn for canvases.
 static void dmnsn_canvas_cleanup(void *ptr);
 
 dmnsn_canvas *
@@ -44,7 +44,7 @@ dmnsn_canvas_cleanup(void *ptr)
 {
   dmnsn_canvas *canvas = ptr;
 
-  /* Free the optimizers */
+  // Free the optimizers
   DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) {
     if (i->free_fn) {
       i->free_fn(i->ptr);
@@ -53,7 +53,7 @@ dmnsn_canvas_cleanup(void *ptr)
   dmnsn_delete_array(canvas->optimizers);
 }
 
-/* Set a canvas optimizer */
+// Set a canvas optimizer
 void
 dmnsn_canvas_optimize(dmnsn_canvas *canvas,
                       const dmnsn_canvas_optimizer *optimizer)
@@ -61,7 +61,7 @@ dmnsn_canvas_optimize(dmnsn_canvas *canvas,
   dmnsn_array_push(canvas->optimizers, optimizer);
 }
 
-/* Find an optimizer if it's already installed */
+// Find an optimizer if it's already installed
 dmnsn_canvas_optimizer *
 dmnsn_canvas_find_optimizer(const dmnsn_canvas *canvas,
                             dmnsn_canvas_optimizer_fn *optimizer_fn)
@@ -75,7 +75,7 @@ dmnsn_canvas_find_optimizer(const dmnsn_canvas *canvas,
   return NULL;
 }
 
-/* Set the value of a pixel */
+// Set the value of a pixel
 void
 dmnsn_canvas_set_pixel(dmnsn_canvas *canvas, size_t x, size_t y,
                        dmnsn_tcolor tcolor)
@@ -84,16 +84,16 @@ dmnsn_canvas_set_pixel(dmnsn_canvas *canvas, size_t x, size_t y,
                "Canvas access out of bounds.");
   dmnsn_assert(!dmnsn_tcolor_isnan(tcolor), "Pixel has NaN component.");
 
-  /* Set the pixel */
+  // Set the pixel
   canvas->pixels[y*canvas->width + x] = tcolor;
 
-  /* Call the optimizers */
+  // Call the optimizers
   DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) {
     i->optimizer_fn(canvas, i->ptr, x, y);
   }
 }
 
-/* Fill a canvas with a solid color */
+// Fill a canvas with a solid color
 void
 dmnsn_canvas_clear(dmnsn_canvas *canvas, dmnsn_tcolor tcolor)
 {
diff --git a/libdimension/canvas_pigment.c b/libdimension/canvas_pigment.c
index d4812cf..2b1e2b6 100644
--- a/libdimension/canvas_pigment.c
+++ b/libdimension/canvas_pigment.c
@@ -25,13 +25,13 @@
 
 #include "dimension.h"
 
-/** Canvas pigment type. */
+/// Canvas pigment type.
 typedef struct dmnsn_canvas_pigment {
   dmnsn_pigment pigment;
   dmnsn_canvas *canvas;
 } dmnsn_canvas_pigment;
 
-/** Canvas pigment color callback. */
+/// Canvas pigment color callback.
 static dmnsn_tcolor
 dmnsn_canvas_pigment_fn(const dmnsn_pigment *pigment, dmnsn_vector v)
 {
@@ -43,7 +43,7 @@ dmnsn_canvas_pigment_fn(const dmnsn_pigment *pigment, dmnsn_vector v)
   return dmnsn_canvas_get_pixel(canvas, x%canvas->width, y%canvas->height);
 }
 
-/* Create a canvas color */
+// Create a canvas color
 dmnsn_pigment *
 dmnsn_new_canvas_pigment(dmnsn_pool *pool, dmnsn_canvas *canvas)
 {
diff --git a/libdimension/checker.c b/libdimension/checker.c
index 01b19f3..740abe8 100644
--- a/libdimension/checker.c
+++ b/libdimension/checker.c
@@ -25,7 +25,7 @@
 
 #include "dimension-internal.h"
 
-/** Checker pattern callback. */
+/// Checker pattern callback.
 static double
 dmnsn_checker_pattern_fn(const dmnsn_pattern *checker, dmnsn_vector v)
 {
@@ -40,7 +40,7 @@ dmnsn_checker_pattern_fn(const dmnsn_pattern *checker, dmnsn_vector v)
   if (zmod < -dmnsn_epsilon)
     zmod += 2.0;
 
-  /* Return 0 when an even number of coordinates are in [0, 1), 1 otherwise */
+  // Return 0 when an even number of coordinates are in [0, 1), 1 otherwise
   unsigned int n = 0;
   if (xmod >= 1.0)
     ++n;
@@ -51,7 +51,7 @@ dmnsn_checker_pattern_fn(const dmnsn_pattern *checker, dmnsn_vector v)
   return (n%2 == 0) ? 0.0 : 1.0;
 }
 
-/** The singleton instance. */
+/// The singleton instance.
 static dmnsn_pattern dmnsn_checker_instance = {
   .pattern_fn = dmnsn_checker_pattern_fn,
 };
diff --git a/libdimension/cone.c b/libdimension/cone.c
index fb05231..1e95b0a 100644
--- a/libdimension/cone.c
+++ b/libdimension/cone.c
@@ -26,13 +26,13 @@
 #include "dimension.h"
 #include <math.h>
 
-/** Cone type. */
+/// Cone type.
 typedef struct dmnsn_cone {
   dmnsn_object object;
   double r1, r2;
 } dmnsn_cone;
 
-/** Intersection callback for a cone. */
+/// Intersection callback for a cone.
 static bool
 dmnsn_cone_intersection_fn(const dmnsn_object *object, dmnsn_line l,
                            dmnsn_intersection *intersection)
@@ -40,8 +40,7 @@ dmnsn_cone_intersection_fn(const dmnsn_object *object, dmnsn_line l,
   const dmnsn_cone *cone = (const dmnsn_cone *)object;
   double r1 = cone->r1, r2 = cone->r2;
 
-  /* Solve (x0 + nx*t)^2 + (z0 + nz*t)^2
-           == (((r2 - r1)*(y0 + ny*t) + r1 + r2)/2)^2 */
+  // Solve (x0 + nx*t)^2 + (z0 + nz*t)^2 == (((r2 - r1)*(y0 + ny*t) + r1 + r2)/2)^2
   double poly[3], x[2];
   poly[2] = l.n.x*l.n.x + l.n.z*l.n.z - l.n.y*l.n.y*(r2 - r1)*(r2 - r1)/4.0;
   poly[1] = 2.0*(l.n.x*l.x0.x + l.n.z*l.x0.z)
@@ -78,7 +77,7 @@ dmnsn_cone_intersection_fn(const dmnsn_object *object, dmnsn_line l,
   return false;
 }
 
-/** Inside callback for a cone. */
+/// Inside callback for a cone.
 static bool
 dmnsn_cone_inside_fn(const dmnsn_object *object, dmnsn_vector point)
 {
@@ -89,7 +88,7 @@ dmnsn_cone_inside_fn(const dmnsn_object *object, dmnsn_vector point)
          && point.y > -1.0 && point.y < 1.0;
 }
 
-/** Cone bounding callback. */
+/// Cone bounding callback.
 static dmnsn_bounding_box
 dmnsn_cone_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
 {
@@ -100,20 +99,20 @@ dmnsn_cone_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
   return dmnsn_transform_bounding_box(trans, box);
 }
 
-/** Cone vtable. */
+/// Cone vtable.
 static const dmnsn_object_vtable dmnsn_cone_vtable = {
   .intersection_fn = dmnsn_cone_intersection_fn,
   .inside_fn = dmnsn_cone_inside_fn,
   .bounding_fn = dmnsn_cone_bounding_fn,
 };
 
-/** Cone cap type. */
+/// Cone cap type.
 typedef struct dmnsn_cone_cap {
   dmnsn_object object;
   double r;
 } dmnsn_cone_cap;
 
-/** Cone cap intersection function. */
+/// Cone cap intersection function.
 static bool
 dmnsn_cone_cap_intersection_fn(const dmnsn_object *object, dmnsn_line l,
                                dmnsn_intersection *intersection)
@@ -133,14 +132,14 @@ dmnsn_cone_cap_intersection_fn(const dmnsn_object *object, dmnsn_line l,
   return false;
 }
 
-/** Inside callback for a cone cap. */
+/// Inside callback for a cone cap.
 static bool
 dmnsn_cone_cap_inside_fn(const dmnsn_object *object, dmnsn_vector point)
 {
   return false;
 }
 
-/** Cone cap bounding callback. */
+/// Cone cap bounding callback.
 static dmnsn_bounding_box
 dmnsn_cone_cap_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
 {
@@ -149,14 +148,14 @@ dmnsn_cone_cap_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
   return dmnsn_transform_bounding_box(trans, box);
 }
 
-/** Cone cap vtable. */
+/// Cone cap vtable.
 static const dmnsn_object_vtable dmnsn_cone_cap_vtable = {
   .intersection_fn = dmnsn_cone_cap_intersection_fn,
   .inside_fn = dmnsn_cone_cap_inside_fn,
   .bounding_fn = dmnsn_cone_cap_bounding_fn,
 };
 
-/** Allocate a new cone cap. */
+/// Allocate a new cone cap.
 dmnsn_object *
 dmnsn_new_cone_cap(dmnsn_pool *pool, double r)
 {
@@ -169,7 +168,7 @@ dmnsn_new_cone_cap(dmnsn_pool *pool, double r)
   return object;
 }
 
-/* Allocate a new cone object */
+// Allocate a new cone object
 dmnsn_object *
 dmnsn_new_cone(dmnsn_pool *pool, double r1, double r2, bool open)
 {
@@ -185,7 +184,7 @@ dmnsn_new_cone(dmnsn_pool *pool, double r1, double r2, bool open)
     return object;
   }
 
-  /* Implement closed cones as a union with the caps */
+  // Implement closed cones as a union with the caps
   dmnsn_object *cap1 = dmnsn_new_cone_cap(pool, r1);
   dmnsn_object *cap2 = dmnsn_new_cone_cap(pool, r2);
   cap1->intrinsic_trans = dmnsn_translation_matrix(
@@ -194,7 +193,7 @@ dmnsn_new_cone(dmnsn_pool *pool, double r1, double r2, bool open)
   cap2->intrinsic_trans = dmnsn_translation_matrix(
     dmnsn_new_vector(0.0, +1.0, 0.0)
   );
-  /* Flip the normal around for the top cap */
+  // Flip the normal around for the top cap
   cap2->intrinsic_trans.n[1][1] = -1.0;
 
   dmnsn_array *withcaps = DMNSN_PALLOC_ARRAY(pool, dmnsn_object *);
diff --git a/libdimension/csg.c b/libdimension/csg.c
index 713bd16..e31cb0e 100644
--- a/libdimension/csg.c
+++ b/libdimension/csg.c
@@ -26,16 +26,16 @@
 #include "dimension-internal.h"
 #include <stdlib.h>
 
-/*
- * Unions
- */
+////////////
+// Unions //
+////////////
 
 typedef struct {
   dmnsn_object object;
   dmnsn_bvh *bvh;
 } dmnsn_csg_union;
 
-/** CSG union intersection callback. */
+/// CSG union intersection callback.
 static bool
 dmnsn_csg_union_intersection_fn(const dmnsn_object *object,
                                 dmnsn_line line,
@@ -45,7 +45,7 @@ dmnsn_csg_union_intersection_fn(const dmnsn_object *object,
   return dmnsn_bvh_intersection(csg->bvh, line, intersection, true);
 }
 
-/** CSG union inside callback. */
+/// CSG union inside callback.
 static bool
 dmnsn_csg_union_inside_fn(const dmnsn_object *object, dmnsn_vector point)
 {
@@ -53,7 +53,7 @@ dmnsn_csg_union_inside_fn(const dmnsn_object *object, dmnsn_vector point)
   return dmnsn_bvh_inside(csg->bvh, point);
 }
 
-/** CSG union precomputation callback. */
+/// CSG union precomputation callback.
 static void
 dmnsn_csg_union_precompute_fn(dmnsn_object *object)
 {
@@ -65,14 +65,14 @@ dmnsn_csg_union_precompute_fn(dmnsn_object *object)
   csg->object.bounding_box = dmnsn_bvh_bounding_box(bvh);
 }
 
-/** CSG union vtable. */
+/// CSG union vtable.
 static const dmnsn_object_vtable dmnsn_csg_union_vtable = {
   .intersection_fn = dmnsn_csg_union_intersection_fn,
   .inside_fn = dmnsn_csg_union_inside_fn,
   .precompute_fn = dmnsn_csg_union_precompute_fn,
 };
 
-/** CSG union destruction callback. */
+/// CSG union destruction callback.
 static void
 dmnsn_csg_union_cleanup(void *ptr)
 {
@@ -80,7 +80,7 @@ dmnsn_csg_union_cleanup(void *ptr)
   dmnsn_delete_bvh(csg->bvh);
 }
 
-/* Bulk-load a union */
+// Bulk-load a union
 dmnsn_object *
 dmnsn_new_csg_union(dmnsn_pool *pool, dmnsn_array *objects)
 {
@@ -171,11 +171,11 @@ dmnsn_csg_intersection_fn(const dmnsn_object *csg, dmnsn_line line,
   return true;
 }
 
-/*
- * Intersections
- */
+///////////////////
+// Intersections //
+///////////////////
 
-/** CSG intersection intersection callback. */
+/// CSG intersection intersection callback.
 static bool
 dmnsn_csg_intersection_intersection_fn(const dmnsn_object *csg,
                                        dmnsn_line line,
@@ -184,7 +184,7 @@ dmnsn_csg_intersection_intersection_fn(const dmnsn_object *csg,
   return dmnsn_csg_intersection_fn(csg, line, intersection, true, true);
 }
 
-/** CSG intersection inside callback. */
+/// CSG intersection inside callback.
 static bool
 dmnsn_csg_intersection_inside_fn(const dmnsn_object *csg, dmnsn_vector point)
 {
@@ -193,7 +193,7 @@ dmnsn_csg_intersection_inside_fn(const dmnsn_object *csg, dmnsn_vector point)
   return dmnsn_object_inside(A, point) && dmnsn_object_inside(B, point);
 }
 
-/** CSG intersection precomputation callback. */
+/// CSG intersection precomputation callback.
 static void
 dmnsn_csg_intersection_precompute_fn(dmnsn_object *csg)
 {
@@ -205,7 +205,7 @@ dmnsn_csg_intersection_precompute_fn(dmnsn_object *csg)
   csg->bounding_box.max = dmnsn_vector_min(A->bounding_box.max, B->bounding_box.max);
 }
 
-/** CSG intersection vtable. */
+/// CSG intersection vtable.
 static const dmnsn_object_vtable dmnsn_csg_intersection_vtable = {
   .intersection_fn = dmnsn_csg_intersection_intersection_fn,
   .inside_fn = dmnsn_csg_intersection_inside_fn,
@@ -225,11 +225,11 @@ dmnsn_new_csg_intersection(dmnsn_pool *pool, dmnsn_object *A, dmnsn_object *B)
   return csg;
 }
 
-/*
- * Differences
- */
+/////////////////
+// Differences //
+/////////////////
 
-/** CSG difference intersection callback. */
+/// CSG difference intersection callback.
 static bool
 dmnsn_csg_difference_intersection_fn(const dmnsn_object *csg,
                                      dmnsn_line line,
@@ -238,7 +238,7 @@ dmnsn_csg_difference_intersection_fn(const dmnsn_object *csg,
   return dmnsn_csg_intersection_fn(csg, line, intersection, true, false);
 }
 
-/** CSG difference inside callback. */
+/// CSG difference inside callback.
 static bool
 dmnsn_csg_difference_inside_fn(const dmnsn_object *csg, dmnsn_vector point)
 {
@@ -247,7 +247,7 @@ dmnsn_csg_difference_inside_fn(const dmnsn_object *csg, dmnsn_vector point)
   return dmnsn_object_inside(A, point)  && !dmnsn_object_inside(B, point);
 }
 
-/** CSG difference precomputation callback. */
+/// CSG difference precomputation callback.
 static void
 dmnsn_csg_difference_precompute_fn(dmnsn_object *csg)
 {
@@ -257,7 +257,7 @@ dmnsn_csg_difference_precompute_fn(dmnsn_object *csg)
   csg->bounding_box = A->bounding_box;
 }
 
-/** CSG difference vtable. */
+/// CSG difference vtable.
 static const dmnsn_object_vtable dmnsn_csg_difference_vtable = {
   .intersection_fn = dmnsn_csg_difference_intersection_fn,
   .inside_fn = dmnsn_csg_difference_inside_fn,
@@ -277,11 +277,11 @@ dmnsn_new_csg_difference(dmnsn_pool *pool, dmnsn_object *A, dmnsn_object *B)
   return csg;
 }
 
-/*
- * Merges
- */
+////////////
+// Merges //
+////////////
 
-/** CSG merge intersection callback. */
+/// CSG merge intersection callback.
 static bool
 dmnsn_csg_merge_intersection_fn(const dmnsn_object *csg,
                                 dmnsn_line line,
@@ -290,7 +290,7 @@ dmnsn_csg_merge_intersection_fn(const dmnsn_object *csg,
   return dmnsn_csg_intersection_fn(csg, line, intersection, false, false);
 }
 
-/** CSG merge inside callback. */
+/// CSG merge inside callback.
 static bool
 dmnsn_csg_merge_inside_fn(const dmnsn_object *csg, dmnsn_vector point)
 {
@@ -299,7 +299,7 @@ dmnsn_csg_merge_inside_fn(const dmnsn_object *csg, dmnsn_vector point)
   return dmnsn_object_inside(A, point) || dmnsn_object_inside(B, point);
 }
 
-/** CSG merge precomputation callback. */
+/// CSG merge precomputation callback.
 static void
 dmnsn_csg_merge_precompute_fn(dmnsn_object *csg)
 {
@@ -311,7 +311,7 @@ dmnsn_csg_merge_precompute_fn(dmnsn_object *csg)
   csg->bounding_box.max = dmnsn_vector_max(A->bounding_box.max, B->bounding_box.max);
 }
 
-/** CSG merge vtable. */
+/// CSG merge vtable.
 static const dmnsn_object_vtable dmnsn_csg_merge_vtable = {
   .intersection_fn = dmnsn_csg_merge_intersection_fn,
   .inside_fn = dmnsn_csg_merge_inside_fn,
diff --git a/libdimension/cube.c b/libdimension/cube.c
index 4c1b955..c455467 100644
--- a/libdimension/cube.c
+++ b/libdimension/cube.c
@@ -26,12 +26,12 @@
 #include "dimension.h"
 #include <math.h>
 
-/** Intersection callback for a cube. */
+/// Intersection callback for a cube.
 static bool
 dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line,
                            dmnsn_intersection *intersection)
 {
-  /* Clip the given line against the X, Y, and Z slabs */
+  // Clip the given line against the X, Y, and Z slabs
 
   dmnsn_vector nmin, nmax;
   double tmin, tmax;
@@ -120,7 +120,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line,
   }
 }
 
-/** Inside callback for a cube. */
+/// Inside callback for a cube.
 static bool
 dmnsn_cube_inside_fn(const dmnsn_object *cube, dmnsn_vector point)
 {
@@ -129,7 +129,7 @@ dmnsn_cube_inside_fn(const dmnsn_object *cube, dmnsn_vector point)
       && point.z > -1.0 && point.z < 1.0;
 }
 
-/** Boundary callback for a cube. */
+/// Boundary callback for a cube.
 static dmnsn_bounding_box
 dmnsn_cube_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
 {
@@ -137,14 +137,14 @@ dmnsn_cube_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
   return dmnsn_transform_bounding_box(trans, box);
 }
 
-/** Cube vtable. */
+/// Cube vtable.
 static const dmnsn_object_vtable dmnsn_cube_vtable = {
   .intersection_fn = dmnsn_cube_intersection_fn,
   .inside_fn = dmnsn_cube_inside_fn,
   .bounding_fn = dmnsn_cube_bounding_fn,
 };
 
-/* Allocate a new cube object */
+// Allocate a new cube object
 dmnsn_object *
 dmnsn_new_cube(dmnsn_pool *pool)
 {
diff --git a/libdimension/dictionary.c b/libdimension/dictionary.c
index 4001d2f..84ebedf 100644
--- a/libdimension/dictionary.c
+++ b/libdimension/dictionary.c
@@ -26,10 +26,10 @@
 #include "dimension.h"
 
 struct dmnsn_dictionary {
-  size_t obj_size;       /**< The size of the objects in the trie. */
-  char *prefix;          /**< The local string prefix of the current node. */
-  void *value;           /**< The node's stored object, if it's a leaf. */
-  dmnsn_array *children; /**< The node's children. */
+  size_t obj_size;       ///< The size of the objects in the trie.
+  char *prefix;          ///< The local string prefix of the current node.
+  void *value;           ///< The node's stored object, if it's a leaf.
+  dmnsn_array *children; ///< The node's children.
 };
 
 dmnsn_dictionary *
@@ -73,10 +73,8 @@ dmnsn_dictionary_get(const dmnsn_dictionary *dict, const char *key, void *obj)
 void *
 dmnsn_dictionary_at(const dmnsn_dictionary *dict, const char *key)
 {
-  /*
-   * PATRICIA trie search: O(k), where k is the length of the longest string
-   * in the trie.
-   */
+  // PATRICIA trie search: O(k), where k is the length of the longest string in
+  // the trie.
 
   size_t len = strlen(dict->prefix);
   if (strncmp(key, dict->prefix, len) != 0)
@@ -110,16 +108,14 @@ void
 dmnsn_dictionary_insert(dmnsn_dictionary *dict, const char *key,
                         const void *obj)
 {
-  /*
-   * PATRICIA trie insertion: O(k), where k is the length of the longest string
-   * in the trie.
-   */
+  // PATRICIA trie insertion: O(k), where k is the length of the longest string
+  // in the trie.
 
   while (true) {
     if (dict->prefix[0] == '\0' && !dict->value
         && dmnsn_array_size(dict->children) == 0)
     {
-      /* Replace an empty tree with a single-element tree */
+      // Replace an empty tree with a single-element tree
       dict->prefix = dmnsn_realloc(dict->prefix, strlen(key) + 1);
       strcpy(dict->prefix, key);
 
@@ -135,14 +131,14 @@ dmnsn_dictionary_insert(dmnsn_dictionary *dict, const char *key,
     }
 
     if (*key == '\0' && *prefix == '\0') {
-      /* Complete match */
+      // Complete match
       if (!dict->value) {
         dict->value = dmnsn_malloc(dict->obj_size);
       }
       memcpy(dict->value, obj, dict->obj_size);
       break;
     } else if (*prefix == '\0') {
-      /* Partial match; key starts with prefix */
+      // Partial match; key starts with prefix
       dmnsn_dictionary **first = dmnsn_array_first(dict->children), **subtrie;
       ptrdiff_t size = dmnsn_array_size(dict->children);
       for (subtrie = first; subtrie - first < size; ++subtrie) {
@@ -153,13 +149,13 @@ dmnsn_dictionary_insert(dmnsn_dictionary *dict, const char *key,
       }
 
       if (subtrie - first == size) {
-        /* No submatch found, add a new child */
+        // No submatch found, add a new child
         dmnsn_dictionary *child = dmnsn_new_dictionary(dict->obj_size);
         dmnsn_array_push(dict->children, &child);
         dict = child;
       }
     } else {
-      /* Split the tree */
+      // Split the tree
       dmnsn_dictionary *copy = dmnsn_new_dictionary(dict->obj_size);
       copy->prefix = dmnsn_realloc(copy->prefix, strlen(prefix) + 1);
       strcpy(copy->prefix, prefix);
@@ -183,13 +179,11 @@ dmnsn_dictionary_insert(dmnsn_dictionary *dict, const char *key,
 bool
 dmnsn_dictionary_remove(dmnsn_dictionary *dict, const char *key)
 {
-  /*
-   * PATRICIA trie removal: O(k), where k is the length of the longest string
-   * in the trie.
-   *
-   * This implementation doesn't actually collapse the tree back upwards if a
-   * node is left with only one child, to reduce complexity.
-   */
+  // PATRICIA trie removal: O(k), where k is the length of the longest string
+  // in the trie.
+
+  // This implementation doesn't actually collapse the tree back upwards if a
+  // node is left with only one child, to reduce complexity.
 
   size_t len = strlen(dict->prefix);
   if (strncmp(key, dict->prefix, len) != 0)
diff --git a/libdimension/dimension-internal.h b/libdimension/dimension-internal.h
index 197447f..53fa24c 100644
--- a/libdimension/dimension-internal.h
+++ b/libdimension/dimension-internal.h
@@ -37,4 +37,4 @@
 #include "prtree.h"
 #include "rgba.h"
 
-#endif /* DIMENSION_INTERNAL_H */
+#endif // DIMENSION_INTERNAL_H
diff --git a/libdimension/error.c b/libdimension/error.c
index 1facc72..cdc9e31 100644
--- a/libdimension/error.c
+++ b/libdimension/error.c
@@ -30,7 +30,7 @@
 #include <stdlib.h>
 #include <errno.h>
 
-/** Report internal errors in this file. */
+/// Report internal errors in this file.
 #define DMNSN_LOCAL_ERROR(str)                          \
   do {                                                  \
     fprintf(stderr, "Dimension ERROR: %s, %s:%u: %s\n", \
@@ -38,7 +38,7 @@
     abort();                                            \
   } while (0)
 
-/** dmnsn_local_lock_mutex implementation. */
+/// dmnsn_local_lock_mutex implementation.
 static void
 dmnsn_local_lock_mutex_impl(pthread_mutex_t *mutex)
 {
@@ -47,7 +47,7 @@ dmnsn_local_lock_mutex_impl(pthread_mutex_t *mutex)
   }
 }
 
-/** dmnsn_local_unlock_mutex implementation. */
+/// dmnsn_local_unlock_mutex implementation.
 static void
 dmnsn_local_unlock_mutex_impl(pthread_mutex_t *mutex)
 {
@@ -56,32 +56,32 @@ dmnsn_local_unlock_mutex_impl(pthread_mutex_t *mutex)
   }
 }
 
-/** Lock a mutex, bailing out without dmnsn_error() on error. */
+/// Lock a mutex, bailing out without dmnsn_error() on error.
 #define dmnsn_local_lock_mutex(mutex)           \
   dmnsn_local_lock_mutex_impl((mutex)); {
-/** Unlock a mutex, bailing out without dmnsn_error() on error. */
+/// Unlock a mutex, bailing out without dmnsn_error() on error.
 #define dmnsn_local_unlock_mutex(mutex)         \
   dmnsn_local_unlock_mutex_impl((mutex)); }
 
-/** The default fatal error handler. */
+/// The default fatal error handler.
 static void dmnsn_default_fatal_error_fn(void);
 
-/** The current fatal error handler. */
+/// The current fatal error handler.
 static dmnsn_fatal_error_fn *dmnsn_fatal = dmnsn_default_fatal_error_fn;
-/** Mutex which protects \c dmnsn_fatal. */
+/// Mutex which protects \c dmnsn_fatal.
 static pthread_mutex_t dmnsn_fatal_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-/** The current resilience. */
+/// The current resilience.
 static bool dmnsn_always_die = false;
-/** Mutex which protects \c dmnsn_always_die. */
+/// Mutex which protects \c dmnsn_always_die.
 static pthread_mutex_t dmnsn_always_die_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-/* Called by dmnsn_error macro (don't call directly) */
+// Called by dmnsn_error macro (don't call directly)
 void
 dmnsn_report_error(bool die, const char *func, const char *file,
                    unsigned int line, const char *str)
 {
-  /* Save the value of errno */
+  // Save the value of errno
   int err = errno;
 
   bool always_die;
@@ -89,11 +89,11 @@ dmnsn_report_error(bool die, const char *func, const char *file,
     always_die = dmnsn_always_die;
   dmnsn_local_unlock_mutex(&dmnsn_always_die_mutex);
 
-  /* Print the diagnostic string */
+  // Print the diagnostic string
   fprintf(stderr, "Dimension %s: %s, %s:%u: %s\n",
           die ? "ERROR" : "WARNING", func, file, line, str);
 
-  /* Print the value of errno */
+  // Print the value of errno
   if (err != 0) {
     fprintf(stderr, "Last error: %d", err);
 #if DMNSN_STRERROR_R
@@ -109,17 +109,17 @@ dmnsn_report_error(bool die, const char *func, const char *file,
     fprintf(stderr, "\n");
   }
 
-  /* Print a stack trace to standard error */
+  // Print a stack trace to standard error
   dmnsn_backtrace(stderr);
 
-  /* Call the fatal error handler if needed */
+  // Call the fatal error handler if needed
   if (die || always_die) {
     static __thread bool thread_exiting = false;
 
     if (thread_exiting) {
       if (die) {
-        /* Prevent infinite recursion if the fatal error function itself calls
-           dmnsn_error() (not dmnsn_warning()) */
+        // Prevent infinite recursion if the fatal error function itself calls
+        // dmnsn_error() (not dmnsn_warning()) */
         DMNSN_LOCAL_ERROR("Error raised while in error handler, aborting.");
       }
     } else {
diff --git a/libdimension/future-internal.h b/libdimension/future-internal.h
index 5fcd553..7ca318a 100644
--- a/libdimension/future-internal.h
+++ b/libdimension/future-internal.h
@@ -25,47 +25,47 @@
 
 #include <pthread.h>
 
-/** Allocate a new future object. */
+/// Allocate a new future object.
 DMNSN_INTERNAL dmnsn_future *dmnsn_new_future(void);
 
-/** Set the total number of loop iterations. */
+/// Set the total number of loop iterations.
 DMNSN_INTERNAL void dmnsn_future_set_total(dmnsn_future *future, size_t total);
-/** Increment the progress of a background task. */
+/// Increment the progress of a background task.
 DMNSN_INTERNAL void dmnsn_future_increment(dmnsn_future *future);
-/** Instantly complete the background teask. */
+/// Instantly complete the background teask.
 DMNSN_INTERNAL void dmnsn_future_finish(dmnsn_future *future);
-/** Set the number of worker threads. */
+/// Set the number of worker threads.
 DMNSN_INTERNAL void dmnsn_future_set_nthreads(dmnsn_future *future,
                                               unsigned int nthreads);
-/** Notify completion of a worker thread. */
+/// Notify completion of a worker thread.
 DMNSN_INTERNAL void dmnsn_future_finish_thread(dmnsn_future *future);
 
 struct dmnsn_future {
-  size_t progress; /**< Completed loop iterations. */
-  size_t total;    /**< Total expected loop iterations. */
+  size_t progress; ///< Completed loop iterations.
+  size_t total;    ///< Total expected loop iterations.
 
-  /** The worker thread. */
+  /// The worker thread.
   pthread_t thread;
 
-  /** Mutex to guard progress and total. */
+  /// Mutex to guard progress and total.
   pthread_mutex_t mutex;
 
-  /** Condition variable for waiting for a particular amount of progress. */
+  /// Condition variable for waiting for a particular amount of progress.
   pthread_cond_t cond;
 
-  /** Minimum waited-on value. */
+  /// Minimum waited-on value.
   double min_wait;
 
-  /** Number of threads working on the future's background task. */
+  /// Number of threads working on the future's background task.
   unsigned int nthreads;
-  /** Number of threads not yet paused. */
+  /// Number of threads not yet paused.
   unsigned int nrunning;
-  /** Count of threads holding the future paused. */
+  /// Count of threads holding the future paused.
   unsigned int npaused;
-  /** Condition variable for waiting for nrunning == 0. */
+  /// Condition variable for waiting for nrunning == 0.
   pthread_cond_t none_running_cond;
-  /** Condition variable for waiting for nrunning == nthreads. */
+  /// Condition variable for waiting for nrunning == nthreads.
   pthread_cond_t all_running_cond;
-  /** Condition variable for waiting for npaused == 0. */
+  /// Condition variable for waiting for npaused == 0.
   pthread_cond_t resume_cond;
 };
diff --git a/libdimension/future.c b/libdimension/future.c
index 0b16234..ef3f5e2 100644
--- a/libdimension/future.c
+++ b/libdimension/future.c
@@ -33,7 +33,7 @@
  */
 #define MUTATE(future) ((dmnsn_future *)(future))
 
-/* Allocate a new dmnsn_future* */
+// Allocate a new dmnsn_future*
 dmnsn_future *
 dmnsn_new_future(void)
 {
@@ -68,7 +68,7 @@ dmnsn_delete_future(dmnsn_future *future)
   }
 }
 
-/* Join the worker thread and delete `future'. */
+// Join the worker thread and delete `future'.
 int
 dmnsn_future_join(dmnsn_future *future)
 {
@@ -78,21 +78,21 @@ dmnsn_future_join(dmnsn_future *future)
   if (future) {
     dmnsn_assert(future->npaused == 0, "Attempt to join future while paused");
 
-    /* Get the thread's return value */
+    // Get the thread's return value
     dmnsn_join_thread(future->thread, &ptr);
     if (ptr && ptr != PTHREAD_CANCELED) {
       retval = *(int *)ptr;
       dmnsn_free(ptr);
     }
 
-    /* Free the future object */
+    // Free the future object
     dmnsn_delete_future(future);
   }
 
   return retval;
 }
 
-/* Cancel a background thread */
+// Cancel a background thread
 void
 dmnsn_future_cancel(dmnsn_future *future)
 {
@@ -110,7 +110,7 @@ dmnsn_future_progress_unlocked(const dmnsn_future *future)
   return (double)future->progress/future->total;
 }
 
-/* Get the current progress of the worker thread, in [0.0, 1.0] */
+// Get the current progress of the worker thread, in [0.0, 1.0]
 double
 dmnsn_future_progress(const dmnsn_future *future)
 {
@@ -124,7 +124,7 @@ dmnsn_future_progress(const dmnsn_future *future)
   return progress;
 }
 
-/* Find out whether the task is complete. */
+// Find out whether the task is complete.
 bool
 dmnsn_future_is_done(const dmnsn_future *future)
 {
@@ -138,7 +138,7 @@ dmnsn_future_is_done(const dmnsn_future *future)
   return result;
 }
 
-/* Wait until dmnsn_future_progress(future) >= progress */
+// Wait until dmnsn_future_progress(future) >= progress
 void
 dmnsn_future_wait(const dmnsn_future *future, double progress)
 {
@@ -146,7 +146,7 @@ dmnsn_future_wait(const dmnsn_future *future, double progress)
 
   dmnsn_lock_mutex(&mfuture->mutex);
     while (dmnsn_future_progress_unlocked(mfuture) < progress) {
-      /* Set the minimum waited-on value */
+      // Set the minimum waited-on value
       if (progress < mfuture->min_wait) {
         mfuture->min_wait = progress;
       }
@@ -156,7 +156,7 @@ dmnsn_future_wait(const dmnsn_future *future, double progress)
   dmnsn_unlock_mutex(&mfuture->mutex);
 }
 
-/* Pause all threads working on a future. */
+// Pause all threads working on a future.
 void
 dmnsn_future_pause(dmnsn_future *future)
 {
@@ -172,7 +172,7 @@ dmnsn_future_pause(dmnsn_future *future)
   dmnsn_unlock_mutex(&future->mutex);
 }
 
-/* Resume all threads working on a future. */
+// Resume all threads working on a future.
 void
 dmnsn_future_resume(dmnsn_future *future)
 {
@@ -185,7 +185,7 @@ dmnsn_future_resume(dmnsn_future *future)
   dmnsn_unlock_mutex(&future->mutex);
 }
 
-/* Set the total number of loop iterations */
+// Set the total number of loop iterations
 void
 dmnsn_future_set_total(dmnsn_future *future, size_t total)
 {
@@ -202,13 +202,13 @@ dmnsn_future_increment_cleanup(void *ptr)
   dmnsn_unlock_mutex_impl(&future->mutex);
 }
 
-/* Increment the number of completed loop iterations */
+// Increment the number of completed loop iterations
 void
 dmnsn_future_increment(dmnsn_future *future)
 {
-  /* Allow a thread to be canceled whenever it increments a future object --
-     this is close to PTHREAD_CANCEL_ASYNCHRONOUS but allows consistent state
-     on cancellation */
+  // Allow a thread to be canceled whenever it increments a future object --
+  // this is close to PTHREAD_CANCEL_ASYNCHRONOUS but allows consistent state
+  // on cancellation
   pthread_testcancel();
 
   dmnsn_lock_mutex(&future->mutex);
@@ -239,7 +239,7 @@ dmnsn_future_increment(dmnsn_future *future)
   dmnsn_unlock_mutex(&future->mutex);
 }
 
-/* Immediately set to 100% completion */
+// Immediately set to 100% completion
 void
 dmnsn_future_finish(dmnsn_future *future)
 {
@@ -252,7 +252,7 @@ dmnsn_future_finish(dmnsn_future *future)
   dmnsn_unlock_mutex(&future->mutex);
 }
 
-/* Set the number of threads */
+// Set the number of threads
 void
 dmnsn_future_set_nthreads(dmnsn_future *future, unsigned int nthreads)
 {
@@ -263,7 +263,7 @@ dmnsn_future_set_nthreads(dmnsn_future *future, unsigned int nthreads)
   dmnsn_unlock_mutex(&future->mutex);
 }
 
-/* Notify completion of a worker thread */
+// Notify completion of a worker thread
 void
 dmnsn_future_finish_thread(dmnsn_future *future)
 {
diff --git a/libdimension/geometry.c b/libdimension/geometry.c
index c6a4da2..1ec2801 100644
--- a/libdimension/geometry.c
+++ b/libdimension/geometry.c
@@ -26,7 +26,7 @@
 #include "dimension-internal.h"
 #include <math.h>
 
-/* Identity matrix */
+// Identity matrix
 dmnsn_matrix
 dmnsn_identity_matrix(void)
 {
@@ -35,7 +35,7 @@ dmnsn_identity_matrix(void)
                           0.0, 0.0, 1.0, 0.0);
 }
 
-/* Scaling matrix */
+// Scaling matrix
 dmnsn_matrix
 dmnsn_scale_matrix(dmnsn_vector s)
 {
@@ -44,7 +44,7 @@ dmnsn_scale_matrix(dmnsn_vector s)
                           0.0, 0.0, s.z, 0.0);
 }
 
-/* Translation matrix */
+// Translation matrix
 dmnsn_matrix
 dmnsn_translation_matrix(dmnsn_vector d)
 {
@@ -53,11 +53,11 @@ dmnsn_translation_matrix(dmnsn_vector d)
                           0.0, 0.0, 1.0, d.z);
 }
 
-/* Left-handed rotation matrix; theta/|theta| = axis, |theta| = angle */
+// Left-handed rotation matrix; theta/|theta| = axis, |theta| = angle
 dmnsn_matrix
 dmnsn_rotation_matrix(dmnsn_vector theta)
 {
-  /* Two trig calls, 25 multiplications, 13 additions */
+  // Two trig calls, 25 multiplications, 13 additions
 
   double angle = dmnsn_vector_norm(theta);
   if (fabs(angle) < dmnsn_epsilon) {
@@ -65,7 +65,7 @@ dmnsn_rotation_matrix(dmnsn_vector theta)
   }
   dmnsn_vector axis = dmnsn_vector_div(theta, angle);
 
-  /* Shorthand to make dmnsn_new_matrix() call legible */
+  // Shorthand to make dmnsn_new_matrix() call legible
 
   double s = sin(angle);
   double t = 1.0 - cos(angle);
@@ -81,7 +81,7 @@ dmnsn_rotation_matrix(dmnsn_vector theta)
   );
 }
 
-/* Find the angle between two vectors with respect to an axis */
+// Find the angle between two vectors with respect to an axis
 static double
 dmnsn_axis_angle(dmnsn_vector from, dmnsn_vector to, dmnsn_vector axis)
 {
@@ -106,7 +106,7 @@ dmnsn_axis_angle(dmnsn_vector from, dmnsn_vector to, dmnsn_vector axis)
   }
 }
 
-/* Alignment matrix */
+// Alignment matrix
 dmnsn_matrix
 dmnsn_alignment_matrix(dmnsn_vector from, dmnsn_vector to,
                        dmnsn_vector axis1, dmnsn_vector axis2)
@@ -122,67 +122,63 @@ dmnsn_alignment_matrix(dmnsn_vector from, dmnsn_vector to,
   return dmnsn_matrix_mul(align2, align1);
 }
 
-/* Matrix inversion helper functions */
+// Matrix inversion helper functions
 
-/** A 2x2 matrix for inversion by partitioning. */
+/// A 2x2 matrix for inversion by partitioning.
 typedef struct { double n[2][2]; } dmnsn_matrix2;
 
-/** Construct a 2x2 matrix. */
+/// Construct a 2x2 matrix.
 static dmnsn_matrix2 dmnsn_new_matrix2(double a1, double a2,
                                        double b1, double b2);
-/** Invert a 2x2 matrix. */
+/// Invert a 2x2 matrix.
 static dmnsn_matrix2 dmnsn_matrix2_inverse(dmnsn_matrix2 A);
-/** Negate a 2x2 matrix. */
+/// Negate a 2x2 matrix.
 static dmnsn_matrix2 dmnsn_matrix2_negate(dmnsn_matrix2 A);
-/** Subtract two 2x2 matricies. */
+/// Subtract two 2x2 matricies.
 static dmnsn_matrix2 dmnsn_matrix2_sub(dmnsn_matrix2 lhs, dmnsn_matrix2 rhs);
-/** Add two 2x2 matricies. */
+/// Add two 2x2 matricies.
 static dmnsn_matrix2 dmnsn_matrix2_mul(dmnsn_matrix2 lhs, dmnsn_matrix2 rhs);
 
-/** Invert a matrix with the slower cofactor algorithm, if partitioning
-    failed.  */
+/// Invert a matrix with the slower cofactor algorithm, if partitioning failed.
 static dmnsn_matrix dmnsn_matrix_inverse_generic(dmnsn_matrix A);
-/** Get the [\p row, \p col] cofactor of A. */
+/// Get the [\p row, \p col] cofactor of A.
 static double dmnsn_matrix_cofactor(dmnsn_matrix A,
                                     unsigned int row, unsigned int col);
 
-/* Invert a matrix, by partitioning */
+// Invert a matrix, by partitioning
 dmnsn_matrix
 dmnsn_matrix_inverse(dmnsn_matrix A)
 {
-  /*
-   * Use partitioning to invert a matrix:
-   *
-   *     [ P Q ] -1
-   *     [ R S ]
-   *
-   *   = [ PP QQ ]
-   *     [ RR SS ],
-   *
-   * with PP = inv(P) - inv(P)*Q*RR,
-   *      QQ = -inv(P)*Q*SS,
-   *      RR = -SS*R*inv(P), and
-   *      SS = inv(S - R*inv(P)*Q).
-   */
-
-  /* The algorithm uses 2 inversions, 6 multiplications, and 2 subtractions,
-     giving 52 multiplications, 34 additions, and 8 divisions. */
+  // Use partitioning to invert a matrix:
+  //
+  //     [ P Q ] -1
+  //     [ R S ]
+  //
+  //   = [ PP QQ ]
+  //     [ RR SS ],
+  //
+  // with PP = inv(P) - inv(P)*Q*RR,
+  //      QQ = -inv(P)*Q*SS,
+  //      RR = -SS*R*inv(P), and
+  //      SS = inv(S - R*inv(P)*Q).
+
+  // The algorithm uses 2 inversions, 6 multiplications, and 2 subtractions,
+  // giving 52 multiplications, 34 additions, and 8 divisions.
 
   dmnsn_matrix2 P, Q, R, S, Pi, RPi, PiQ, RPiQ, PP, QQ, RR, SS;
   double Pdet = A.n[0][0]*A.n[1][1] - A.n[0][1]*A.n[1][0];
 
   if (dmnsn_unlikely(fabs(Pdet) < dmnsn_epsilon)) {
-    /* If P is close to singular, try a more generic algorithm; this is very
-     * unlikely, but not impossible, eg.
-     *   [ 1 1 0 0 ]
-     *   [ 1 1 1 0 ]
-     *   [ 0 1 1 0 ]
-     *   [ 0 0 0 1 ]
-     */
+    // If P is close to singular, try a more generic algorithm; this is very
+    // unlikely, but not impossible, eg.
+    //   [ 1 1 0 0 ]
+    //   [ 1 1 1 0 ]
+    //   [ 0 1 1 0 ]
+    //   [ 0 0 0 1 ]
     return dmnsn_matrix_inverse_generic(A);
   }
 
-  /* Partition the matrix */
+  // Partition the matrix
   P = dmnsn_new_matrix2(A.n[0][0], A.n[0][1],
                         A.n[1][0], A.n[1][1]);
   Q = dmnsn_new_matrix2(A.n[0][2], A.n[0][3],
@@ -192,28 +188,28 @@ dmnsn_matrix_inverse(dmnsn_matrix A)
   S = dmnsn_new_matrix2(A.n[2][2], A.n[2][3],
                         0.0,       1.0);
 
-  /* Do this inversion ourselves, since we already have the determinant */
+  // Do this inversion ourselves, since we already have the determinant
   Pi = dmnsn_new_matrix2( P.n[1][1]/Pdet, -P.n[0][1]/Pdet,
                          -P.n[1][0]/Pdet,  P.n[0][0]/Pdet);
 
-  /* Calculate R*inv(P), inv(P)*Q, and R*inv(P)*Q */
+  // Calculate R*inv(P), inv(P)*Q, and R*inv(P)*Q
   RPi  = dmnsn_matrix2_mul(R, Pi);
   PiQ  = dmnsn_matrix2_mul(Pi, Q);
   RPiQ = dmnsn_matrix2_mul(R, PiQ);
 
-  /* Calculate the partitioned inverse */
+  // Calculate the partitioned inverse
   SS = dmnsn_matrix2_inverse(dmnsn_matrix2_sub(S, RPiQ));
   RR = dmnsn_matrix2_negate(dmnsn_matrix2_mul(SS, RPi));
   QQ = dmnsn_matrix2_negate(dmnsn_matrix2_mul(PiQ, SS));
   PP = dmnsn_matrix2_sub(Pi, dmnsn_matrix2_mul(PiQ, RR));
 
-  /* Reconstruct the matrix */
+  // Reconstruct the matrix
   return dmnsn_new_matrix(PP.n[0][0], PP.n[0][1], QQ.n[0][0], QQ.n[0][1],
                           PP.n[1][0], PP.n[1][1], QQ.n[1][0], QQ.n[1][1],
                           RR.n[0][0], RR.n[0][1], SS.n[0][0], SS.n[0][1]);
 }
 
-/* For nice shorthand */
+// For nice shorthand
 static dmnsn_matrix2
 dmnsn_new_matrix2(double a1, double a2, double b1, double b2)
 {
@@ -222,17 +218,17 @@ dmnsn_new_matrix2(double a1, double a2, double b1, double b2)
   return m;
 }
 
-/* Invert a 2x2 matrix */
+// Invert a 2x2 matrix
 static dmnsn_matrix2
 dmnsn_matrix2_inverse(dmnsn_matrix2 A)
 {
-  /* 4 divisions, 2 multiplications, 1 addition */
+  // 4 divisions, 2 multiplications, 1 addition
   double det = A.n[0][0]*A.n[1][1] - A.n[0][1]*A.n[1][0];
   return dmnsn_new_matrix2( A.n[1][1]/det, -A.n[0][1]/det,
                            -A.n[1][0]/det,  A.n[0][0]/det);
 }
 
-/* Also basically a shorthand */
+// Also basically a shorthand
 static dmnsn_matrix2
 dmnsn_matrix2_negate(dmnsn_matrix2 A)
 {
@@ -240,22 +236,22 @@ dmnsn_matrix2_negate(dmnsn_matrix2 A)
                            -A.n[1][0], -A.n[1][1]);
 }
 
-/* 2x2 matrix subtraction */
+// 2x2 matrix subtraction
 static dmnsn_matrix2
 dmnsn_matrix2_sub(dmnsn_matrix2 lhs, dmnsn_matrix2 rhs)
 {
-  /* 4 additions */
+  // 4 additions
   return dmnsn_new_matrix2(
     lhs.n[0][0] - rhs.n[0][0], lhs.n[0][1] - rhs.n[0][1],
     lhs.n[1][0] - rhs.n[1][0], lhs.n[1][1] - rhs.n[1][1]
   );
 }
 
-/* 2x2 matrix multiplication */
+// 2x2 matrix multiplication
 static dmnsn_matrix2
 dmnsn_matrix2_mul(dmnsn_matrix2 lhs, dmnsn_matrix2 rhs)
 {
-  /* 8 multiplications, 4 additions */
+  // 8 multiplications, 4 additions
   return dmnsn_new_matrix2(
     lhs.n[0][0]*rhs.n[0][0] + lhs.n[0][1]*rhs.n[1][0],
       lhs.n[0][0]*rhs.n[0][1] + lhs.n[0][1]*rhs.n[1][1],
@@ -264,33 +260,31 @@ dmnsn_matrix2_mul(dmnsn_matrix2 lhs, dmnsn_matrix2 rhs)
   );
 }
 
-/* Invert a matrix, if partitioning failed (|P| == 0) */
+// Invert a matrix, if partitioning failed (|P| == 0)
 static dmnsn_matrix
 dmnsn_matrix_inverse_generic(dmnsn_matrix A)
 {
-  /*
-   * For A = [ A'      b ], A^-1 = [ A'^-1   -(A'^-1)*b ].
-   *         [ 0 ... 0 1 ]         [ 0 ... 0      1     ]
-   *
-   * Invert A' by calculating its adjucate.
-   */
+  // For A = [ A'      b ]  A^-1 = [ A'^-1   -(A'^-1)*b ]
+  //         [ 0 ... 0 1 ],        [ 0 ... 0      1     ].
+  //
+  // Invert A' by calculating its adjucate.
   dmnsn_matrix inv;
   double det = 0.0, C;
 
-  /* Perform a Laplace expansion along the first row to give us the adjugate's
-     first column and the determinant */
+  // Perform a Laplace expansion along the first row to give us the adjugate's
+  // first column and the determinant
   for (size_t j = 0; j < 3; ++j) {
     C = dmnsn_matrix_cofactor(A, 0, j);
     det += A.n[0][j]*C;
     inv.n[j][0] = C;
   }
 
-  /* Divide the first column by the determinant */
+  // Divide the first column by the determinant
   for (size_t j = 0; j < 3; ++j) {
     inv.n[j][0] /= det;
   }
 
-  /* Find the rest of A' */
+  // Find the rest of A'
   for (size_t j = 0; j < 3; ++j) {
     for (size_t i = 1; i < 3; ++i) {
       inv.n[j][i] = dmnsn_matrix_cofactor(A, i, j)/det;
@@ -298,7 +292,7 @@ dmnsn_matrix_inverse_generic(dmnsn_matrix A)
     inv.n[j][3] = 0.0;
   }
 
-  /* Find the translational component of the inverse */
+  // Find the translational component of the inverse
   for (size_t i = 0; i < 3; ++i) {
     for (size_t j = 0; j < 3; ++j) {
       inv.n[i][3] -= inv.n[i][j]*A.n[j][3];
@@ -308,13 +302,13 @@ dmnsn_matrix_inverse_generic(dmnsn_matrix A)
   return inv;
 }
 
-/* Gives the cofactor at row, col; the determinant of the matrix formed from the
-   upper-left 3x3 corner of A by ignoring row `row' and column `col',
-   times (-1)^(row + col) */
+// Gives the cofactor at row, col; the determinant of the matrix formed from the
+// upper-left 3x3 corner of A by ignoring row `row' and column `col',
+// times (-1)^(row + col)
 static double
 dmnsn_matrix_cofactor(dmnsn_matrix A, unsigned int row, unsigned int col)
 {
-  /* 2 multiplications, 1 addition */
+  // 2 multiplications, 1 addition
   double n[4];
   size_t k = 0;
   for (size_t i = 0; i < 3; ++i) {
@@ -334,48 +328,36 @@ dmnsn_matrix_cofactor(dmnsn_matrix A, unsigned int row, unsigned int col)
   }
 }
 
-/* 4x4 matrix multiplication */
+// 4x4 matrix multiplication
 dmnsn_matrix
 dmnsn_matrix_mul(dmnsn_matrix lhs, dmnsn_matrix rhs)
 {
-  /* 36 multiplications, 27 additions */
+  // 36 multiplications, 27 additions
   dmnsn_matrix r;
 
-  r.n[0][0] = lhs.n[0][0]*rhs.n[0][0] + lhs.n[0][1]*rhs.n[1][0]
-    + lhs.n[0][2]*rhs.n[2][0];
-  r.n[0][1] = lhs.n[0][0]*rhs.n[0][1] + lhs.n[0][1]*rhs.n[1][1]
-    + lhs.n[0][2]*rhs.n[2][1];
-  r.n[0][2] = lhs.n[0][0]*rhs.n[0][2] + lhs.n[0][1]*rhs.n[1][2]
-    + lhs.n[0][2]*rhs.n[2][2];
-  r.n[0][3] = lhs.n[0][0]*rhs.n[0][3] + lhs.n[0][1]*rhs.n[1][3]
-    + lhs.n[0][2]*rhs.n[2][3] + lhs.n[0][3];
-
-  r.n[1][0] = lhs.n[1][0]*rhs.n[0][0] + lhs.n[1][1]*rhs.n[1][0]
-    + lhs.n[1][2]*rhs.n[2][0];
-  r.n[1][1] = lhs.n[1][0]*rhs.n[0][1] + lhs.n[1][1]*rhs.n[1][1]
-    + lhs.n[1][2]*rhs.n[2][1];
-  r.n[1][2] = lhs.n[1][0]*rhs.n[0][2] + lhs.n[1][1]*rhs.n[1][2]
-    + lhs.n[1][2]*rhs.n[2][2];
-  r.n[1][3] = lhs.n[1][0]*rhs.n[0][3] + lhs.n[1][1]*rhs.n[1][3]
-    + lhs.n[1][2]*rhs.n[2][3] + lhs.n[1][3];
-
-  r.n[2][0] = lhs.n[2][0]*rhs.n[0][0] + lhs.n[2][1]*rhs.n[1][0]
-    + lhs.n[2][2]*rhs.n[2][0];
-  r.n[2][1] = lhs.n[2][0]*rhs.n[0][1] + lhs.n[2][1]*rhs.n[1][1]
-    + lhs.n[2][2]*rhs.n[2][1];
-  r.n[2][2] = lhs.n[2][0]*rhs.n[0][2] + lhs.n[2][1]*rhs.n[1][2]
-    + lhs.n[2][2]*rhs.n[2][2];
-  r.n[2][3] = lhs.n[2][0]*rhs.n[0][3] + lhs.n[2][1]*rhs.n[1][3]
-    + lhs.n[2][2]*rhs.n[2][3] + lhs.n[2][3];
+  r.n[0][0] = lhs.n[0][0]*rhs.n[0][0] + lhs.n[0][1]*rhs.n[1][0] + lhs.n[0][2]*rhs.n[2][0];
+  r.n[0][1] = lhs.n[0][0]*rhs.n[0][1] + lhs.n[0][1]*rhs.n[1][1] + lhs.n[0][2]*rhs.n[2][1];
+  r.n[0][2] = lhs.n[0][0]*rhs.n[0][2] + lhs.n[0][1]*rhs.n[1][2] + lhs.n[0][2]*rhs.n[2][2];
+  r.n[0][3] = lhs.n[0][0]*rhs.n[0][3] + lhs.n[0][1]*rhs.n[1][3] + lhs.n[0][2]*rhs.n[2][3] + lhs.n[0][3];
+
+  r.n[1][0] = lhs.n[1][0]*rhs.n[0][0] + lhs.n[1][1]*rhs.n[1][0] + lhs.n[1][2]*rhs.n[2][0];
+  r.n[1][1] = lhs.n[1][0]*rhs.n[0][1] + lhs.n[1][1]*rhs.n[1][1] + lhs.n[1][2]*rhs.n[2][1];
+  r.n[1][2] = lhs.n[1][0]*rhs.n[0][2] + lhs.n[1][1]*rhs.n[1][2] + lhs.n[1][2]*rhs.n[2][2];
+  r.n[1][3] = lhs.n[1][0]*rhs.n[0][3] + lhs.n[1][1]*rhs.n[1][3] + lhs.n[1][2]*rhs.n[2][3] + lhs.n[1][3];
+
+  r.n[2][0] = lhs.n[2][0]*rhs.n[0][0] + lhs.n[2][1]*rhs.n[1][0] + lhs.n[2][2]*rhs.n[2][0];
+  r.n[2][1] = lhs.n[2][0]*rhs.n[0][1] + lhs.n[2][1]*rhs.n[1][1] + lhs.n[2][2]*rhs.n[2][1];
+  r.n[2][2] = lhs.n[2][0]*rhs.n[0][2] + lhs.n[2][1]*rhs.n[1][2] + lhs.n[2][2]*rhs.n[2][2];
+  r.n[2][3] = lhs.n[2][0]*rhs.n[0][3] + lhs.n[2][1]*rhs.n[1][3] + lhs.n[2][2]*rhs.n[2][3] + lhs.n[2][3];
 
   return r;
 }
 
-/* Give an axis-aligned box that contains the given box transformed by `lhs' */
+// Give an axis-aligned box that contains the given box transformed by `lhs'
 dmnsn_bounding_box
 dmnsn_transform_bounding_box(dmnsn_matrix trans, dmnsn_bounding_box box)
 {
-  /* Infinite/zero bounding box support */
+  // Infinite/zero bounding box support
   if (isinf(box.min.x))
     return box;
 
diff --git a/libdimension/gl.c b/libdimension/gl.c
index c6a2da5..2800484 100644
--- a/libdimension/gl.c
+++ b/libdimension/gl.c
@@ -28,7 +28,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 
-/* Optimize canvas for GL drawing */
+// Optimize canvas for GL drawing
 int
 dmnsn_gl_optimize_canvas(dmnsn_canvas *canvas)
 {
@@ -36,14 +36,14 @@ dmnsn_gl_optimize_canvas(dmnsn_canvas *canvas)
   return 0;
 }
 
-/* Write canvas to GL framebuffer.  Returns 0 on success, nonzero on failure */
+// Write canvas to GL framebuffer.  Returns 0 on success, nonzero on failure
 int
 dmnsn_gl_write_canvas(const dmnsn_canvas *canvas)
 {
   size_t width = canvas->width;
   size_t height = canvas->height;
 
-  /* Check if we can optimize this */
+  // Check if we can optimize this
   dmnsn_canvas_optimizer *optimizer =
     dmnsn_canvas_find_optimizer(canvas, dmnsn_rgba8_optimizer_fn);
   if (optimizer) {
@@ -51,7 +51,7 @@ dmnsn_gl_write_canvas(const dmnsn_canvas *canvas)
     return glGetError() == GL_NO_ERROR ? 0 : 1;
   }
 
-  /* We couldn't, so transform the canvas to RGB now */
+  // We couldn't, so transform the canvas to RGB now
   GLubyte *pixels = dmnsn_malloc(4*width*height*sizeof(GLubyte));
 
   for (size_t y = 0; y < height; ++y) {
@@ -76,14 +76,14 @@ dmnsn_gl_write_canvas(const dmnsn_canvas *canvas)
   return glGetError() == GL_NO_ERROR ? 0 : 1;
 }
 
-/* Read a canvas from a GL framebuffer.  Returns NULL on failure. */
+// Read a canvas from a GL framebuffer.  Returns NULL on failure.
 int
 dmnsn_gl_read_canvas(dmnsn_canvas *canvas, size_t x0, size_t y0)
 {
   size_t width = canvas->width;
   size_t height = canvas->height;
 
-  /* Array of 16-bit ints in RGBA order */
+  // Array of 16-bit ints in RGBA order
   GLushort *pixels = dmnsn_malloc(4*width*height*sizeof(GLushort));
   glReadPixels(x0, y0, width, height, GL_RGBA, GL_UNSIGNED_SHORT, pixels);
   if (glGetError() != GL_NO_ERROR) {
diff --git a/libdimension/gradient.c b/libdimension/gradient.c
index 2e28974..74e8045 100644
--- a/libdimension/gradient.c
+++ b/libdimension/gradient.c
@@ -25,13 +25,13 @@
 
 #include "dimension.h"
 
-/** Gradient pattern type. */
+/// Gradient pattern type.
 typedef struct dmnns_gradient {
   dmnsn_pattern pattern;
   dmnsn_vector orientation;
 } dmnsn_gradient;
 
-/** Gradient pattern callback. */
+/// Gradient pattern callback.
 static double
 dmnsn_gradient_pattern_fn(const dmnsn_pattern *pattern, dmnsn_vector v)
 {
diff --git a/libdimension/inline.c b/libdimension/inline.c
index 6b8b29d..ae175e0 100644
--- a/libdimension/inline.c
+++ b/libdimension/inline.c
@@ -23,20 +23,20 @@
  * Emit definitions of inline functions, if necessary.
  */
 
-/* Set DMNSN_INLINE to produce definitions of inline functions, emitted here,
-   if needed */
+// Set DMNSN_INLINE to produce definitions of inline functions, emitted here,
+// if needed
 #ifdef __cplusplus
-  /* C++ inline semantics */
+  // C++ inline semantics
   #define DMNSN_INLINE inline
 #elif __STDC_VERSION__ >= 199901L
-  /* C99 inline semantics */
+  // C99 inline semantics
   #define DMNSN_INLINE
 #elif defined(__GNUC__)
-  /* GCC inline semantics */
+  // GCC inline semantics
   #define DMNSN_INLINE __inline__
 #else
-  /* Unknown C - mark functions static and hope the compiler is smart enough
-     to inline them */
+  // Unknown C - mark functions static and hope the compiler is smart enough to
+  // inline them
   #define DMNSN_INLINE static
 #endif
 
diff --git a/libdimension/interior.c b/libdimension/interior.c
index 7657461..d725b6f 100644
--- a/libdimension/interior.c
+++ b/libdimension/interior.c
@@ -26,7 +26,7 @@
 #include "dimension-internal.h"
 #include <stdlib.h>
 
-/* Allocate an interior */
+// Allocate an interior
 dmnsn_interior *
 dmnsn_new_interior(dmnsn_pool *pool)
 {
@@ -35,7 +35,7 @@ dmnsn_new_interior(dmnsn_pool *pool)
   return interior;
 }
 
-/* Cascade a interior */
+// Cascade an interior
 void
 dmnsn_interior_cascade(dmnsn_interior *default_interior,
                        dmnsn_interior **interiorp)
diff --git a/libdimension/lambertian.c b/libdimension/lambertian.c
index 9360872..cced4a7 100644
--- a/libdimension/lambertian.c
+++ b/libdimension/lambertian.c
@@ -27,13 +27,13 @@
 #include <math.h>
 #include <stdlib.h>
 
-/** Lambertian diffuse type. */
+/// Lambertian diffuse type.
 typedef struct dmnsn_lambertian {
   dmnsn_diffuse diffuse;
   double coeff;
 } dmnsn_lambertian;
 
-/** Diffuse finish callback. */
+/// Diffuse finish callback.
 static dmnsn_color
 dmnsn_lambertian_diffuse_fn(const dmnsn_diffuse *diffuse,
                             dmnsn_color light, dmnsn_color color,
diff --git a/libdimension/leopard.c b/libdimension/leopard.c
index 110c69c..a4000d2 100644
--- a/libdimension/leopard.c
+++ b/libdimension/leopard.c
@@ -26,7 +26,7 @@
 #include "dimension-internal.h"
 #include <math.h>
 
-/** Leopard pattern callback. */
+/// Leopard pattern callback.
 static double
 dmnsn_leopard_pattern_fn(const dmnsn_pattern *leopard, dmnsn_vector v)
 {
@@ -34,7 +34,7 @@ dmnsn_leopard_pattern_fn(const dmnsn_pattern *leopard, dmnsn_vector v)
   return val*val;
 }
 
-/** The singleton instance. */
+/// The singleton instance.
 static dmnsn_pattern dmnsn_leopard_instance = {
   .pattern_fn = dmnsn_leopard_pattern_fn,
 };
diff --git a/libdimension/light.c b/libdimension/light.c
index b1d2108..14917de 100644
--- a/libdimension/light.c
+++ b/libdimension/light.c
@@ -26,7 +26,7 @@
 #include "dimension-internal.h"
 #include <stdlib.h>
 
-/* Allocate a new dummy light */
+// Allocate a new dummy light
 dmnsn_light *
 dmnsn_new_light(dmnsn_pool *pool)
 {
@@ -35,7 +35,7 @@ dmnsn_new_light(dmnsn_pool *pool)
   return light;
 }
 
-/* Initialize a light */
+// Initialize a light
 void
 dmnsn_init_light(dmnsn_light *light)
 {
diff --git a/libdimension/map.c b/libdimension/map.c
index 9a85773..1ae2a10 100644
--- a/libdimension/map.c
+++ b/libdimension/map.c
@@ -25,13 +25,13 @@
 
 #include "dimension.h"
 
-/** dmnsn_map definition. */
+/// dmnsn_map definition.
 struct dmnsn_map {
-  size_t obj_size; /**< @internal The size of the mapped objects. */
-  dmnsn_array *array; /**< @internal The map entries. */
+  size_t obj_size; ///< @internal The size of the mapped objects.
+  dmnsn_array *array; ///< @internal The map entries.
 };
 
-/** An [index, object] pair. */
+/// An [index, object] pair.
 typedef struct dmnsn_map_entry {
   double n;
   char object[];
@@ -54,7 +54,7 @@ dmnsn_map_add_entry(dmnsn_map *map, double n, const void *obj)
   entry->n = n;
   memcpy(entry->object, obj, map->obj_size);
 
-  /* Sorted insertion */
+  // Sorted insertion
   size_t i;
   for (i = dmnsn_array_size(map->array); i-- > 0;) {
     dmnsn_map_entry *other = dmnsn_array_at(map->array, i);
diff --git a/libdimension/object.c b/libdimension/object.c
index 2521353..a67b8cb 100644
--- a/libdimension/object.c
+++ b/libdimension/object.c
@@ -26,7 +26,7 @@
 #include "dimension-internal.h"
 #include <stdlib.h>
 
-/* Allocate a dummy object */
+// Allocate a dummy object
 dmnsn_object *
 dmnsn_new_object(dmnsn_pool *pool)
 {
@@ -35,7 +35,7 @@ dmnsn_new_object(dmnsn_pool *pool)
   return object;
 }
 
-/* Initialize a dmnsn_object field */
+// Initialize a dmnsn_object field
 void
 dmnsn_init_object(dmnsn_object *object)
 {
@@ -49,7 +49,7 @@ dmnsn_init_object(dmnsn_object *object)
   object->precomputed = false;
 }
 
-/** Recursively precompute objects. */
+/// Recursively precompute objects.
 static void
 dmnsn_object_precompute_recursive(dmnsn_object *object, dmnsn_matrix pigment_trans)
 {
@@ -61,14 +61,14 @@ dmnsn_object_precompute_recursive(dmnsn_object *object, dmnsn_matrix pigment_tra
   dmnsn_assert(vtable->inside_fn, "Missing inside function.");
   dmnsn_assert(vtable->bounding_fn || vtable->precompute_fn, "Missing bounding and precompute function.");
 
-  /* Initialize the texture */
+  // Initialize the texture
   if (!object->texture->initialized) {
     dmnsn_texture_initialize(object->texture);
   }
 
   dmnsn_matrix total_trans = dmnsn_matrix_mul(object->trans, object->intrinsic_trans);
 
-  /* Precompute the object's children */
+  // Precompute the object's children
   if (object->children) {
     DMNSN_ARRAY_FOREACH (dmnsn_object **, child, object->children) {
       dmnsn_matrix saved_trans = (*child)->trans;
@@ -76,7 +76,7 @@ dmnsn_object_precompute_recursive(dmnsn_object *object, dmnsn_matrix pigment_tra
 
       dmnsn_matrix child_pigment_trans;
       if ((*child)->texture == NULL || (*child)->texture->pigment == NULL) {
-        /* Don't transform cascaded pigments with the child object */
+        // Don't transform cascaded pigments with the child object
         child_pigment_trans = pigment_trans;
       } else {
         child_pigment_trans = dmnsn_matrix_inverse((*child)->trans);
@@ -89,7 +89,7 @@ dmnsn_object_precompute_recursive(dmnsn_object *object, dmnsn_matrix pigment_tra
     }
   }
 
-  /* Precalculate object values */
+  // Precalculate object values
   object->pigment_trans = pigment_trans;
   object->trans_inv = dmnsn_matrix_inverse(total_trans);
   if (vtable->bounding_fn) {
@@ -100,7 +100,7 @@ dmnsn_object_precompute_recursive(dmnsn_object *object, dmnsn_matrix pigment_tra
   }
 }
 
-/* Precompute object properties */
+// Precompute object properties
 void
 dmnsn_object_precompute(dmnsn_object *object)
 {
diff --git a/libdimension/perspective.c b/libdimension/perspective.c
index a87f673..518e52e 100644
--- a/libdimension/perspective.c
+++ b/libdimension/perspective.c
@@ -26,7 +26,7 @@
 #include "dimension.h"
 #include <stdlib.h>
 
-/** Perspective camera ray callback. */
+/// Perspective camera ray callback.
 static dmnsn_line
 dmnsn_perspective_camera_ray_fn(const dmnsn_camera *camera, double x, double y)
 {
@@ -37,7 +37,7 @@ dmnsn_perspective_camera_ray_fn(const dmnsn_camera *camera, double x, double y)
   return l;
 }
 
-/* Create a new perspective camera. */
+// Create a new perspective camera.
 dmnsn_camera *
 dmnsn_new_perspective_camera(dmnsn_pool *pool)
 {
diff --git a/libdimension/phong.c b/libdimension/phong.c
index 3536f45..10e5b1a 100644
--- a/libdimension/phong.c
+++ b/libdimension/phong.c
@@ -26,14 +26,14 @@
 #include "dimension.h"
 #include <stdlib.h>
 
-/** Phone specular type. */
+/// Phone specular type.
 typedef struct dmnsn_phong {
   dmnsn_specular specular;
   double coeff;
   double exp;
 } dmnsn_phong;
 
-/** Phong specular highlight callback. */
+/// Phong specular highlight callback.
 static dmnsn_color
 dmnsn_phong_specular_fn(const dmnsn_specular *specular,
                         dmnsn_color light, dmnsn_color color,
@@ -54,7 +54,7 @@ dmnsn_phong_specular_fn(const dmnsn_specular *specular,
   return dmnsn_color_mul(phong->coeff*specular_factor, light);
 }
 
-/* A phong finish */
+// A phong finish
 dmnsn_specular *
 dmnsn_new_phong(dmnsn_pool *pool, double coeff, double exp)
 {
diff --git a/libdimension/pigment.c b/libdimension/pigment.c
index 5756087..5fae4f6 100644
--- a/libdimension/pigment.c
+++ b/libdimension/pigment.c
@@ -25,7 +25,7 @@
 
 #include "dimension-internal.h"
 
-/* Allocate a dummy pigment */
+// Allocate a dummy pigment
 dmnsn_pigment *
 dmnsn_new_pigment(dmnsn_pool *pool)
 {
@@ -34,7 +34,7 @@ dmnsn_new_pigment(dmnsn_pool *pool)
   return pigment;
 }
 
-/* Initialize a pigment */
+// Initialize a pigment
 void
 dmnsn_init_pigment(dmnsn_pigment *pigment)
 {
@@ -45,7 +45,7 @@ dmnsn_init_pigment(dmnsn_pigment *pigment)
   pigment->initialized = false;
 }
 
-/* Precompute pigment properties */
+// Precompute pigment properties
 void
 dmnsn_pigment_initialize(dmnsn_pigment *pigment)
 {
@@ -59,7 +59,7 @@ dmnsn_pigment_initialize(dmnsn_pigment *pigment)
   pigment->trans_inv = dmnsn_matrix_inverse(pigment->trans);
 }
 
-/* Evaluate a pigment */
+// Evaluate a pigment
 dmnsn_tcolor
 dmnsn_pigment_evaluate(const dmnsn_pigment *pigment, dmnsn_vector v)
 {
diff --git a/libdimension/pigment_map.c b/libdimension/pigment_map.c
index a4240d2..71de4e0 100644
--- a/libdimension/pigment_map.c
+++ b/libdimension/pigment_map.c
@@ -25,7 +25,7 @@
 
 #include "dimension.h"
 
-/** Initialize a pigment in a pigment map. */
+/// Initialize a pigment in a pigment map.
 static void
 dmnsn_initialize_mapped_pigment(void *ptr)
 {
@@ -39,7 +39,7 @@ dmnsn_new_pigment_map(dmnsn_pool *pool)
   return dmnsn_new_map(pool, sizeof(dmnsn_pigment *));
 }
 
-/** Pigment map type. */
+/// Pigment map type.
 typedef struct dmnsn_pigment_map {
   dmnsn_pigment pigment;
   dmnsn_pattern *pattern;
@@ -47,7 +47,7 @@ typedef struct dmnsn_pigment_map {
   dmnsn_pigment_map_flags flags;
 } dmnsn_pigment_map;
 
-/** pigment_map pigment callback. */
+/// pigment_map pigment callback.
 static dmnsn_tcolor
 dmnsn_pigment_map_pigment_fn(const dmnsn_pigment *pigment, dmnsn_vector v)
 {
@@ -72,7 +72,7 @@ dmnsn_pigment_map_pigment_fn(const dmnsn_pigment *pigment, dmnsn_vector v)
   return ret;
 }
 
-/** pigment_map initialization callback. */
+/// pigment_map initialization callback.
 static void
 dmnsn_pigment_map_initialize_fn(dmnsn_pigment *pigment)
 {
diff --git a/libdimension/plane.c b/libdimension/plane.c
index c09dd70..5428485 100644
--- a/libdimension/plane.c
+++ b/libdimension/plane.c
@@ -27,13 +27,13 @@
 #include <math.h>
 #include <stdlib.h>
 
-/** Plane type. */
+/// Plane type.
 typedef struct {
   dmnsn_object object;
   dmnsn_vector normal;
 } dmnsn_plane;
 
-/** Returns the closest intersection of `line' with `plane'. */
+/// Returns the closest intersection of `line' with `plane'.
 static bool
 dmnsn_plane_intersection_fn(const dmnsn_object *object, dmnsn_line line,
                             dmnsn_intersection *intersection)
@@ -53,7 +53,7 @@ dmnsn_plane_intersection_fn(const dmnsn_object *object, dmnsn_line line,
   return false;
 }
 
-/** Return whether a point is inside a plane. */
+/// Return whether a point is inside a plane.
 static bool
 dmnsn_plane_inside_fn(const dmnsn_object *object, dmnsn_vector point)
 {
@@ -61,14 +61,14 @@ dmnsn_plane_inside_fn(const dmnsn_object *object, dmnsn_vector point)
   return dmnsn_vector_dot(point, plane->normal) < 0.0;
 }
 
-/** Plane bounding callback. */
+/// Plane bounding callback.
 static dmnsn_bounding_box
 dmnsn_plane_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
 {
   return dmnsn_infinite_bounding_box();
 }
 
-/** Plane vtable. */
+/// Plane vtable.
 static const dmnsn_object_vtable dmnsn_plane_vtable = {
   .intersection_fn = dmnsn_plane_intersection_fn,
   .inside_fn = dmnsn_plane_inside_fn,
diff --git a/libdimension/platform.c b/libdimension/platform.c
index d9d0e98..e0de578 100644
--- a/libdimension/platform.c
+++ b/libdimension/platform.c
@@ -33,13 +33,13 @@
   #include <windows.h>
 #endif
 #if DMNSN_BACKTRACE
-  #include <execinfo.h>    /* For backtrace() etc. */
+  #include <execinfo.h>    // For backtrace() etc.
 #endif
 #if DMNSN_GETTID
-  #include <sys/syscall.h> /* For gettid() where supported */
+  #include <sys/syscall.h> // For gettid() where supported
 #endif
 #if DMNSN_SCHED_GETAFFINITY
-  #include <sched.h>       /* For sched_getaffinity() */
+  #include <sched.h>       // For sched_getaffinity()
 #endif
 #if DMNSN_TIMES
   #include <sys/times.h>
@@ -77,7 +77,7 @@ dmnsn_is_main_thread(void)
 bool
 dmnsn_is_little_endian(void)
 {
-  /* Undefined behaviour, but quite portable */
+  // Undefined behaviour, but quite portable
   union {
     unsigned int i;
     unsigned char c;
@@ -114,7 +114,7 @@ dmnsn_ncpus(void)
 }
 
 #if DMNSN_GETRUSAGE
-/** Convert a struct timeval to a double. */
+/// Convert a struct timeval to a double.
 static inline double
 dmnsn_timeval2double(struct timeval tv)
 {
@@ -141,7 +141,7 @@ dmnsn_get_times(dmnsn_timer *timer)
 #elif DMNSN_TIMES
   static long clk_tck = 0;
 
-  /* Figure out the clock ticks per second */
+  // Figure out the clock ticks per second
   if (!clk_tck) {
     clk_tck = sysconf(_SC_CLK_TCK);
     if (clk_tck == -1) {
diff --git a/libdimension/png.c b/libdimension/png.c
index 8348e5f..24f8afa 100644
--- a/libdimension/png.c
+++ b/libdimension/png.c
@@ -30,7 +30,6 @@
 #include <stdlib.h>
 #include <stdint.h>
 
-/* Optimize canvas for PNG exporting */
 int
 dmnsn_png_optimize_canvas(dmnsn_canvas *canvas)
 {
@@ -38,14 +37,14 @@ dmnsn_png_optimize_canvas(dmnsn_canvas *canvas)
   return 0;
 }
 
-/** Payload type for PNG write thread callback. */
+/// Payload type for PNG write thread callback.
 typedef struct {
   dmnsn_future *future;
   const dmnsn_canvas *canvas;
   FILE *file;
 } dmnsn_png_write_payload;
 
-/** Payload type for PNG read thread callback. */
+/// Payload type for PNG read thread callback.
 typedef struct {
   dmnsn_future *future;
   dmnsn_canvas **canvas;
@@ -53,13 +52,11 @@ typedef struct {
   FILE *file;
 } dmnsn_png_read_payload;
 
-/** PNG write thread callback. */
+/// PNG write thread callback.
 static int dmnsn_png_write_canvas_thread(void *ptr);
-/** PNG read thread callback. */
+/// PNG read thread callback.
 static int dmnsn_png_read_canvas_thread(void *ptr);
 
-/* Write a canvas to a png file, using libpng.  Return 0 on success, nonzero on
-   failure. */
 int
 dmnsn_png_write_canvas(const dmnsn_canvas *canvas, FILE *file)
 {
@@ -67,7 +64,6 @@ dmnsn_png_write_canvas(const dmnsn_canvas *canvas, FILE *file)
   return dmnsn_future_join(future);
 }
 
-/* Write a canvas to a png file in the background */
 dmnsn_future *
 dmnsn_png_write_canvas_async(const dmnsn_canvas *canvas, FILE *file)
 {
@@ -78,13 +74,13 @@ dmnsn_png_write_canvas_async(const dmnsn_canvas *canvas, FILE *file)
   payload->canvas = canvas;
   payload->file   = file;
 
-  /* Create the worker thread */
+  // Create the worker thread
   dmnsn_new_thread(future, dmnsn_png_write_canvas_thread, payload);
 
   return future;
 }
 
-/* Read a canvas from the PNG file `file'.  Return NULL on error. */
+// Read a canvas from the PNG file `file'.  Return NULL on error.
 dmnsn_canvas *
 dmnsn_png_read_canvas(dmnsn_pool *pool, FILE *file)
 {
@@ -94,7 +90,7 @@ dmnsn_png_read_canvas(dmnsn_pool *pool, FILE *file)
   return canvas;
 }
 
-/* Read a canvas from a png file in the background */
+// Read a canvas from a png file in the background
 dmnsn_future *
 dmnsn_png_read_canvas_async(dmnsn_canvas **canvas, dmnsn_pool *pool, FILE *file)
 {
@@ -107,17 +103,17 @@ dmnsn_png_read_canvas_async(dmnsn_canvas **canvas, dmnsn_pool *pool, FILE *file)
   payload->pool = pool;
   payload->file = file;
 
-  /* Create the worker thread */
+  // Create the worker thread
   dmnsn_new_thread(future, dmnsn_png_read_canvas_thread, payload);
 
   return future;
 }
 
-/*
- * Thread callbacks
- */
+//////////////////////
+// Thread callbacks //
+//////////////////////
 
-/* Write a PNG file */
+// Write a PNG file
 static int
 dmnsn_png_write_canvas_thread(void *ptr)
 {
@@ -131,74 +127,74 @@ dmnsn_png_write_canvas_thread(void *ptr)
   png_structp png_ptr
     = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
   if (!png_ptr) {
-    /* Couldn't create libpng write struct */
+    // Couldn't create libpng write struct
     dmnsn_free(payload);
     return -1;
   }
 
   png_infop info_ptr = png_create_info_struct(png_ptr);
   if (!info_ptr) {
-    /* Couldn't create libpng info struct */
+    // Couldn't create libpng info struct
     png_destroy_write_struct(&png_ptr, NULL);
     dmnsn_free(payload);
     return -1;
   }
 
-  /* libpng will longjmp here if it encounters an error from here on */
+  // libpng will longjmp here if it encounters an error from here on
   uint16_t *row = NULL;
   if (setjmp(png_jmpbuf(png_ptr))) {
-    /* libpng error */
+    // libpng error
     dmnsn_free(row);
     png_destroy_write_struct(&png_ptr, &info_ptr);
     dmnsn_free(payload);
     return -1;
   }
 
-  /* Associate file with the libpng write struct */
+  // Associate file with the libpng write struct
   png_init_io(png_ptr, payload->file);
 
-  /* Set header correctly for 16-bit sRGB image */
+  // Set header correctly for 16-bit sRGB image
   png_set_IHDR(png_ptr, info_ptr, width, height, 16,
                PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
                PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
   png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, PNG_sRGB_INTENT_ABSOLUTE);
 
-  /* We think of transparency in the opposite way that PNG does */
+  // We think of transparency in the opposite way that PNG does
   png_set_invert_alpha(png_ptr);
 
-  /* Write the info struct */
+  // Write the info struct
   png_write_info(png_ptr, info_ptr);
 
   if (dmnsn_is_little_endian()) {
-    /* We are little-endian; swap the byte order of the pixels */
+    // We are little-endian; swap the byte order of the pixels
     png_set_swap(png_ptr);
   }
 
-  /* Check if we can optimize this */
+  // Check if we can optimize this
   dmnsn_canvas_optimizer *optimizer =
     dmnsn_canvas_find_optimizer(payload->canvas, dmnsn_rgba16_optimizer_fn);
   if (optimizer) {
     for (size_t y = 0; y < height; ++y) {
-      /* Invert the rows.  PNG coordinates are fourth quadrant. */
+      // Invert the rows.  PNG coordinates are fourth quadrant.
       uint16_t *row_opt = (uint16_t *)optimizer->ptr + 4*(height - y - 1)*width;
       png_write_row(png_ptr, (png_bytep)row_opt);
       dmnsn_future_increment(payload->future);
     }
 
-    /* Finish the PNG file */
+    // Finish the PNG file
     png_write_end(png_ptr, info_ptr);
     png_destroy_write_struct(&png_ptr, &info_ptr);
     dmnsn_free(payload);
     return 0;
   }
 
-  /* Allocate the temporary row of RGBA values */
+  // Allocate the temporary row of RGBA values
   row = dmnsn_malloc(4*sizeof(uint16_t)*width);
 
-  /* Write the pixels */
+  // Write the pixels
   for (size_t y = 0; y < height; ++y) {
     for (size_t x = 0; x < width; ++x) {
-      /* Invert the rows.  PNG coordinates are fourth quadrant. */
+      // Invert the rows.  PNG coordinates are fourth quadrant.
       dmnsn_tcolor tcolor = dmnsn_canvas_get_pixel(payload->canvas,
                                                    x, height - y - 1);
       tcolor = dmnsn_tcolor_remove_filter(tcolor);
@@ -211,12 +207,12 @@ dmnsn_png_write_canvas_thread(void *ptr)
       row[4*x + 3] = lround(tcolor.T*UINT16_MAX);
     }
 
-    /* Write the row */
+    // Write the row
     png_write_row(png_ptr, (png_bytep)row);
     dmnsn_future_increment(payload->future);
   }
 
-  /* Finish the PNG file */
+  // Finish the PNG file
   png_write_end(png_ptr, info_ptr);
 
   dmnsn_free(row);
@@ -225,18 +221,18 @@ dmnsn_png_write_canvas_thread(void *ptr)
   return 0;
 }
 
-/** Thread-specific pointer to the appropriate dmnsn_future* for
-    dmnsn_png_read_row_callback. */
+/// Thread-specific pointer to the appropriate dmnsn_future* for
+/// dmnsn_png_read_row_callback.
 static __thread dmnsn_future *dmnsn_tl_png_read_future;
 
-/** Callback to increment the progress after a row has been read. */
+/// Callback to increment the progress after a row has been read.
 static void
 dmnsn_png_read_row_callback(png_structp png_ptr, png_uint_32 row, int pass)
 {
   dmnsn_future_increment(dmnsn_tl_png_read_future);
 }
 
-/* Read a PNG file */
+// Read a PNG file
 static int
 dmnsn_png_read_canvas_thread(void *ptr)
 {
@@ -249,13 +245,13 @@ dmnsn_png_read_canvas_thread(void *ptr)
     return -1;
   }
   if (png_sig_cmp(header, 0, 8)) {
-    /* payload->file is not a PNG file */
+    // payload->file is not a PNG file
     dmnsn_free(payload);
     errno = EINVAL;
     return -1;
   }
 
-  /* Create the libpng read struct */
+  // Create the libpng read struct
   png_structp png_ptr
     = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
   if (!png_ptr) {
@@ -263,7 +259,7 @@ dmnsn_png_read_canvas_thread(void *ptr)
     return -1;
   }
 
-  /* Create the libpng info struct */
+  // Create the libpng info struct
   png_infop info_ptr = png_create_info_struct(png_ptr);
   if (!info_ptr) {
     png_destroy_read_struct(&png_ptr, NULL, NULL);
@@ -271,11 +267,11 @@ dmnsn_png_read_canvas_thread(void *ptr)
     return -1;
   }
 
-  /* libpng will longjmp here if it encounters an error from here on */
+  // libpng will longjmp here if it encounters an error from here on
   png_bytep image = NULL;
   png_bytep *row_pointers = NULL;
   if (setjmp(png_jmpbuf(png_ptr))) {
-    /* libpng error */
+    // libpng error
     dmnsn_free(row_pointers);
     dmnsn_free(image);
     png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
@@ -283,15 +279,15 @@ dmnsn_png_read_canvas_thread(void *ptr)
     return -1;
   }
 
-  /* Associate the read struct with the file, and tell it we've already checked
-     8 bytes of signature */
+  // Associate the read struct with the file, and tell it we've already checked
+  // 8 bytes of signature
   png_init_io(png_ptr, payload->file);
   png_set_sig_bytes(png_ptr, 8);
 
-  /* Read the PNG header into info struct */
+  // Read the PNG header into info struct
   png_read_info(png_ptr, info_ptr);
 
-  /* Get useful information from the info struct */
+  // Get useful information from the info struct
   png_uint_32 width, height;
   int bit_depth, color_type, interlace_type, compression_type, filter_method;
   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
@@ -301,12 +297,10 @@ dmnsn_png_read_canvas_thread(void *ptr)
   dmnsn_future_set_total(payload->future, (number_of_passes + 1)*height);
   png_set_read_status_fn(png_ptr, dmnsn_png_read_row_callback);
 
-  /*
-   * - Convert paletted images to RGB.
-   * - Convert a tRNS chunk to an alpha channel
-   * - Convert grayscale to RGB
-   * - Invert the alpha channel
-   */
+  // - Convert paletted images to RGB.
+  // - Convert a tRNS chunk to an alpha channel
+  // - Convert grayscale to RGB
+  // - Invert the alpha channel
   if (color_type == PNG_COLOR_TYPE_PALETTE) {
     png_set_palette_to_rgb(png_ptr);
   }
@@ -320,32 +314,32 @@ dmnsn_png_read_canvas_thread(void *ptr)
   }
   png_set_invert_alpha(png_ptr);
 
-  /* Update the info struct */
+  // Update the info struct
   png_read_update_info(png_ptr, info_ptr);
 
-  /* Get bytes/image row */
+  // Get bytes/image row
   png_uint_32 rowbytes = png_get_rowbytes(png_ptr, info_ptr);
 
-  /* Allocate the temporary image buffer */
+  // Allocate the temporary image buffer
   image = dmnsn_malloc(rowbytes*height);
 
-  /* Allocate and set an array of pointers to rows in image */
+  // Allocate and set an array of pointers to rows in image
   row_pointers = dmnsn_malloc(sizeof(png_bytep)*height);
 
   for (size_t y = 0; y < height; ++y) {
     row_pointers[y] = image + y*rowbytes;
   }
 
-  /* Read the image to memory all at once.  At the expense of greater memory
-     use, this handles interlacing for us. */
+  // Read the image to memory all at once.  At the expense of greater memory
+  // use, this handles interlacing for us.
   png_read_image(png_ptr, row_pointers);
 
-  /* Allocate the canvas */
+  // Allocate the canvas
   *payload->canvas = dmnsn_new_canvas(payload->pool, width, height);
 
-  /* Now we convert the image to our canvas format.  This depends on the image
-     bit depth (which has been scaled up to at least 8 or 16), and the presence
-     of an alpha channel. */
+  // Now we convert the image to our canvas format.  This depends on the image
+  // bit depth (which has been scaled up to at least 8 or 16), and the presence
+  // of an alpha channel.
   for (size_t y = 0; y < height; ++y) {
     for (size_t x = 0; x < width; ++x) {
       dmnsn_tcolor tcolor;
diff --git a/libdimension/point_light.c b/libdimension/point_light.c
index 62857d8..b8c2cfb 100644
--- a/libdimension/point_light.c
+++ b/libdimension/point_light.c
@@ -26,14 +26,14 @@
 #include "dimension.h"
 #include <stdlib.h>
 
-/** Point light type. */
+/// Point light type.
 typedef struct dmnsn_point_light {
   dmnsn_light light;
   dmnsn_vector origin;
   dmnsn_color color;
 } dmnsn_point_light;
 
-/** Point light direction callback. */
+/// Point light direction callback.
 static dmnsn_vector
 dmnsn_point_light_direction_fn(const dmnsn_light *light, dmnsn_vector v)
 {
@@ -41,7 +41,7 @@ dmnsn_point_light_direction_fn(const dmnsn_light *light, dmnsn_vector v)
   return dmnsn_vector_sub(point_light->origin, v);
 }
 
-/** Point light illumination callback. */
+/// Point light illumination callback.
 static dmnsn_color
 dmnsn_point_light_illumination_fn(const dmnsn_light *light, dmnsn_vector v)
 {
@@ -49,7 +49,7 @@ dmnsn_point_light_illumination_fn(const dmnsn_light *light, dmnsn_vector v)
   return point_light->color;
 }
 
-/** Point light illumination callback. */
+/// Point light illumination callback.
 static bool
 dmnsn_point_light_shadow_fn(const dmnsn_light *light, double t)
 {
diff --git a/libdimension/polynomial.c b/libdimension/polynomial.c
index 3f64091..23b96d1 100644
--- a/libdimension/polynomial.c
+++ b/libdimension/polynomial.c
@@ -27,7 +27,7 @@
 #include "dimension-internal.h"
 #include <math.h>
 
-/** Get the real degree of a polynomial, ignoring leading zeros. */
+/// Get the real degree of a polynomial, ignoring leading zeros.
 static inline size_t
 dmnsn_real_degree(const double poly[], size_t degree)
 {
@@ -40,7 +40,7 @@ dmnsn_real_degree(const double poly[], size_t degree)
   return 0;
 }
 
-/** Divide each coefficient by the leading coefficient. */
+/// Divide each coefficient by the leading coefficient.
 static inline void
 dmnsn_polynomial_normalize(double poly[], size_t degree)
 {
@@ -50,7 +50,7 @@ dmnsn_polynomial_normalize(double poly[], size_t degree)
   poly[degree] = 1.0;
 }
 
-/** Eliminate trivial zero roots from \p poly[]. */
+/// Eliminate trivial zero roots from \p poly[].
 static inline void
 dmnsn_eliminate_zero_roots(double **poly, size_t *degree)
 {
@@ -65,7 +65,7 @@ dmnsn_eliminate_zero_roots(double **poly, size_t *degree)
   *degree -= i;
 }
 
-/** Calculate a finite upper bound on the roots of a normalized polynomial. */
+/// Calculate a finite upper bound on the roots of a normalized polynomial.
 static inline double
 dmnsn_root_bound(const double poly[], size_t degree)
 {
@@ -77,7 +77,7 @@ dmnsn_root_bound(const double poly[], size_t degree)
   return bound;
 }
 
-/** Copy a polynomial. */
+/// Copy a polynomial.
 static inline void
 dmnsn_polynomial_copy(double dest[], const double src[], size_t degree)
 {
@@ -86,7 +86,7 @@ dmnsn_polynomial_copy(double dest[], const double src[], size_t degree)
   }
 }
 
-/** Transform a polynomial by P'(x) = P(x + 1). */
+/// Transform a polynomial by P'(x) = P(x + 1).
 static inline void
 dmnsn_polynomial_translate(double poly[], size_t degree)
 {
@@ -97,7 +97,7 @@ dmnsn_polynomial_translate(double poly[], size_t degree)
   }
 }
 
-/** Transform a polynomial by P'(x) = P(c*x). */
+/// Transform a polynomial by P'(x) = P(c*x).
 static inline void
 dmnsn_polynomial_scale(double poly[], size_t degree, double c)
 {
@@ -108,22 +108,22 @@ dmnsn_polynomial_scale(double poly[], size_t degree, double c)
   }
 }
 
-/** Returns the result of Descartes' rule on x^degree * poly(1/(x + 1)). */
+/// Returns the result of Descartes' rule on x^degree * poly(1/(x + 1)).
 static size_t
 dmnsn_descartes_bound(const double poly[], size_t degree)
 {
-  /* Copy the polynomial so we can be destructive */
+  // Copy the polynomial so we can be destructive
   double p[degree + 1];
   dmnsn_polynomial_copy(p, poly, degree);
 
-  /* Calculate poly(1/(1/x + 1)) which avoids reversal */
+  // Calculate poly(1/(1/x + 1)) which avoids reversal
   for (size_t i = 1; i <= degree; ++i) {
     for (size_t j = i; j >= 1; --j) {
       p[j] += p[j - 1];
     }
   }
 
-  /* Find the number of sign changes in p[] */
+  // Find the number of sign changes in p[]
   size_t changes = 0;
   int lastsign = dmnsn_sign(p[0]);
   for (size_t i = 1; changes <= 1 && i <= degree; ++i) {
@@ -137,20 +137,20 @@ dmnsn_descartes_bound(const double poly[], size_t degree)
   return changes;
 }
 
-/** Depth-first search of possible isolating intervals. */
+/// Depth-first search of possible isolating intervals.
 static size_t
 dmnsn_root_bounds_recursive(double poly[], size_t degree, double *c, double *k,
                             double bounds[][2], size_t nbounds)
 {
   size_t s = dmnsn_descartes_bound(poly, degree);
   if (s >= 2) {
-    /* Get the left child */
+    // Get the left child
     dmnsn_polynomial_scale(poly, degree, 1.0/2.0);
     *c *= 2.0;
     *k /= 2.0;
     double currc = *c, currk = *k;
 
-    /* Test the left child */
+    // Test the left child
     size_t n = dmnsn_root_bounds_recursive(poly, degree, c, k, bounds, nbounds);
     if (nbounds == n) {
       return n;
@@ -158,13 +158,13 @@ dmnsn_root_bounds_recursive(double poly[], size_t degree, double *c, double *k,
     bounds += n;
     nbounds -= n;
 
-    /* Get the right child from the last tested polynomial */
+    // Get the right child from the last tested polynomial
     dmnsn_polynomial_translate(poly, degree);
     dmnsn_polynomial_scale(poly, degree, currk/(*k));
     *c = currc + 1.0;
     *k = currk;
 
-    /* Test the right child */
+    // Test the right child
     n += dmnsn_root_bounds_recursive(poly, degree, c, k, bounds, nbounds);
     return n;
   } else if (s == 1) {
@@ -176,26 +176,26 @@ dmnsn_root_bounds_recursive(double poly[], size_t degree, double *c, double *k,
   }
 }
 
-/** Find ranges that contain a single root. */
+/// Find ranges that contain a single root.
 static size_t
 dmnsn_root_bounds(const double poly[], size_t degree, double bounds[][2],
                   size_t nbounds)
 {
-  /* Copy the polynomial so we can be destructive */
+  // Copy the polynomial so we can be destructive
   double p[degree + 1];
   dmnsn_polynomial_copy(p, poly, degree);
 
-  /* Scale the roots to within (0, 1] */
+  // Scale the roots to within (0, 1]
   double bound = dmnsn_root_bound(p, degree);
   dmnsn_polynomial_scale(p, degree, bound);
 
-  /* Bounding intervals are of the form (c*k, (c + 1)*k) */
+  // Bounding intervals are of the form (c*k, (c + 1)*k)
   double c = 0.0, k = 1.0;
 
-  /* Isolate the roots */
+  // Isolate the roots
   size_t n = dmnsn_root_bounds_recursive(p, degree, &c, &k, bounds, nbounds);
 
-  /* Scale the roots back to within (0, bound] */
+  // Scale the roots back to within (0, bound]
   for (size_t i = 0; i < n; ++i) {
     bounds[i][0] *= bound;
     bounds[i][1] *= bound;
@@ -204,18 +204,18 @@ dmnsn_root_bounds(const double poly[], size_t degree, double bounds[][2],
   return n;
 }
 
-/** Maximum number of iterations in dmnsn_bisect_root() before bailout. */
+/// Maximum number of iterations in dmnsn_bisect_root() before bailout.
 #define DMNSN_BISECT_ITERATIONS 64
 
-/** Use the false position method to find a root in a range that contains
-    exactly one root. */
+/// Use the false position method to find a root in a range that contains
+/// exactly one root.
 static inline double
 dmnsn_bisect_root(const double poly[], size_t degree, double min, double max)
 {
   double evmin = dmnsn_polynomial_evaluate(poly, degree, min);
   double evmax = dmnsn_polynomial_evaluate(poly, degree, max);
 
-  /* Handle equal bounds, and equal values at the bounds. */
+  // Handle equal bounds, and equal values at the bounds.
   if (dmnsn_unlikely(fabs(evmax - evmin) < dmnsn_epsilon)) {
     return (min + max)/2.0;
   }
@@ -230,8 +230,8 @@ dmnsn_bisect_root(const double poly[], size_t degree, double min, double max)
     int sign = dmnsn_sign(evmid);
 
     if ((fabs(evmid) < fabs(mid)*dmnsn_epsilon
-         /* This condition improves stability when one of the bounds is
-            close to a different root than we are trying to find */
+         // This condition improves stability when one of the bounds is close to
+         // a different root than we are trying to find
          && fabs(evmid) <= evinitial)
         || max - min < fabs(mid)*dmnsn_epsilon)
     {
@@ -239,8 +239,8 @@ dmnsn_bisect_root(const double poly[], size_t degree, double min, double max)
     }
 
     if (mid < min) {
-      /* This can happen due to numerical instability in the root bounding
-         algorithm, so behave like the normal secant method */
+      // This can happen due to numerical instability in the root bounding
+      // algorithm, so behave like the normal secant method
       max = min;
       evmax = evmin;
       min = mid;
@@ -254,8 +254,8 @@ dmnsn_bisect_root(const double poly[], size_t degree, double min, double max)
       max = mid;
       evmax = evmid;
       if (sign == lastsign) {
-        /* Don't allow the algorithm to keep the same endpoint for three
-           iterations in a row; this ensures superlinear convergence */
+        // Don't allow the algorithm to keep the same endpoint for three
+        // iterations in a row; this ensures superlinear convergence
         evmin /= 2.0;
       }
     } else {
@@ -272,7 +272,7 @@ dmnsn_bisect_root(const double poly[], size_t degree, double min, double max)
   return mid;
 }
 
-/** Use synthetic division to eliminate the root \p r from \p poly[]. */
+/// Use synthetic division to eliminate the root \p r from \p poly[].
 static inline size_t
 dmnsn_eliminate_root(double poly[], size_t degree, double r)
 {
@@ -285,7 +285,7 @@ dmnsn_eliminate_root(double poly[], size_t degree, double r)
   return degree - 1;
 }
 
-/** Solve a normalized linear polynomial algebraically. */
+/// Solve a normalized linear polynomial algebraically.
 static inline size_t
 dmnsn_solve_linear(const double poly[2], double x[1])
 {
@@ -296,7 +296,7 @@ dmnsn_solve_linear(const double poly[2], double x[1])
     return 0;
 }
 
-/** Solve a normalized quadratic polynomial algebraically. */
+/// Solve a normalized quadratic polynomial algebraically.
 static inline size_t
 dmnsn_solve_quadratic(const double poly[3], double x[2])
 {
@@ -317,11 +317,11 @@ dmnsn_solve_quadratic(const double poly[3], double x[2])
   }
 }
 
-/** Solve a normalized cubic polynomial algebraically. */
+/// Solve a normalized cubic polynomial algebraically.
 static inline size_t
 dmnsn_solve_cubic(double poly[4], double x[3])
 {
-  /* Reduce to a monic trinomial (t^3 + p*t + q, t = x + b/3) */
+  // Reduce to a monic trinomial (t^3 + p*t + q, t = x + b/3)
   double b2 = poly[2]*poly[2];
   double p = poly[1] - b2/3.0;
   double q = poly[0] - poly[2]*(9.0*poly[1] - 2.0*b2)/27.0;
@@ -330,11 +330,11 @@ dmnsn_solve_cubic(double poly[4], double x[3])
   double bdiv3 = poly[2]/3.0;
 
   if (disc < 0.0) {
-    /* Three real roots -- this implies p < 0 */
+    // Three real roots -- this implies p < 0
     double msqrtp3 = -sqrt(-p/3.0);
     double theta = acos(3*q/(2*p*msqrtp3))/3.0;
 
-    /* Store the roots in order from largest to smallest */
+    // Store the roots in order from largest to smallest
     x[2] = 2.0*msqrtp3*cos(theta) - bdiv3;
     x[0] = -2.0*msqrtp3*cos(4.0*atan(1.0)/3.0 - theta) - bdiv3;
     x[1] = -(x[0] + x[2] + poly[2]);
@@ -344,7 +344,7 @@ dmnsn_solve_cubic(double poly[4], double x[3])
     else if (x[1] >= dmnsn_epsilon)
       return 2;
   } else if (disc > 0.0) {
-    /* One real root */
+    // One real root
     double cbrtdiscq = cbrt(sqrt(disc/108.0) + fabs(q)/2.0);
     double abst = cbrtdiscq - p/(3.0*cbrtdiscq);
 
@@ -354,10 +354,10 @@ dmnsn_solve_cubic(double poly[4], double x[3])
       x[0] = abst - bdiv3;
     }
   } else if (fabs(p) < dmnsn_epsilon) {
-    /* Equation is a perfect cube */
+    // Equation is a perfect cube
     x[0] = -bdiv3;
   } else {
-    /* Two real roots; one duplicate */
+    // Two real roots; one duplicate
     double t1 = -(3.0*q)/(2.0*p), t2 = -2.0*t1;
     x[0] = dmnsn_max(t1, t2) - bdiv3;
     x[1] = dmnsn_min(t1, t2) - bdiv3;
@@ -371,38 +371,38 @@ dmnsn_solve_cubic(double poly[4], double x[3])
     return 0;
 }
 
-/* Solve a polynomial */
+// Solve a polynomial
 DMNSN_HOT size_t
 dmnsn_polynomial_solve(const double poly[], size_t degree, double x[])
 {
-  /* Copy the polynomial so we can be destructive */
+  // Copy the polynomial so we can be destructive
   double copy[degree + 1], *p = copy;
   dmnsn_polynomial_copy(p, poly, degree);
 
-  /* Index into x[] */
+  // Index into x[]
   size_t i = 0;
 
-  /* Account for leading zero coefficients */
+  // Account for leading zero coefficients
   degree = dmnsn_real_degree(p, degree);
-  /* Normalize the leading coefficient to 1.0 */
+  // Normalize the leading coefficient to 1.0
   dmnsn_polynomial_normalize(p, degree);
-  /* Eliminate simple zero roots */
+  // Eliminate simple zero roots
   dmnsn_eliminate_zero_roots(&p, &degree);
 
   static const size_t max_algebraic = 3;
   if (degree > max_algebraic) {
-    /* Find isolating intervals for (degree - max_algebraic) roots of p[] */
+    // Find isolating intervals for (degree - max_algebraic) roots of p[]
     double ranges[degree - max_algebraic][2];
     size_t n = dmnsn_root_bounds(p, degree, ranges, degree - max_algebraic);
 
     for (size_t j = 0; j < n; ++j) {
-      /* Bisect within the found range */
+      // Bisect within the found range
       double r = dmnsn_bisect_root(p, degree, ranges[j][0], ranges[j][1]);
 
-      /* Use synthetic division to eliminate the root `r' */
+      // Use synthetic division to eliminate the root `r'
       degree = dmnsn_eliminate_root(p, degree, r);
 
-      /* Store the found root */
+      // Store the found root
       x[i] = r;
       ++i;
     }
@@ -423,7 +423,7 @@ dmnsn_polynomial_solve(const double poly[], size_t degree, double x[])
   return i;
 }
 
-/* Print a polynomial */
+// Print a polynomial
 void
 dmnsn_polynomial_print(FILE *file, const double poly[], size_t degree)
 {
diff --git a/libdimension/pool.c b/libdimension/pool.c
index 8973371..bd31677 100644
--- a/libdimension/pool.c
+++ b/libdimension/pool.c
@@ -26,30 +26,30 @@
 #include "dimension-internal.h"
 #include <stdatomic.h>
 
-/** A single allocation and associated destructor. */
+/// A single allocation and associated destructor.
 typedef struct dmnsn_allocation {
   void *ptr;
   dmnsn_callback_fn *cleanup_fn;
 } dmnsn_allocation;
 
-/** Number of pointers per block, we want a block to fit in a single page. */
+/// Number of pointers per block, we want a block to fit in a single page.
 #define DMNSN_POOL_BLOCK_SIZE ((4096 - 4*sizeof(void *))/sizeof(dmnsn_allocation))
 
-/** A single block in a thread pool. */
+/// A single block in a thread pool.
 typedef struct dmnsn_pool_block {
-  /** Current index into allocs[]. */
+  /// Current index into allocs[].
   size_t i;
-  /** All allocations in the current block. */
+  /// All allocations in the current block.
   dmnsn_allocation allocs[DMNSN_POOL_BLOCK_SIZE];
-  /** Tail pointer to the previous block in the global chain. */
+  /// Tail pointer to the previous block in the global chain.
   struct dmnsn_pool_block *prev;
 } dmnsn_pool_block;
 
-/** dmnsn_pool implementation. */
+/// dmnsn_pool implementation.
 struct dmnsn_pool {
-  /** Thread-local block. */
+  /// Thread-local block.
   pthread_key_t thread_block;
-  /** Global chain of pools. */
+  /// Global chain of pools.
   _Atomic(dmnsn_pool_block *) chain;
 };
 
@@ -87,7 +87,7 @@ dmnsn_palloc_tidy(dmnsn_pool *pool, size_t size, dmnsn_callback_fn *cleanup_fn)
   if (dmnsn_unlikely(new_block != old_block)) {
     dmnsn_setspecific(pool->thread_block, new_block);
 
-    /* Atomically update pool->chain */
+    // Atomically update pool->chain
     dmnsn_pool_block *chain;
     do {
       chain = atomic_load(&pool->chain);
@@ -107,7 +107,7 @@ dmnsn_delete_pool(dmnsn_pool *pool)
 
   dmnsn_pool_block *block = atomic_load_explicit(&pool->chain, memory_order_relaxed);
   while (block) {
-    /* Free all the allocations in reverse order */
+    // Free all the allocations in reverse order
     for (size_t i = block->i; i-- > 0;) {
       dmnsn_allocation *alloc = block->allocs + i;
       if (alloc->cleanup_fn) {
@@ -116,7 +116,7 @@ dmnsn_delete_pool(dmnsn_pool *pool)
       dmnsn_free(alloc->ptr);
     }
 
-    /* Free the block itself and go to the previous one */
+    // Free the block itself and go to the previous one
     dmnsn_pool_block *saved = block;
     block = block->prev;
     dmnsn_free(saved);
diff --git a/libdimension/profile.c b/libdimension/profile.c
index 308c8fb..164e002 100644
--- a/libdimension/profile.c
+++ b/libdimension/profile.c
@@ -28,23 +28,23 @@
 #include <stdio.h>
 #include <inttypes.h>
 
-/** Information on one predicted branch. */
+/// Information on one predicted branch.
 typedef struct {
   char *location;
   uint64_t predicted, branches;
 } dmnsn_branch;
 
-/** Count of mispredicted branches. */
+/// Count of mispredicted branches.
 static dmnsn_dictionary *dmnsn_profile = NULL;
-/** Mutex which protects \c dmnsn_profile. */
+/// Mutex which protects \c dmnsn_profile.
 static pthread_mutex_t dmnsn_profile_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-/** Thread-local count of mispredicted branches. */
+/// Thread-local count of mispredicted branches.
 static pthread_key_t dmnsn_thread_profile;
-/** Initialize the thread-specific pointer exactly once. */
+/// Initialize the thread-specific pointer exactly once.
 static pthread_once_t dmnsn_thread_profile_once = PTHREAD_ONCE_INIT;
 
-/** Add thread-specific profile data to the global counts. */
+/// Add thread-specific profile data to the global counts.
 static void
 dmnsn_profile_globalize(void *ptr)
 {
@@ -59,7 +59,7 @@ dmnsn_profile_globalize(void *ptr)
   }
 }
 
-/** Destructor function for thread-specific profile data. */
+/// Destructor function for thread-specific profile data.
 static void
 dmnsn_delete_thread_profile(void *ptr)
 {
@@ -72,7 +72,7 @@ dmnsn_delete_thread_profile(void *ptr)
   dmnsn_delete_dictionary(thread_profile);
 }
 
-/** Initialize the thread-specific pointer. */
+/// Initialize the thread-specific pointer.
 static void
 dmnsn_initialize_thread_profile(void)
 {
@@ -83,7 +83,7 @@ dmnsn_initialize_thread_profile(void)
   dmnsn_unlock_mutex(&dmnsn_profile_mutex);
 }
 
-/** Get the thread-specific profile data. */
+/// Get the thread-specific profile data.
 static dmnsn_dictionary *
 dmnsn_get_thread_profile(void)
 {
@@ -91,7 +91,7 @@ dmnsn_get_thread_profile(void)
   return pthread_getspecific(dmnsn_thread_profile);
 }
 
-/** Set the thread-specific profile data. */
+/// Set the thread-specific profile data.
 static void
 dmnsn_set_thread_profile(dmnsn_dictionary *thread_profile)
 {
diff --git a/libdimension/prtree.c b/libdimension/prtree.c
index b4b9e82..0d484ce 100644
--- a/libdimension/prtree.c
+++ b/libdimension/prtree.c
@@ -26,28 +26,28 @@
 #include "dimension-internal.h"
 #include <stdlib.h>
 
-/** Number of children per PR-node. */
+/// Number of children per PR-node.
 #define DMNSN_PRTREE_B 8
-/** Number of priority leaves per pseudo-PR-node (must be 2*ndimensions). */
+/// Number of priority leaves per pseudo-PR-node (must be 2*ndimensions).
 #define DMNSN_PSEUDO_B 6
 
-/** The side of the split that a node ended up on. */
+/// The side of the split that a node ended up on.
 typedef enum dmnsn_prnode_location {
-  DMNSN_PRTREE_LEAF, /**< Priority leaf. */
-  DMNSN_PRTREE_LEFT, /**< Left child. */
-  DMNSN_PRTREE_RIGHT /**< Right child. */
+  DMNSN_PRTREE_LEAF, ///< Priority leaf.
+  DMNSN_PRTREE_LEFT, ///< Left child.
+  DMNSN_PRTREE_RIGHT ///< Right child.
 } dmnsn_prnode_location;
 
-/** Construct an empty PR-node. */
+/// Construct an empty PR-node.
 static inline dmnsn_bvh_node *
 dmnsn_new_prnode(void)
 {
   dmnsn_bvh_node *node = dmnsn_new_bvh_node(DMNSN_PRTREE_B);
-  node->data = DMNSN_PRTREE_LEFT; /* Mustn't be _LEAF */
+  node->data = DMNSN_PRTREE_LEFT; // Mustn't be _LEAF
   return node;
 }
 
-/** Comparator types. */
+/// Comparator types.
 enum {
   DMNSN_XMIN,
   DMNSN_YMIN,
@@ -57,7 +57,7 @@ enum {
   DMNSN_ZMAX
 };
 
-/* List sorting comparators */
+// List sorting comparators
 
 static int
 dmnsn_xmin_comp(const void *l, const void *r)
@@ -107,7 +107,7 @@ dmnsn_zmax_comp(const void *l, const void *r)
   return (lval < rval) - (lval > rval);
 }
 
-/** All comparators. */
+/// All comparators.
 static dmnsn_array_comparator_fn *const dmnsn_comparators[DMNSN_PSEUDO_B] = {
   [DMNSN_XMIN] = dmnsn_xmin_comp,
   [DMNSN_YMIN] = dmnsn_ymin_comp,
@@ -117,7 +117,7 @@ static dmnsn_array_comparator_fn *const dmnsn_comparators[DMNSN_PSEUDO_B] = {
   [DMNSN_ZMAX] = dmnsn_zmax_comp,
 };
 
-/** Add the priority leaves for this level. */
+/// Add the priority leaves for this level.
 static void
 dmnsn_add_priority_leaves(dmnsn_bvh_node **sorted_leaves[DMNSN_PSEUDO_B],
                           size_t nleaves,
@@ -130,7 +130,7 @@ dmnsn_add_priority_leaves(dmnsn_bvh_node **sorted_leaves[DMNSN_PSEUDO_B],
          j < nleaves && (!leaf || leaf->nchildren < DMNSN_PRTREE_B);
          ++j)
     {
-      /* Skip all the previously found extreme nodes */
+      // Skip all the previously found extreme nodes
       if (leaves[j]->data == DMNSN_PRTREE_LEAF) {
         continue;
       }
@@ -155,7 +155,7 @@ dmnsn_split_sorted_leaves_easy(dmnsn_bvh_node **leaves,
                                size_t *nleaves,
                                size_t *nright_leaves)
 {
-  /* Get rid of the extreme nodes */
+  // Get rid of the extreme nodes
   size_t i, skip, size = *nleaves;
   for (i = 0, skip = 0; i < size; ++i) {
     if (leaves[i]->data == DMNSN_PRTREE_LEAF) {
@@ -167,7 +167,7 @@ dmnsn_split_sorted_leaves_easy(dmnsn_bvh_node **leaves,
 
   size -= skip;
 
-  /* Split the leaves and mark the left and right child nodes */
+  // Split the leaves and mark the left and right child nodes
   size_t left_size = (size + 1)/2;
   for (i = 0; i < left_size; ++i) {
     leaves[i]->data = DMNSN_PRTREE_LEFT;
@@ -204,7 +204,7 @@ dmnsn_split_sorted_leaves_hard(dmnsn_bvh_node **leaves,
   }
 }
 
-/** Split the sorted lists into the left and right subtrees. */
+/// Split the sorted lists into the left and right subtrees.
 static void
 dmnsn_split_sorted_leaves(dmnsn_bvh_node **sorted_leaves[DMNSN_PSEUDO_B],
                           size_t *nleaves,
@@ -215,10 +215,10 @@ dmnsn_split_sorted_leaves(dmnsn_bvh_node **sorted_leaves[DMNSN_PSEUDO_B],
 {
   size_t original_size = *nleaves;
 
-  /* Split the ith list */
+  // Split the ith list
   dmnsn_split_sorted_leaves_easy(sorted_leaves[i], nleaves, nright_leaves);
 
-  /* Split the rest of the lists */
+  // Split the rest of the lists
   for (size_t j = 0; j < DMNSN_PSEUDO_B; ++j) {
     right_sorted_leaves[j] = sorted_leaves[j] + *nleaves;
     if (j == i) {
@@ -229,8 +229,8 @@ dmnsn_split_sorted_leaves(dmnsn_bvh_node **sorted_leaves[DMNSN_PSEUDO_B],
   }
 }
 
-/** Recursively constructs an implicit pseudo-PR-tree and collects the priority
-    leaves. */
+/// Recursively constructs an implicit pseudo-PR-tree and collects the priority
+/// leaves.
 static void
 dmnsn_priority_leaves_recursive(dmnsn_bvh_node **sorted_leaves[DMNSN_PSEUDO_B],
                                 size_t nleaves,
@@ -260,7 +260,7 @@ dmnsn_priority_leaves_recursive(dmnsn_bvh_node **sorted_leaves[DMNSN_PSEUDO_B],
   }
 }
 
-/** Sort each dimension in parallel with more than this many leaves. */
+/// Sort each dimension in parallel with more than this many leaves.
 #define DMNSN_PARALLEL_SORT_THRESHOLD 1024
 
 typedef struct {
@@ -293,7 +293,7 @@ dmnsn_sort_leaves(void *ptr, unsigned int thread, unsigned int nthreads)
   return 0;
 }
 
-/** Constructs an implicit pseudo-PR-tree and returns the priority leaves. */
+/// Constructs an implicit pseudo-PR-tree and returns the priority leaves.
 static dmnsn_array *
 dmnsn_priority_leaves(const dmnsn_array *leaves, unsigned int nthreads)
 {
@@ -337,11 +337,11 @@ dmnsn_new_prtree(const dmnsn_array *objects)
     return NULL;
   }
 
-  /* Make the initial array of leaves */
+  // Make the initial array of leaves
   dmnsn_array *leaves = DMNSN_NEW_ARRAY(dmnsn_bvh_node *);
   DMNSN_ARRAY_FOREACH (dmnsn_object **, object, objects) {
     dmnsn_bvh_node *node = dmnsn_new_bvh_leaf_node(*object);
-    node->data = DMNSN_PRTREE_LEFT; /* Mustn't be _LEAF */
+    node->data = DMNSN_PRTREE_LEFT; // Mustn't be _LEAF
     dmnsn_array_push(leaves, &node);
   }
 
diff --git a/libdimension/prtree.h b/libdimension/prtree.h
index 0a8224a..76a4051 100644
--- a/libdimension/prtree.h
+++ b/libdimension/prtree.h
@@ -26,5 +26,5 @@
  * from B-trees.
  */
 
-/** Create a PR-tree. */
+/// Create a PR-tree.
 DMNSN_INTERNAL dmnsn_bvh_node *dmnsn_new_prtree(const dmnsn_array *objects);
diff --git a/libdimension/ray_trace.c b/libdimension/ray_trace.c
index d7383e4..6f4ce33 100644
--- a/libdimension/ray_trace.c
+++ b/libdimension/ray_trace.c
@@ -26,18 +26,18 @@
 #include "dimension-internal.h"
 #include <stdlib.h>
 
-/*
- * Boilerplate for multithreading
- */
+////////////////////////////////////
+// Boilerplate for multithreading //
+////////////////////////////////////
 
-/** Payload type for passing arguments to worker threads. */
+/// Payload type for passing arguments to worker threads.
 typedef struct {
   dmnsn_future *future;
   dmnsn_scene *scene;
   dmnsn_bvh *bvh;
 } dmnsn_ray_trace_payload;
 
-/* Ray-trace a scene */
+// Ray-trace a scene
 void
 dmnsn_ray_trace(dmnsn_scene *scene)
 {
@@ -47,10 +47,10 @@ dmnsn_ray_trace(dmnsn_scene *scene)
   }
 }
 
-/** Background thread callback. */
+/// Background thread callback.
 static int dmnsn_ray_trace_scene_thread(void *ptr);
 
-/* Ray-trace a scene in the background */
+// Ray-trace a scene in the background
 dmnsn_future *
 dmnsn_ray_trace_async(dmnsn_scene *scene)
 {
@@ -65,28 +65,28 @@ dmnsn_ray_trace_async(dmnsn_scene *scene)
   return future;
 }
 
-/** Worker thread callback. */
+/// Worker thread callback.
 static int dmnsn_ray_trace_scene_concurrent(void *ptr, unsigned int thread,
                                             unsigned int nthreads);
 
-/* Thread callback -- set up the multithreaded engine */
+// Thread callback -- set up the multithreaded engine
 static int
 dmnsn_ray_trace_scene_thread(void *ptr)
 {
   dmnsn_ray_trace_payload *payload = ptr;
 
-  /* Pre-calculate bounding box transformations, etc. */
+  // Pre-calculate bounding box transformations, etc.
   dmnsn_scene_initialize(payload->scene);
 
-  /* Time the bounding tree construction */
+  // Time the bounding tree construction
   dmnsn_timer_start(&payload->scene->bounding_timer);
     payload->bvh = dmnsn_new_bvh(payload->scene->objects, DMNSN_BVH_PRTREE);
   dmnsn_timer_stop(&payload->scene->bounding_timer);
 
-  /* Set up the future object */
+  // Set up the future object
   dmnsn_future_set_total(payload->future, payload->scene->canvas->height);
 
-  /* Time the render itself */
+  // Time the render itself
   dmnsn_timer_start(&payload->scene->render_timer);
     int ret = dmnsn_execute_concurrently(payload->future,
                                          dmnsn_ray_trace_scene_concurrent,
@@ -99,11 +99,11 @@ dmnsn_ray_trace_scene_thread(void *ptr)
   return ret;
 }
 
-/*
- * Ray-tracing algorithm
- */
+///////////////////////////
+// Ray-tracing algorithm //
+///////////////////////////
 
-/** The current state of the ray-tracing engine. */
+/// The current state of the ray-tracing engine.
 typedef struct dmnsn_rtstate {
   const struct dmnsn_rtstate *parent;
 
@@ -131,14 +131,14 @@ typedef struct dmnsn_rtstate {
   dmnsn_color adc_value;
 } dmnsn_rtstate;
 
-/** Compute a ray-tracing state from an intersection. */
+/// Compute a ray-tracing state from an intersection.
 static inline void
 dmnsn_rtstate_initialize(dmnsn_rtstate *state,
                          const dmnsn_intersection *intersection);
-/** Main helper for dmnsn_ray_trace_scene_concurrent - shoot a ray. */
+/// Main helper for dmnsn_ray_trace_scene_concurrent - shoot a ray.
 static dmnsn_tcolor dmnsn_ray_shoot(dmnsn_rtstate *state, dmnsn_line ray);
 
-/* Actually ray-trace a scene */
+// Actually ray-trace a scene
 static int
 dmnsn_ray_trace_scene_concurrent(void *ptr, unsigned int thread,
                                  unsigned int nthreads)
@@ -154,17 +154,17 @@ dmnsn_ray_trace_scene_concurrent(void *ptr, unsigned int thread,
     .bvh = bvh,
   };
 
-  /* Iterate through each pixel */
+  // Iterate through each pixel
   for (size_t y = thread; y < scene->canvas->height; y += nthreads) {
     for (size_t x = 0; x < scene->canvas->width; ++x) {
-      /* Get the ray corresponding to the (x,y)'th pixel */
+      // Get the ray corresponding to the (x,y)'th pixel
       dmnsn_line ray = dmnsn_camera_ray(
         scene->camera,
         ((double)(x + scene->region_x))/(scene->outer_width - 1),
         ((double)(y + scene->region_y))/(scene->outer_height - 1)
       );
 
-      /* Shoot a ray */
+      // Shoot a ray
       state.reclevel = scene->reclimit;
       state.ior = 1.0;
       state.adc_value = dmnsn_white;
@@ -178,7 +178,7 @@ dmnsn_ray_trace_scene_concurrent(void *ptr, unsigned int thread,
   return 0;
 }
 
-/* Compute rtstate fields */
+// Compute rtstate fields
 static inline void
 dmnsn_rtstate_initialize(dmnsn_rtstate *state,
                          const dmnsn_intersection *intersection)
@@ -205,18 +205,18 @@ dmnsn_rtstate_initialize(dmnsn_rtstate *state,
   state->is_shadow_ray = false;
 }
 
-/** Calculate the background color. */
+/// Calculate the background color.
 static void dmnsn_trace_background(dmnsn_rtstate *state, dmnsn_line ray);
-/** Calculate the base pigment at the intersection. */
+/// Calculate the base pigment at the intersection.
 static void dmnsn_trace_pigment(dmnsn_rtstate *state);
-/** Handle light, shadow, and shading. */
+/// Handle light, shadow, and shading.
 static void dmnsn_trace_lighting(dmnsn_rtstate *state);
-/** Trace a reflected ray. */
+/// Trace a reflected ray.
 static void dmnsn_trace_reflection(dmnsn_rtstate *state);
-/** Trace a transmitted ray. */
+/// Trace a transmitted ray.
 static void dmnsn_trace_transparency(dmnsn_rtstate *state);
 
-/* Shoot a ray, and calculate the color */
+// Shoot a ray, and calculate the color
 static dmnsn_tcolor
 dmnsn_ray_shoot(dmnsn_rtstate *state, dmnsn_line ray)
 {
@@ -232,7 +232,7 @@ dmnsn_ray_shoot(dmnsn_rtstate *state, dmnsn_line ray)
   bool reset = state->reclevel == state->scene->reclimit - 1;
   dmnsn_bvh_intersection(state->bvh, ray, &intersection, reset);
   if (dmnsn_bvh_intersection(state->bvh, ray, &intersection, reset)) {
-    /* Found an intersection */
+    // Found an intersection
     dmnsn_rtstate_initialize(state, &intersection);
 
     dmnsn_trace_pigment(state);
@@ -246,7 +246,7 @@ dmnsn_ray_shoot(dmnsn_rtstate *state, dmnsn_line ray)
       dmnsn_trace_transparency(state);
     }
   } else {
-    /* No intersection, return the background color */
+    // No intersection, return the background color
     dmnsn_trace_background(state, ray);
   }
 
@@ -277,7 +277,7 @@ dmnsn_trace_pigment(dmnsn_rtstate *state)
   state->color = state->pigment;
 }
 
-/** Determine the amount of specular highlight. */
+/// Determine the amount of specular highlight.
 static inline dmnsn_color
 dmnsn_evaluate_specular(const dmnsn_rtstate *state)
 {
@@ -292,7 +292,7 @@ dmnsn_evaluate_specular(const dmnsn_rtstate *state)
   }
 }
 
-/** Determine the amount of reflected light. */
+/// Determine the amount of reflected light.
 static inline dmnsn_color
 dmnsn_evaluate_reflection(const dmnsn_rtstate *state,
                           dmnsn_color light, dmnsn_vector direction)
@@ -308,7 +308,7 @@ dmnsn_evaluate_reflection(const dmnsn_rtstate *state,
   }
 }
 
-/** Determine the amount of transmitted light. */
+/// Determine the amount of transmitted light.
 static inline dmnsn_color
 dmnsn_evaluate_transparency(const dmnsn_rtstate *state, dmnsn_color light)
 {
@@ -321,7 +321,7 @@ dmnsn_evaluate_transparency(const dmnsn_rtstate *state, dmnsn_color light)
   }
 }
 
-/** Get a light's diffuse contribution to the object */
+/// Get a light's diffuse contribution to the object
 static inline dmnsn_color
 dmnsn_evaluate_diffuse(const dmnsn_rtstate *state)
 {
@@ -336,7 +336,7 @@ dmnsn_evaluate_diffuse(const dmnsn_rtstate *state)
   }
 }
 
-/** Get the color of a light ray at an intersection point. */
+/// Get the color of a light ray at an intersection point.
 static bool
 dmnsn_trace_light_ray(dmnsn_rtstate *state, const dmnsn_light *light)
 {
@@ -344,10 +344,10 @@ dmnsn_trace_light_ray(dmnsn_rtstate *state, const dmnsn_light *light)
     state->r,
     light->direction_fn(light, state->r)
   );
-  /* Add epsilon to avoid hitting ourselves with the shadow ray */
+  // Add epsilon to avoid hitting ourselves with the shadow ray
   shadow_ray = dmnsn_line_add_epsilon(shadow_ray);
 
-  /* Check if we're casting a shadow on ourself */
+  // Check if we're casting a shadow on ourself
   if ((dmnsn_vector_dot(shadow_ray.n, state->intersection->normal)
        * dmnsn_vector_dot(state->viewer, state->intersection->normal) < 0.0)
       && (!state->is_shadow_ray || state->pigment.T < dmnsn_epsilon))
@@ -358,7 +358,7 @@ dmnsn_trace_light_ray(dmnsn_rtstate *state, const dmnsn_light *light)
   state->light_ray = dmnsn_vector_normalized(shadow_ray.n);
   state->light_color = light->illumination_fn(light, state->r);
 
-  /* Test for shadow ray intersections */
+  // Test for shadow ray intersections
   dmnsn_intersection shadow_caster;
   bool in_shadow = dmnsn_bvh_intersection(state->bvh, shadow_ray,
                                           &shadow_caster, false);
@@ -382,13 +382,13 @@ dmnsn_trace_light_ray(dmnsn_rtstate *state, const dmnsn_light *light)
       if (dmnsn_trace_light_ray(&shadow_state, light)) {
         state->light_color = shadow_state.light_color;
 
-        /* Handle reflection */
+        // Handle reflection
         dmnsn_color reflected = dmnsn_evaluate_reflection(
           &shadow_state, state->light_color, state->light_ray
         );
         state->light_color = dmnsn_color_sub(state->light_color, reflected);
 
-        /* Handle transparency */
+        // Handle transparency
         state->light_color = dmnsn_evaluate_transparency(
           &shadow_state, state->light_color
         );
@@ -404,13 +404,13 @@ dmnsn_trace_light_ray(dmnsn_rtstate *state, const dmnsn_light *light)
 static void
 dmnsn_trace_lighting(dmnsn_rtstate *state)
 {
-  /* Calculate the ambient color */
+  // Calculate the ambient color
   state->color = DMNSN_TCOLOR(dmnsn_black);
   const dmnsn_finish *finish = &state->texture->finish;
   if (finish->ambient) {
     dmnsn_color ambient = finish->ambient->ambient;
 
-    /* Handle reflection and transmittance of the ambient light */
+    // Handle reflection and transmittance of the ambient light
     dmnsn_color reflected = dmnsn_evaluate_reflection(
       state, ambient, state->intersection->normal
     );
@@ -421,7 +421,7 @@ dmnsn_trace_lighting(dmnsn_rtstate *state)
     state->color.c = dmnsn_color_illuminate(ambient, state->pigment.c);
   }
 
-  /* Iterate over each light */
+  // Iterate over each light
   DMNSN_ARRAY_FOREACH (dmnsn_light **, light, state->scene->lights) {
     if (dmnsn_trace_light_ray(state, *light)) {
       if (state->scene->quality & DMNSN_RENDER_FINISH) {
@@ -460,12 +460,12 @@ dmnsn_trace_reflection(dmnsn_rtstate *state)
 
     dmnsn_rtstate recursive_state = *state;
 
-    /* Calculate ADC value */
+    // Calculate ADC value
     recursive_state.adc_value = dmnsn_evaluate_reflection(
       state, state->adc_value, state->reflected
     );
 
-    /* Shoot the reflected ray */
+    // Shoot the reflected ray
     dmnsn_color rec = dmnsn_ray_shoot(&recursive_state, refl_ray).c;
     dmnsn_color reflected = dmnsn_evaluate_reflection(
       state, rec, state->reflected
@@ -489,23 +489,23 @@ dmnsn_trace_transparency(dmnsn_rtstate *state)
 
     dmnsn_rtstate recursive_state = *state;
 
-    /* Calculate new refractive index */
+    // Calculate new refractive index
     if (dmnsn_vector_dot(r, n) < 0.0) {
-      /* We are entering an object */
+      // We are entering an object
       recursive_state.ior = interior->ior;
       recursive_state.parent = state;
     } else {
-      /* We are leaving an object */
+      // We are leaving an object
       recursive_state.ior = state->parent ? state->parent->ior : 1.0;
       recursive_state.parent = state->parent ? state->parent->parent : NULL;
     }
 
-    /* Calculate transmitted ray direction */
-    double iorr = state->ior/recursive_state.ior; /* ior ratio */
+    // Calculate transmitted ray direction
+    double iorr = state->ior/recursive_state.ior; // ior ratio
     double c1 = -dmnsn_vector_dot(r, n);
     double c2 = 1.0 - iorr*iorr*(1.0 - c1*c1);
     if (c2 <= 0.0) {
-      /* Total internal reflection */
+      // Total internal reflection
       return;
     }
     c2 = sqrt(c2);
@@ -521,7 +521,7 @@ dmnsn_trace_transparency(dmnsn_rtstate *state)
       );
     }
 
-    /* Calculate ADC value */
+    // Calculate ADC value
     recursive_state.adc_value = dmnsn_evaluate_transparency(
       state, state->adc_value
     );
@@ -532,11 +532,11 @@ dmnsn_trace_transparency(dmnsn_rtstate *state)
       recursive_state.adc_value, adc_reflected
     );
 
-    /* Shoot the transmitted ray */
+    // Shoot the transmitted ray
     dmnsn_color rec = dmnsn_ray_shoot(&recursive_state, trans_ray).c;
     dmnsn_color filtered = dmnsn_evaluate_transparency(state, rec);
 
-    /* Conserve energy */
+    // Conserve energy
     dmnsn_color reflected = dmnsn_evaluate_reflection(
       state, filtered, state->reflected
     );
diff --git a/libdimension/reflection.c b/libdimension/reflection.c
index 3b2aeeb..6765bef 100644
--- a/libdimension/reflection.c
+++ b/libdimension/reflection.c
@@ -27,14 +27,14 @@
 #include <math.h>
 #include <stdlib.h>
 
-/** Basic reflective finish type. */
+/// Basic reflective finish type.
 typedef struct dmnsn_basic_reflection {
   dmnsn_reflection reflection;
   dmnsn_color min, max;
   double falloff;
 } dmnsn_basic_reflection;
 
-/** Reflective finish callback. */
+/// Reflective finish callback.
 static dmnsn_color
 dmnsn_basic_reflection_fn(const dmnsn_reflection *reflection,
                           dmnsn_color reflect, dmnsn_color color,
diff --git a/libdimension/rgba.h b/libdimension/rgba.h
index 21d5044..a67caf2 100644
--- a/libdimension/rgba.h
+++ b/libdimension/rgba.h
@@ -23,16 +23,16 @@
  * RGBA canvas optimizer interface, used by image optimizers.
  */
 
-/** Apply the RGBA8 optimizer to a canvas. */
+/// Apply the RGBA8 optimizer to a canvas.
 DMNSN_INTERNAL void dmnsn_rgba8_optimize_canvas(dmnsn_canvas *canvas);
-/** Apply the RGBA16 optimizer to a canvas. */
+/// Apply the RGBA16 optimizer to a canvas.
 DMNSN_INTERNAL void dmnsn_rgba16_optimize_canvas(dmnsn_canvas *canvas);
 
-/** RGBA8 optimizer callback. */
+/// RGBA8 optimizer callback.
 DMNSN_INTERNAL void dmnsn_rgba8_optimizer_fn(const dmnsn_canvas *canvas,
                                              void *ptr,
                                              size_t x, size_t y);
-/** RGBA16 optimizer callback. */
+/// RGBA16 optimizer callback.
 DMNSN_INTERNAL void dmnsn_rgba16_optimizer_fn(const dmnsn_canvas *canvas,
                                               void *ptr,
                                               size_t x, size_t y);
diff --git a/libdimension/scene.c b/libdimension/scene.c
index 18cda80..6c9c495 100644
--- a/libdimension/scene.c
+++ b/libdimension/scene.c
@@ -26,7 +26,7 @@
 #include "dimension-internal.h"
 #include <stdlib.h>
 
-/* Allocate an empty scene */
+// Allocate an empty scene
 dmnsn_scene *
 dmnsn_new_scene(dmnsn_pool *pool)
 {
diff --git a/libdimension/solid_pigment.c b/libdimension/solid_pigment.c
index 1f6cf6f..8c94e1c 100644
--- a/libdimension/solid_pigment.c
+++ b/libdimension/solid_pigment.c
@@ -26,7 +26,7 @@
 #include "dimension.h"
 #include <stdlib.h>
 
-/* Create a solid color */
+// Create a solid color
 dmnsn_pigment *
 dmnsn_new_solid_pigment(dmnsn_pool *pool, dmnsn_tcolor color)
 {
diff --git a/libdimension/sphere.c b/libdimension/sphere.c
index cd791c3..5555499 100644
--- a/libdimension/sphere.c
+++ b/libdimension/sphere.c
@@ -25,12 +25,12 @@
 
 #include "dimension-internal.h"
 
-/** Sphere intersection callback. */
+/// Sphere intersection callback.
 static bool
 dmnsn_sphere_intersection_fn(const dmnsn_object *sphere, dmnsn_line l,
                              dmnsn_intersection *intersection)
 {
-  /* Solve (x0 + nx*t)^2 + (y0 + ny*t)^2 + (z0 + nz*t)^2 == 1 */
+  // Solve (x0 + nx*t)^2 + (y0 + ny*t)^2 + (z0 + nz*t)^2 == 1
   double poly[3], x[2];
   poly[2] = dmnsn_vector_dot(l.n, l.n);
   poly[1] = 2.0*dmnsn_vector_dot(l.n, l.x0);
@@ -42,7 +42,7 @@ dmnsn_sphere_intersection_fn(const dmnsn_object *sphere, dmnsn_line l,
   }
 
   double t = x[0];
-  /* Optimize for the case where we're outside the sphere */
+  // Optimize for the case where we're outside the sphere
   if (dmnsn_likely(n == 2)) {
     t = dmnsn_min(t, x[1]);
   }
@@ -52,23 +52,23 @@ dmnsn_sphere_intersection_fn(const dmnsn_object *sphere, dmnsn_line l,
   return true;
 }
 
-/** Sphere inside callback. */
+/// Sphere inside callback.
 static bool
 dmnsn_sphere_inside_fn(const dmnsn_object *sphere, dmnsn_vector point)
 {
   return point.x*point.x + point.y*point.y + point.z*point.z < 1.0;
 }
 
-/** Sphere bounding callback. */
+/// Sphere bounding callback.
 static dmnsn_bounding_box
 dmnsn_sphere_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
 {
-  /* TODO: tighter bound */
+  // TODO: tighter bound
   dmnsn_bounding_box box = dmnsn_symmetric_bounding_box(dmnsn_new_vector(1.0, 1.0, 1.0));
   return dmnsn_transform_bounding_box(trans, box);
 }
 
-/** Sphere vtable. */
+/// Sphere vtable.
 static const dmnsn_object_vtable dmnsn_sphere_vtable = {
   .intersection_fn = dmnsn_sphere_intersection_fn,
   .inside_fn = dmnsn_sphere_inside_fn,
diff --git a/libdimension/tests/custom-error-fn.c b/libdimension/tests/custom-error-fn.c
index 9e12457..49a0f9e 100644
--- a/libdimension/tests/custom-error-fn.c
+++ b/libdimension/tests/custom-error-fn.c
@@ -17,7 +17,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  *************************************************************************/
 
-/* Make sure that custom fatal error handlers work. */
+// Make sure that custom fatal error handlers work.
 
 #include "dimension.h"
 #include <stdlib.h>
diff --git a/libdimension/tests/cxx.cpp b/libdimension/tests/cxx.cpp
index 7405502..104ee1b 100644
--- a/libdimension/tests/cxx.cpp
+++ b/libdimension/tests/cxx.cpp
@@ -26,10 +26,10 @@
 int
 main(void)
 {
-  /* Treat warnings as errors for tests */
+  // Treat warnings as errors for tests
   dmnsn_die_on_warnings(true);
 
-  /* Make sure we can to bit-ops on this enum type */
+  // Make sure we can to bit-ops on this enum type
   dmnsn_quality quality = DMNSN_RENDER_PIGMENT | DMNSN_RENDER_LIGHTS;
 
   return EXIT_SUCCESS;
diff --git a/libdimension/tests/dictionary.c b/libdimension/tests/dictionary.c
index ca0c6b0..117887a 100644
--- a/libdimension/tests/dictionary.c
+++ b/libdimension/tests/dictionary.c
@@ -86,12 +86,12 @@ DMNSN_TEST(dictionary, insert_overwrites)
   const int value1 = 123, value2 = 456;
   int value_out;
 
-  /* Insert and read back value1 */
+  // Insert and read back value1
   dmnsn_dictionary_insert(dict, "key", &value1);
   ck_assert(dmnsn_dictionary_get(dict, "key", &value_out));
   ck_assert_int_eq(value_out, value1);
 
-  /* Insert and read back value2 */
+  // Insert and read back value2
   dmnsn_dictionary_insert(dict, "key", &value2);
   ck_assert(dmnsn_dictionary_get(dict, "key", &value_out));
   ck_assert_int_eq(value_out, value2);
diff --git a/libdimension/tests/display.c b/libdimension/tests/display.c
index 133eb25..9cd71fe 100644
--- a/libdimension/tests/display.c
+++ b/libdimension/tests/display.c
@@ -31,7 +31,7 @@ struct dmnsn_display {
   XVisualInfo *vi;
 };
 
-/* XIfEvent callback */
+// XIfEvent callback
 static Bool
 WaitForNotify(Display *d, XEvent *e, char *arg)
 {
@@ -60,14 +60,14 @@ dmnsn_new_display(const dmnsn_canvas *canvas)
   display->cx   = NULL;
   display->vi   = NULL;
 
-  /* Get an X connection */
+  // Get an X connection
   display->dpy = XOpenDisplay(0);
   if (!display->dpy) {
     dmnsn_delete_display(display);
     return NULL;
   }
 
-  /* Get an appropriate visual */
+  // Get an appropriate visual
   display->vi = glXChooseVisual(display->dpy, DefaultScreen(display->dpy),
                                 attributeList);
   if (!display->vi) {
@@ -75,14 +75,14 @@ dmnsn_new_display(const dmnsn_canvas *canvas)
     return NULL;
   }
 
-  /* Create a GLX context */
+  // Create a GLX context
   display->cx = glXCreateContext(display->dpy, display->vi, 0, GL_TRUE);
   if (!display->cx) {
     dmnsn_delete_display(display);
     return NULL;
   }
 
-  /* Create a color map */
+  // Create a color map
   display->cmap = XCreateColormap(display->dpy,
                                   RootWindow(display->dpy, display->vi->screen),
                                   display->vi->visual, AllocNone);
@@ -91,7 +91,7 @@ dmnsn_new_display(const dmnsn_canvas *canvas)
     return NULL;
   }
 
-  /* Create a window */
+  // Create a window
   swa.colormap = display->cmap;
   swa.border_pixel = 0;
   swa.event_mask = StructureNotifyMask;
@@ -111,7 +111,7 @@ dmnsn_new_display(const dmnsn_canvas *canvas)
   XMapWindow(display->dpy, display->win);
   XIfEvent(display->dpy, &display->event, WaitForNotify, (char*)display->win);
 
-  /* Connect the context to the window */
+  // Connect the context to the window
   glXMakeCurrent(display->dpy, display->win, display->cx);
   glClearColor(0.0, 0.0, 0.0, 1.0);
   glClear(GL_COLOR_BUFFER_BIT);
diff --git a/libdimension/tests/error.c b/libdimension/tests/error.c
index f4ffcee..58a5b43 100644
--- a/libdimension/tests/error.c
+++ b/libdimension/tests/error.c
@@ -17,7 +17,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  *************************************************************************/
 
-/* Make sure that errors terminate us - this test should fail */
+// Make sure that errors terminate us - this test should fail
 
 #include "dimension.h"
 #include <stdlib.h>
diff --git a/libdimension/tests/gl.c b/libdimension/tests/gl.c
index c46eada..262fecf 100644
--- a/libdimension/tests/gl.c
+++ b/libdimension/tests/gl.c
@@ -23,17 +23,17 @@
 int
 main(void)
 {
-  /* Treat warnings as errors for tests */
+  // Treat warnings as errors for tests
   dmnsn_die_on_warnings(true);
 
-  /* Allocate our canvas */
+  // Allocate our canvas
   dmnsn_pool *pool = dmnsn_new_pool();
   dmnsn_canvas *canvas = dmnsn_new_canvas(pool, 768, 480);
 
-  /* Paint the test pattern */
+  // Paint the test pattern
   dmnsn_paint_test_canvas(canvas);
 
-  /* Create a new glX display */
+  // Create a new glX display
   dmnsn_display *display = dmnsn_new_display(canvas);
   if (!display) {
     fprintf(stderr, "--- WARNING: Couldn't initialize X or glX! ---\n");
@@ -41,7 +41,7 @@ main(void)
     return EXIT_SUCCESS;
   }
 
-  /* Draw to OpenGL */
+  // Draw to OpenGL
   printf("Drawing to OpenGL\n");
   if (dmnsn_gl_write_canvas(canvas) != 0) {
     dmnsn_delete_display(display);
@@ -55,14 +55,14 @@ main(void)
    * Now test GL import/export
    */
 
-  /* Optimize the canvas for GL drawing */
+  // Optimize the canvas for GL drawing
   if (dmnsn_gl_optimize_canvas(canvas) != 0) {
     dmnsn_delete_pool(pool);
     fprintf(stderr, "--- Couldn't optimize canvas for GL! ---\n");
     return EXIT_FAILURE;
   }
 
-  /* Read the image back from OpenGL */
+  // Read the image back from OpenGL
   printf("Reading from OpenGL\n");
   if (dmnsn_gl_read_canvas(canvas, 0, 0) != 0) {
     dmnsn_delete_display(display);
@@ -71,7 +71,7 @@ main(void)
     return EXIT_FAILURE;
   }
 
-  /* And draw it back */
+  // And draw it back
   printf("Drawing to OpenGL\n");
   if (dmnsn_gl_write_canvas(canvas) != 0) {
     dmnsn_delete_display(display);
diff --git a/libdimension/tests/png.c b/libdimension/tests/png.c
index ed64b39..1feff72 100644
--- a/libdimension/tests/png.c
+++ b/libdimension/tests/png.c
@@ -26,24 +26,24 @@ main(void)
 {
   int ret = EXIT_SUCCESS;
 
-  /* Treat warnings as errors for tests */
+  // Treat warnings as errors for tests
   dmnsn_die_on_warnings(true);
 
-  /* Allocate our canvas */
+  // Allocate our canvas
   dmnsn_pool *pool = dmnsn_new_pool();
   dmnsn_canvas *canvas = dmnsn_new_canvas(pool, 768, 480);
 
-  /* Optimize the canvas for PNG export */
+  // Optimize the canvas for PNG export
   if (dmnsn_png_optimize_canvas(canvas) != 0) {
     fprintf(stderr, "--- Couldn't optimize canvas for PNG! ---\n");
     ret = EXIT_FAILURE;
     goto exit;
   }
 
-  /* Paint the test pattern */
+  // Paint the test pattern
   dmnsn_paint_test_canvas(canvas);
 
-  /* Write the image to PNG */
+  // Write the image to PNG
 
   printf("Writing scene to PNG\n");
   FILE *ofile = fopen("png1.png", "wb");
@@ -66,7 +66,7 @@ main(void)
    * Now test PNG import/export
    */
 
-  /* Read the image back from PNG */
+  // Read the image back from PNG
 
   printf("Reading scene from PNG\n");
   FILE *ifile = fopen("png1.png", "rb");
@@ -86,7 +86,7 @@ main(void)
 
   fclose(ifile);
 
-  /* And write it back */
+  // And write it back
 
   printf("Writing scene to PNG\n");
   ofile = fopen("png2.png", "wb");
diff --git a/libdimension/tests/polynomial.c b/libdimension/tests/polynomial.c
index b734cc2..dc172d4 100644
--- a/libdimension/tests/polynomial.c
+++ b/libdimension/tests/polynomial.c
@@ -69,7 +69,7 @@ dmnsn_assert_roots(const double poly[], size_t degree, size_t nroots_ex, ...)
 
 DMNSN_TEST(linear, no_positive_roots)
 {
-  /* poly[] = x + 1 */
+  // poly[] = x + 1
   static const double poly[] = {
     [1] = 1.0,
     [0] = 1.0,
@@ -79,7 +79,7 @@ DMNSN_TEST(linear, no_positive_roots)
 
 DMNSN_TEST(linear, one_root)
 {
-  /* poly[] = x - 1 */
+  // poly[] = x - 1
   static const double poly[] = {
     [1] =  1.0,
     [0] = -1.0,
@@ -90,7 +90,7 @@ DMNSN_TEST(linear, one_root)
 
 DMNSN_TEST(quadratic, no_roots)
 {
-  /* poly[] = x^2 + 1 */
+  // poly[] = x^2 + 1
   static const double poly[] = {
     [2] = 1.0,
     [1] = 0.0,
@@ -101,7 +101,7 @@ DMNSN_TEST(quadratic, no_roots)
 
 DMNSN_TEST(quadratic, no_positive_roots)
 {
-  /* poly[] = (x + 1)^2 */
+  // poly[] = (x + 1)^2
   static const double poly[] = {
     [2] = 1.0,
     [1] = 2.0,
@@ -112,7 +112,7 @@ DMNSN_TEST(quadratic, no_positive_roots)
 
 DMNSN_TEST(quadratic, one_positive_root)
 {
-  /* poly[] = (x + 1)*(x - 1) */
+  // poly[] = (x + 1)*(x - 1)
   static const double poly[] = {
     [2] =  1.0,
     [1] =  0.0,
@@ -123,7 +123,7 @@ DMNSN_TEST(quadratic, one_positive_root)
 
 DMNSN_TEST(quadratic, two_roots)
 {
-  /* poly[] = (x - 1.2345)*(x - 2.3456) */
+  // poly[] = (x - 1.2345)*(x - 2.3456)
   static const double poly[] = {
     [2] =  1.0,
     [1] = -3.5801,
@@ -135,7 +135,7 @@ DMNSN_TEST(quadratic, two_roots)
 
 DMNSN_TEST(cubic, no_positive_roots)
 {
-  /* poly[] = x^3 + 1 */
+  // poly[] = x^3 + 1
   static const double poly[] = {
     [3] = 1.0,
     [2] = 0.0,
@@ -147,7 +147,7 @@ DMNSN_TEST(cubic, no_positive_roots)
 
 DMNSN_TEST(cubic, one_root)
 {
-  /* poly[] = x^3 - 1 */
+  // poly[] = x^3 - 1
   static const double poly[] = {
     [3] =  1.0,
     [2] =  0.0,
@@ -171,7 +171,7 @@ DMNSN_TEST(cubic, two_roots)
 
 DMNSN_TEST(cubic, three_roots)
 {
-  /* poly[] = (x - 1.2345)*(x - 2.3456)*(x - 100) */
+  // poly[] = (x - 1.2345)*(x - 2.3456)*(x - 100)
   static const double poly[] = {
     [3] =    1.0,
     [2] = -103.5801,
@@ -184,7 +184,7 @@ DMNSN_TEST(cubic, three_roots)
 
 DMNSN_TEST(quintic, four_roots)
 {
-  /* poly[] = 2*(x + 1)*(x - 1.2345)*(x - 2.3456)*(x - 5)*(x - 100) */
+  // poly[] = 2*(x + 1)*(x - 1.2345)*(x - 2.3456)*(x - 5)*(x - 100)
   static const double poly[] = {
     [5] =     2.0,
     [4] =  -215.1602,
@@ -196,7 +196,7 @@ DMNSN_TEST(quintic, four_roots)
   dmnsn_assert_roots(poly, 5, 4, 1.2345, 2.3456, 5.0, 100.0);
 }
 
-/* repeated_root[] = (x - 1)^6 */
+// repeated_root[] = (x - 1)^6
 static const double repeated_root[7] = {
   [6] =   1.0,
   [5] =  -6.0,
diff --git a/libdimension/tests/pool.c b/libdimension/tests/pool.c
index d12850d..83f25f7 100644
--- a/libdimension/tests/pool.c
+++ b/libdimension/tests/pool.c
@@ -46,7 +46,7 @@ DMNSN_TEST(pool, simple)
     *p = i;
   }
 
-  /* Leak checking will tell us if something bad happened */
+  // Leak checking will tell us if something bad happened
 }
 
 static int counter = 0;
diff --git a/libdimension/tests/prtree.c b/libdimension/tests/prtree.c
index fdc5878..3c2b7bf 100644
--- a/libdimension/tests/prtree.c
+++ b/libdimension/tests/prtree.c
@@ -75,7 +75,7 @@ dmnsn_new_fake_object(dmnsn_pool *pool)
 int
 main(void)
 {
-  /* Treat warnings as errors for tests */
+  // Treat warnings as errors for tests
   dmnsn_die_on_warnings(true);
 
   dmnsn_pool *pool = dmnsn_new_pool();
diff --git a/libdimension/tests/render.c b/libdimension/tests/render.c
index 9b830f6..2588937 100644
--- a/libdimension/tests/render.c
+++ b/libdimension/tests/render.c
@@ -25,7 +25,7 @@
 static void
 dmnsn_test_scene_set_defaults(dmnsn_pool *pool, dmnsn_scene *scene)
 {
-  /* Default texture */
+  // Default texture
   scene->default_texture->pigment = dmnsn_new_solid_pigment(pool, DMNSN_TCOLOR(dmnsn_black));
   dmnsn_finish *default_finish = &scene->default_texture->finish;
   default_finish->ambient = dmnsn_new_ambient(
@@ -43,7 +43,7 @@ dmnsn_test_scene_add_canvas(dmnsn_pool *pool, dmnsn_scene *scene)
 static void
 dmnsn_test_scene_add_camera(dmnsn_pool *pool, dmnsn_scene *scene)
 {
-  /* Set up the transformation matrix for the perspective camera */
+  // Set up the transformation matrix for the perspective camera
   dmnsn_matrix trans = dmnsn_scale_matrix(
     dmnsn_new_vector(
       ((double)scene->canvas->width)/scene->canvas->height, 1.0, 1.0
@@ -62,7 +62,7 @@ dmnsn_test_scene_add_camera(dmnsn_pool *pool, dmnsn_scene *scene)
     trans
   );
 
-  /* Create a perspective camera */
+  // Create a perspective camera
   scene->camera = dmnsn_new_perspective_camera(pool);
   scene->camera->trans = trans;
 }
@@ -86,7 +86,7 @@ dmnsn_test_scene_add_background(dmnsn_pool *pool, dmnsn_scene *scene)
       dmnsn_new_vector(0.0, dmnsn_radians(53.0), 0.0)
     );
   } else {
-    /* Loading png2.png failed, possibly compiled with --disable-png */
+    // Loading png2.png failed, possibly compiled with --disable-png
     fprintf(stderr, "--- WARNING: Couldn't open or read png2.png! ---\n");
     png_pigment = dmnsn_new_solid_pigment(pool, DMNSN_TCOLOR(dmnsn_orange));
   }
@@ -306,16 +306,16 @@ main(void)
 {
   int ret = EXIT_FAILURE;
 
-  /* Treat warnings as errors for tests */
+  // Treat warnings as errors for tests
   dmnsn_die_on_warnings(true);
 
   dmnsn_display *display = NULL;
 
-  /* Create the test scene */
+  // Create the test scene
   dmnsn_pool *pool = dmnsn_new_pool();
   dmnsn_scene *scene = dmnsn_new_test_scene(pool);
 
-  /* Optimize the canvas for PNG export */
+  // Optimize the canvas for PNG export
   bool have_png = true;
   errno = 0;
   if (dmnsn_png_optimize_canvas(scene->canvas) != 0) {
@@ -327,7 +327,7 @@ main(void)
     }
   }
 
-  /* Optimize the canvas for GL drawing */
+  // Optimize the canvas for GL drawing
   bool have_gl = true;
   errno = 0;
   if (dmnsn_gl_optimize_canvas(scene->canvas) != 0) {
@@ -341,7 +341,7 @@ main(void)
 
   dmnsn_canvas_clear(scene->canvas, DMNSN_TCOLOR(dmnsn_black));
 
-  /* Create a new glX display */
+  // Create a new glX display
   if (have_gl) {
     display = dmnsn_new_display(scene->canvas);
     if (!display) {
@@ -349,12 +349,12 @@ main(void)
     }
   }
 
-  /* Render the scene */
+  // Render the scene
 
   printf("Rendering scene\n");
   dmnsn_future *future = dmnsn_ray_trace_async(scene);
 
-  /* Display the scene as it's rendered */
+  // Display the scene as it's rendered
   if (display) {
     while (!dmnsn_future_is_done(future)) {
       dmnsn_future_pause(future);
@@ -373,7 +373,7 @@ main(void)
     goto exit;
   }
 
-  /* Make sure we show the completed rendering */
+  // Make sure we show the completed rendering
   if (display) {
     printf("Drawing to OpenGL\n");
     if (dmnsn_gl_write_canvas(scene->canvas) != 0) {
diff --git a/libdimension/tests/tests.h b/libdimension/tests/tests.h
index 0b8bfce..6e9ad21 100644
--- a/libdimension/tests/tests.h
+++ b/libdimension/tests/tests.h
@@ -24,19 +24,19 @@
 #include <check.h>
 
 #ifdef __cplusplus
-/* We've been included from a C++ file; mark everything here as extern "C" */
+// We've been included from a C++ file; mark everything here as extern "C"
 extern "C" {
 #endif
 
-/** @internal Map to known test cases from their names. */
+/// @internal Map to known test cases from their names.
 extern dmnsn_dictionary* dmnsn_test_cases;
 
-/** @internal Get the test case with the given name, possibly creating it. */
+/// @internal Get the test case with the given name, possibly creating it.
 TCase *dmnsn_get_test_case(const char* name);
 
-/** @internal Default test fixture. */
+/// @internal Default test fixture.
 void dmnsn_test_setup(void);
-/** @internal Default test fixture. */
+/// @internal Default test fixture.
 void dmnsn_test_teardown(void);
 
 /**
@@ -121,11 +121,11 @@ typedef struct dmnsn_display dmnsn_display;
 dmnsn_display *dmnsn_new_display(const dmnsn_canvas *canvas);
 void dmnsn_delete_display(dmnsn_display *display);
 
-/* Flush the GL buffers */
+// Flush the GL buffers
 void dmnsn_display_flush(dmnsn_display *display);
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* TESTS_H */
+#endif // TESTS_H
diff --git a/libdimension/tests/unit-test.c b/libdimension/tests/unit-test.c
index 2ba3baf..5d3f699 100644
--- a/libdimension/tests/unit-test.c
+++ b/libdimension/tests/unit-test.c
@@ -47,7 +47,7 @@ dmnsn_get_test_case(const char* name)
 void
 dmnsn_test_setup(void)
 {
-  /* Treat warnings as errors for tests */
+  // Treat warnings as errors for tests
   dmnsn_die_on_warnings(true);
 }
 
@@ -89,21 +89,21 @@ dmnsn_test_suite(void)
 int
 main(void)
 {
-  /* Treat warnings as errors for tests */
+  // Treat warnings as errors for tests
   dmnsn_die_on_warnings(true);
 
-  /* Create the test suite */
+  // Create the test suite
   Suite *suite = dmnsn_test_suite();
   SRunner *sr = srunner_create(suite);
 
-  /* Run the tests */
+  // Run the tests
   srunner_run_all(sr, CK_VERBOSE);
   int nfailed = srunner_ntests_failed(sr);
 
-  /* Clean up */
+  // Clean up
   srunner_free(sr);
 
-  /* Return the right result code */
+  // Return the right result code
   if (nfailed == 0) {
     return EXIT_SUCCESS;
   } else {
diff --git a/libdimension/tests/warning-as-error.c b/libdimension/tests/warning-as-error.c
index dfc08d6..7d0fdb7 100644
--- a/libdimension/tests/warning-as-error.c
+++ b/libdimension/tests/warning-as-error.c
@@ -17,7 +17,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  *************************************************************************/
 
-/* Make sure warnings kill us in strict mode - this test should fail */
+// Make sure warnings kill us in strict mode - this test should fail
 
 #include "dimension.h"
 #include <stdlib.h>
diff --git a/libdimension/tests/warning.c b/libdimension/tests/warning.c
index 4e5dd75..cc1aed1 100644
--- a/libdimension/tests/warning.c
+++ b/libdimension/tests/warning.c
@@ -17,7 +17,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  *************************************************************************/
 
-/* Make sure warnings don't kill us - this test should pass */
+// Make sure warnings don't kill us - this test should pass
 
 #include "dimension.h"
 #include <stdlib.h>
diff --git a/libdimension/threads.c b/libdimension/threads.c
index 539a3f9..1fee01d 100644
--- a/libdimension/threads.c
+++ b/libdimension/threads.c
@@ -26,14 +26,14 @@
 #include "dimension-internal.h"
 #include <pthread.h>
 
-/** The payload to pass to the pthread callback. */
+/// The payload to pass to the pthread callback.
 typedef struct dmnsn_thread_payload {
   dmnsn_thread_fn *thread_fn;
   void *arg;
   dmnsn_future *future;
 } dmnsn_thread_payload;
 
-/** Clean up after a thread. */
+/// Clean up after a thread.
 static void
 dmnsn_thread_cleanup(void *arg)
 {
@@ -44,7 +44,7 @@ dmnsn_thread_cleanup(void *arg)
   dmnsn_future_finish(future);
 }
 
-/** pthread callback -- call the real thread callback. */
+/// pthread callback -- call the real thread callback.
 static void *
 dmnsn_thread(void *arg)
 {
@@ -71,7 +71,7 @@ dmnsn_new_thread(dmnsn_future *future, dmnsn_thread_fn *thread_fn, void *arg)
   }
 }
 
-/** Payload for threads executed by dmnsn_execute_concurrently(). */
+/// Payload for threads executed by dmnsn_execute_concurrently().
 typedef struct dmnsn_ccthread_payload {
   dmnsn_future *future;
   dmnsn_ccthread_fn *ccthread_fn;
@@ -177,7 +177,7 @@ dmnsn_execute_concurrently(dmnsn_future *future, dmnsn_ccthread_fn *ccthread_fn,
   return ret;
 }
 
-/* pthread wrappers */
+// pthread wrappers
 
 void
 dmnsn_initialize_mutex(pthread_mutex_t *mutex)
diff --git a/libdimension/threads.h b/libdimension/threads.h
index 57e52aa..839299e 100644
--- a/libdimension/threads.h
+++ b/libdimension/threads.h
@@ -70,9 +70,9 @@ DMNSN_INTERNAL int dmnsn_execute_concurrently(dmnsn_future *future,
  */
 DMNSN_INTERNAL void dmnsn_initialize_mutex(pthread_mutex_t *mutex);
 
-/** dmnsn_lock_mutex() implementation. */
+/// dmnsn_lock_mutex() implementation.
 DMNSN_INTERNAL void dmnsn_lock_mutex_impl(pthread_mutex_t *mutex);
-/** dmnsn_unlock_mutex() implementation. */
+/// dmnsn_unlock_mutex() implementation.
 DMNSN_INTERNAL void dmnsn_unlock_mutex_impl(void *mutex);
 
 /**
@@ -101,11 +101,11 @@ DMNSN_INTERNAL void dmnsn_destroy_mutex(pthread_mutex_t *mutex);
  */
 DMNSN_INTERNAL void dmnsn_initialize_rwlock(pthread_rwlock_t *rwlock);
 
-/** dmnsn_read_lock() implementation. */
+/// dmnsn_read_lock() implementation.
 DMNSN_INTERNAL void dmnsn_read_lock_impl(pthread_rwlock_t *rwlock);
-/** dmnsn_write_lock() implementation. */
+/// dmnsn_write_lock() implementation.
 DMNSN_INTERNAL void dmnsn_write_lock_impl(pthread_rwlock_t *rwlock);
-/** dmnsn_unlock_rwlock() implementation. */
+/// dmnsn_unlock_rwlock() implementation.
 DMNSN_INTERNAL void dmnsn_unlock_rwlock_impl(pthread_rwlock_t *rwlock);
 
 /**
diff --git a/libdimension/torus.c b/libdimension/torus.c
index 2b7a818..30acbd8 100644
--- a/libdimension/torus.c
+++ b/libdimension/torus.c
@@ -25,13 +25,13 @@
 
 #include "dimension.h"
 
-/** Torus type. */
+/// Torus type.
 typedef struct {
   dmnsn_object object;
   double major, minor;
 } dmnsn_torus;
 
-/** Bound the torus in a cylindrical shell. */
+/// Bound the torus in a cylindrical shell.
 static inline bool
 dmnsn_torus_bound_intersection(const dmnsn_torus *torus, dmnsn_line l)
 {
@@ -39,7 +39,7 @@ dmnsn_torus_bound_intersection(const dmnsn_torus *torus, dmnsn_line l)
   double rmax = R + r, rmin = R - r;
   double rmax2 = rmax*rmax, rmin2 = rmin*rmin;
 
-  /* Try the caps first */
+  // Try the caps first
   double tlower = (-r - l.x0.y)/l.n.y;
   double tupper = (+r - l.x0.y)/l.n.y;
   dmnsn_vector lower = dmnsn_line_point(l, tlower);
@@ -47,7 +47,7 @@ dmnsn_torus_bound_intersection(const dmnsn_torus *torus, dmnsn_line l)
   double ldist2 = lower.x*lower.x + lower.z*lower.z;
   double udist2 = upper.x*upper.x + upper.z*upper.z;
   if ((ldist2 < rmin2 || ldist2 > rmax2) && (udist2 < rmin2 || udist2 > rmax2)) {
-    /* No valid intersection with the caps, try the cylinder walls */
+    // No valid intersection with the caps, try the cylinder walls
     double dist2 = l.x0.x*l.x0.x + l.x0.z*l.x0.z;
     double bigcyl[3], smallcyl[3];
     bigcyl[2]   = smallcyl[2] = l.n.x*l.n.x + l.n.z*l.n.z;
@@ -67,7 +67,7 @@ dmnsn_torus_bound_intersection(const dmnsn_torus *torus, dmnsn_line l)
     }
 
     if (i == n) {
-      /* No valid intersection found */
+      // No valid intersection found
       return false;
     }
   }
@@ -75,7 +75,7 @@ dmnsn_torus_bound_intersection(const dmnsn_torus *torus, dmnsn_line l)
   return true;
 }
 
-/** Torus intersection callback. */
+/// Torus intersection callback.
 static bool
 dmnsn_torus_intersection_fn(const dmnsn_object *object, dmnsn_line l,
                             dmnsn_intersection *intersection)
@@ -88,7 +88,7 @@ dmnsn_torus_intersection_fn(const dmnsn_object *object, dmnsn_line l,
     return false;
   }
 
-  /* This bit of algebra here is correct */
+  // This bit of algebra here is correct
   dmnsn_vector x0mod = dmnsn_new_vector(l.x0.x, -l.x0.y, l.x0.z);
   dmnsn_vector nmod  = dmnsn_new_vector(l.n.x,  -l.n.y,  l.n.z);
   double nn      = dmnsn_vector_dot(l.n, l.n);
@@ -131,7 +131,7 @@ dmnsn_torus_intersection_fn(const dmnsn_object *object, dmnsn_line l,
   return true;
 }
 
-/** Torus inside callback. */
+/// Torus inside callback.
 static bool
 dmnsn_torus_inside_fn(const dmnsn_object *object, dmnsn_vector point)
 {
@@ -140,7 +140,7 @@ dmnsn_torus_inside_fn(const dmnsn_object *object, dmnsn_vector point)
   return dmajor*dmajor + point.y*point.y < torus->minor*torus->minor;
 }
 
-/** Torus bounding callback. */
+/// Torus bounding callback.
 static dmnsn_bounding_box
 dmnsn_torus_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
 {
@@ -151,7 +151,7 @@ dmnsn_torus_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
   return dmnsn_transform_bounding_box(trans, box);
 }
 
-/** Torus vtable. */
+/// Torus vtable.
 static const dmnsn_object_vtable dmnsn_torus_vtable = {
   .intersection_fn = dmnsn_torus_intersection_fn,
   .inside_fn = dmnsn_torus_inside_fn,
diff --git a/libdimension/triangle.c b/libdimension/triangle.c
index 6025caa..4a70c59 100644
--- a/libdimension/triangle.c
+++ b/libdimension/triangle.c
@@ -27,18 +27,18 @@
 
 #include "dimension.h"
 
-/** Optimized ray/triangle intersection test. */
+/// Optimized ray/triangle intersection test.
 static inline bool
 dmnsn_ray_triangle_intersection(dmnsn_line l, double *t, double *u, double *v)
 {
-  /* See the change of basis in dmnsn_triangle_basis() */
+  // See the change of basis in dmnsn_triangle_basis()
   *t = -l.x0.z/l.n.z;
   *u = l.x0.x + (*t)*l.n.x;
   *v = l.x0.y + (*t)*l.n.y;
   return *t >= 0.0 && *u >= 0.0 && *v >= 0.0 && *u + *v <= 1.0;
 }
 
-/** Triangle intersection callback. */
+/// Triangle intersection callback.
 static bool
 dmnsn_triangle_intersection_fn(const dmnsn_object *object, dmnsn_line l,
                                dmnsn_intersection *intersection)
@@ -53,14 +53,14 @@ dmnsn_triangle_intersection_fn(const dmnsn_object *object, dmnsn_line l,
   return false;
 }
 
-/** Triangle inside callback. */
+/// Triangle inside callback.
 static bool
 dmnsn_triangle_inside_fn(const dmnsn_object *object, dmnsn_vector point)
 {
   return false;
 }
 
-/** Triangle bounding callback. */
+/// Triangle bounding callback.
 static dmnsn_bounding_box
 dmnsn_triangle_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
 {
@@ -74,20 +74,20 @@ dmnsn_triangle_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
   return box;
 }
 
-/** Triangle vtable. */
+/// Triangle vtable.
 static const dmnsn_object_vtable dmnsn_triangle_vtable = {
   .intersection_fn = dmnsn_triangle_intersection_fn,
   .inside_fn = dmnsn_triangle_inside_fn,
   .bounding_fn = dmnsn_triangle_bounding_fn,
 };
 
-/** Smooth triangle type. */
+/// Smooth triangle type.
 typedef struct {
   dmnsn_object object;
   dmnsn_vector na, nab, nac;
 } dmnsn_smooth_triangle;
 
-/** Smooth triangle intersection callback. */
+/// Smooth triangle intersection callback.
 static bool
 dmnsn_smooth_triangle_intersection_fn(const dmnsn_object *object, dmnsn_line l,
                                       dmnsn_intersection *intersection)
@@ -110,21 +110,19 @@ dmnsn_smooth_triangle_intersection_fn(const dmnsn_object *object, dmnsn_line l,
   return false;
 }
 
-/** Smooth triangle vtable. */
+/// Smooth triangle vtable.
 static const dmnsn_object_vtable dmnsn_smooth_triangle_vtable = {
   .intersection_fn = dmnsn_smooth_triangle_intersection_fn,
   .inside_fn = dmnsn_triangle_inside_fn,
   .bounding_fn = dmnsn_triangle_bounding_fn,
 };
 
-/** Make a change-of-basis matrix. */
+/// Make a change-of-basis matrix.
 static inline dmnsn_matrix
 dmnsn_triangle_basis(dmnsn_vector vertices[3])
 {
-  /*
-   * The new vector space has corners at <1, 0, 0>, <0, 1, 0>, and 0,
-   * corresponding to the basis (ab, ac, ab X ac).
-   */
+  // The new vector space has corners at <1, 0, 0>, <0, 1, 0>, and 0,
+  // corresponding to the basis (ab, ac, ab X ac).
   dmnsn_vector ab = dmnsn_vector_sub(vertices[1], vertices[0]);
   dmnsn_vector ac = dmnsn_vector_sub(vertices[2], vertices[0]);
   dmnsn_vector normal = dmnsn_vector_cross(ab, ac);
@@ -145,7 +143,7 @@ dmnsn_new_smooth_triangle(dmnsn_pool *pool, dmnsn_vector vertices[3], dmnsn_vect
 {
   dmnsn_matrix P = dmnsn_triangle_basis(vertices);
 
-  /* Transform the given normals. */
+  // Transform the given normals.
   dmnsn_vector na = dmnsn_vector_normalized(dmnsn_transform_normal(P, normals[0]));
   dmnsn_vector nb = dmnsn_vector_normalized(dmnsn_transform_normal(P, normals[1]));
   dmnsn_vector nc = dmnsn_vector_normalized(dmnsn_transform_normal(P, normals[2]));
diff --git a/libdimension/triangle_fan.c b/libdimension/triangle_fan.c
index fe974df..0165a51 100644
--- a/libdimension/triangle_fan.c
+++ b/libdimension/triangle_fan.c
@@ -27,14 +27,14 @@
 
 #include "dimension.h"
 
-/** Triangle fan type. */
+/// Triangle fan type.
 typedef struct {
   dmnsn_object object;
   size_t ncoeffs;
   double coeffs[][6];
 } dmnsn_triangle_fan;
 
-/** Change basis from one triangle to the next. */
+/// Change basis from one triangle to the next.
 static inline dmnsn_vector
 dmnsn_change_basis(const double coeffs[6], dmnsn_vector v)
 {
@@ -45,7 +45,7 @@ dmnsn_change_basis(const double coeffs[6], dmnsn_vector v)
   );
 }
 
-/** Change basis from one triangle to the next for a normal vector. */
+/// Change basis from one triangle to the next for a normal vector.
 static inline dmnsn_vector
 dmnsn_change_normal_basis(const double coeffs[6], dmnsn_vector n)
 {
@@ -56,7 +56,7 @@ dmnsn_change_normal_basis(const double coeffs[6], dmnsn_vector n)
   );
 }
 
-/** Triangle intersection callback. */
+/// Triangle intersection callback.
 static bool
 dmnsn_triangle_fan_intersection_fn(const dmnsn_object *object, dmnsn_line l, dmnsn_intersection *intersection)
 {
@@ -98,14 +98,14 @@ dmnsn_triangle_fan_intersection_fn(const dmnsn_object *object, dmnsn_line l, dmn
   return false;
 }
 
-/** Triangle fan inside callback. */
+/// Triangle fan inside callback.
 static bool
 dmnsn_triangle_fan_inside_fn(const dmnsn_object *object, dmnsn_vector point)
 {
   return false;
 }
 
-/** Triangle fan bounding callback. */
+/// Triangle fan bounding callback.
 static dmnsn_bounding_box
 dmnsn_triangle_fan_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
 {
@@ -134,7 +134,7 @@ dmnsn_triangle_fan_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans)
   return box;
 }
 
-/** Triangle fan vtable. */
+/// Triangle fan vtable.
 static dmnsn_object_vtable dmnsn_triangle_fan_vtable = {
   .intersection_fn = dmnsn_triangle_fan_intersection_fn,
   .inside_fn = dmnsn_triangle_fan_inside_fn,
@@ -154,7 +154,7 @@ dmnsn_new_triangle_fan(dmnsn_pool *pool, dmnsn_vector vertices[], size_t nvertic
   dmnsn_init_object(object);
   object->vtable = &dmnsn_triangle_fan_vtable;
 
-  /* Compute the initial matrix and the coefficients */
+  // Compute the initial matrix and the coefficients
   dmnsn_vector a = vertices[0];
   dmnsn_vector ab = dmnsn_vector_sub(vertices[1], a);
   dmnsn_vector ac = dmnsn_vector_sub(vertices[2], a);
-- 
cgit v1.2.3