use the fast double->int conversion in 3dgfx.c
authorJohn Tsiombikas <nuclear@mutantstargoat.com>
Mon, 3 Oct 2016 05:09:59 +0000 (08:09 +0300)
committerJohn Tsiombikas <nuclear@mutantstargoat.com>
Mon, 3 Oct 2016 05:09:59 +0000 (08:09 +0300)
src/3dgfx.c
src/util.h [new file with mode: 0644]

index 30721c8..d7e2e41 100644 (file)
@@ -6,6 +6,7 @@
 #include "3dgfx.h"
 #include "polyfill.h"
 #include "inttypes.h"
+#include "util.h"
 
 #define STACK_SIZE     8
 typedef float g3d_matrix[16];
@@ -388,11 +389,11 @@ void g3d_draw_indexed(int prim, const struct g3d_vertex *varr, int varr_size,
                        v[i].y = (0.5f - v[i].y * 0.5f) * (float)st->height;
 
                        /* convert pos to 24.8 fixed point */
-                       pv[i].x = (int32_t)(v[i].x * 256.0f);
-                       pv[i].y = (int32_t)(v[i].y * 256.0f);
+                       pv[i].x = cround64(v[i].x * 256.0f);
+                       pv[i].y = cround64(v[i].y * 256.0f);
                        /* convert tex coords to 16.16 fixed point */
-                       pv[i].u = (int32_t)(v[i].u * 65536.0f);
-                       pv[i].v = (int32_t)(v[i].v * 65536.0f);
+                       pv[i].u = cround64(v[i].u * 65536.0f);
+                       pv[i].v = cround64(v[i].v * 65536.0f);
                        /* pass the color through as is */
                        pv[i].r = v[i].r;
                        pv[i].g = v[i].g;
@@ -483,9 +484,9 @@ static void shade(struct g3d_vertex *v)
                color[2] += st->mtl.kd[2] * st->lt[i].b * ndotl;
        }
 
-       r = color[0] * 255.0;
-       g = color[1] * 255.0;
-       b = color[2] * 255.0;
+       r = cround64(color[0] * 255.0);
+       g = cround64(color[1] * 255.0);
+       b = cround64(color[2] * 255.0);
 
        v->r = r > 255 ? 255 : r;
        v->g = g > 255 ? 255 : g;
diff --git a/src/util.h b/src/util.h
new file mode 100644 (file)
index 0000000..eb3773d
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#include "inttypes.h"
+
+#ifdef __GNUC__
+#define INLINE __inline
+
+#elif defined(__WATCOMC__)
+#define INLINE __inline
+
+#else
+#define INLINE
+#endif
+
+/* fast conversion of double -> 32bit int
+ * for details see:
+ *  - http://chrishecker.com/images/f/fb/Gdmfp.pdf
+ *  - http://stereopsis.com/FPU.html#convert
+ */
+static INLINE int32_t cround64(double val)
+{
+       val += 6755399441055744.0;
+       return *(int32_t*)&val;
+}
+
+#endif /* UTIL_H_ */