shithub: puzzles

Download patch

ref: e8ac0381f976f2dfd70fbe52e0ec59c1a8da9df6
parent: 26c7f3aa285a45176c940afebe3885ad2be2ed65
author: Ben Harris <bjh21@bjh21.me.uk>
date: Sat Feb 18 13:52:21 EST 2023

Convert a lot of floating-point constants to single precision

For reasons now lost to history, Puzzles generally uses single-precision
floating point.  However, C floating-point constants are by default
double-precision, and if they're then operated on along with a
single-precision variable the value of the variable gets promoted to
double precision, then the operation gets done, and then often the
result gets converted back to single precision again.

This is obviously silly, so I've used Clang's "-Wdouble-promotion" to
find instances of this and mark the constants as single-precision as
well.  This is a bit awkward for PI, which ends up with a cast.  Maybe
there should be a PIF, or maybe PI should just be single-precision.

This doesn't eliminate all warnings from -Wdouble-promotion.  Some of
the others might merit fixing but adding explicit casts to double just
to shut the compiler up would be going too far, I feel.

--- a/cube.c
+++ b/cube.c
@@ -171,7 +171,7 @@
     (ra)[0] = rx; (ra)[1] = ry; (ra)[2] = rz; \
 } while (0)
 
-#define APPROXEQ(x,y) ( SQ(x-y) < 0.1 )
+#define APPROXEQ(x,y) ( SQ(x-y) < 0.1F )
 
 struct grid_square {
     float x, y;
@@ -787,7 +787,7 @@
             dist += SQ(solid->vertices[i*3+1] * flip - sq->points[j*2+1] + sq->y);
             dist += SQ(solid->vertices[i*3+2] - zmin);
 
-            if (dist < 0.1) {
+            if (dist < 0.1F) {
                 matches++;
                 index = i;
             }
@@ -837,7 +837,7 @@
      */
     vx = ret->vertices[key1*3+0] - ret->vertices[key0*3+0];
     vy = ret->vertices[key1*3+1] - ret->vertices[key0*3+1];
-    assert(APPROXEQ(vx*vx + vy*vy, 1.0));
+    assert(APPROXEQ(vx*vx + vy*vy, 1.0F));
 
     vmatrix[0] =  vx; vmatrix[3] = vy; vmatrix[6] = 0;
     vmatrix[1] = -vy; vmatrix[4] = vx; vmatrix[7] = 0;
@@ -1091,11 +1091,11 @@
             for (j = 0; j < from->grid->squares[i].npoints; j++) {
                 dist = (SQ(from->grid->squares[i].points[j*2] - points[0]) +
                         SQ(from->grid->squares[i].points[j*2+1] - points[1]));
-                if (dist < 0.1)
+                if (dist < 0.1F)
                     dkey[match++] = j;
                 dist = (SQ(from->grid->squares[i].points[j*2] - points[2]) +
                         SQ(from->grid->squares[i].points[j*2+1] - points[3]));
-                if (dist < 0.1)
+                if (dist < 0.1F)
                     dkey[match++] = j;
             }
 
--- a/drawing.c
+++ b/drawing.c
@@ -90,8 +90,8 @@
 void draw_thick_line(drawing *dr, float thickness,
 		     float x1, float y1, float x2, float y2, int colour)
 {
-    if (thickness < 1.0)
-        thickness = 1.0;
+    if (thickness < 1.0F)
+        thickness = 1.0F;
     if (dr->api->draw_thick_line) {
 	dr->api->draw_thick_line(dr->handle, thickness,
 				 x1, y1, x2, y2, colour);
@@ -101,8 +101,8 @@
 	 * polygon rendering uses integer coordinates.
 	 */
 	float len = sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
-	float tvhatx = (x2 - x1)/len * (thickness/2 - 0.2);
-	float tvhaty = (y2 - y1)/len * (thickness/2 - 0.2);
+	float tvhatx = (x2 - x1)/len * (thickness/2 - 0.2F);
+	float tvhaty = (y2 - y1)/len * (thickness/2 - 0.2F);
 	int p[8];
 
 	p[0] = x1 - tvhaty;
--- a/emcc.c
+++ b/emcc.c
@@ -1045,9 +1045,9 @@
     for (i = 0; i < ncolours; i++) {
         char col[40];
         sprintf(col, "#%02x%02x%02x",
-                (unsigned)(0.5 + 255 * colours[i*3+0]),
-                (unsigned)(0.5 + 255 * colours[i*3+1]),
-                (unsigned)(0.5 + 255 * colours[i*3+2]));
+                (unsigned)(0.5F + 255 * colours[i*3+0]),
+                (unsigned)(0.5F + 255 * colours[i*3+1]),
+                (unsigned)(0.5F + 255 * colours[i*3+2]));
         colour_strings[i] = dupstr(col);
     }
     /* Put the background colour in a CSS variable. */
--- a/flip.c
+++ b/flip.c
@@ -1160,7 +1160,7 @@
 	coords[7] = by + TILE_SIZE - (int)((float)TILE_SIZE * animtime);
 
 	colour = (tile & 1 ? COL_WRONG : COL_RIGHT);
-	if (animtime < 0.5)
+	if (animtime < 0.5F)
 	    colour = COL_WRONG + COL_RIGHT - colour;
 
 	draw_polygon(dr, coords, 4, colour, COL_GRID);
--- a/galaxies.c
+++ b/galaxies.c
@@ -2503,8 +2503,8 @@
     int px, py;
     space *sp;
 
-    px = 2*FROMCOORD((float)x) + 0.5;
-    py = 2*FROMCOORD((float)y) + 0.5;
+    px = 2*FROMCOORD((float)x) + 0.5F;
+    py = 2*FROMCOORD((float)y) + 0.5F;
 
     if (button == 'C' || button == 'c') return dupstr("C");
 
@@ -2618,8 +2618,8 @@
 
         ui->cur_visible = false;
 
-        px = (int)(2*FROMCOORD((float)x) + 0.5);
-        py = (int)(2*FROMCOORD((float)y) + 0.5);
+        px = (int)(2*FROMCOORD((float)x) + 0.5F);
+        py = (int)(2*FROMCOORD((float)y) + 0.5F);
 
         dot = NULL;
 
--- a/inertia.c
+++ b/inertia.c
@@ -1605,7 +1605,7 @@
 	     * end up the right way round. */
 	    angle = atan2(dx, -dy);
 
-	    angle = (angle + (PI/8)) / (PI/4);
+	    angle = (angle + (float)(PI/8)) / (float)(PI/4);
 	    assert(angle > -16.0F);
 	    dir = (int)(angle + 16.0F) & 7;
 	}
--- a/net.c
+++ b/net.c
@@ -2606,8 +2606,8 @@
 
     for (i = 0; i < npoints; i++) {
         rotated_coords(&xf, &yf, matrix, cx, cy, fpoints[2*i], fpoints[2*i+1]);
-        points[2*i] = 0.5 + xf;
-        points[2*i+1] = 0.5 + yf;
+        points[2*i] = 0.5F + xf;
+        points[2*i+1] = 0.5F + yf;
     }
 
     draw_polygon(dr, points, npoints, colour, colour);
@@ -2747,8 +2747,8 @@
      * rotated by an arbitrary angle about that centre point.
      */
     if (tile & TILE_ROTATING) {
-        matrix[0] = (float)cos(angle * PI / 180.0);
-        matrix[2] = (float)sin(angle * PI / 180.0);
+        matrix[0] = (float)cos(angle * (float)PI / 180.0F);
+        matrix[2] = (float)sin(angle * (float)PI / 180.0F);
     } else {
         matrix[0] = 1.0F;
         matrix[2] = 0.0F;
@@ -2787,8 +2787,8 @@
                 float x, y;
                 rotated_coords(&x, &y, matrix, cx, cy,
                                boxr * points[i], boxr * points[i+1]);
-                points[i] = x + 0.5;
-                points[i+1] = y + 0.5;
+                points[i] = x + 0.5F;
+                points[i+1] = y + 0.5F;
             }
 
             draw_polygon(dr, points, 4, col, COL_WIRE);
--- a/netslide.c
+++ b/netslide.c
@@ -1492,7 +1492,7 @@
         vx = (dy ? 1 : 0);
         vy = (dx ? 1 : 0);
 
-        if (xshift == 0.0 && yshift == 0.0 && (tile & dir)) {
+        if (xshift == 0.0F && yshift == 0.0F && (tile & dir)) {
             /*
              * If we are fully connected to the other tile, we must
              * draw right across the tile border. (We can use our
@@ -1696,7 +1696,7 @@
     /*
      * Draw any tile which differs from the way it was last drawn.
      */
-    if (xshift != 0.0 || yshift != 0.0) {
+    if (xshift != 0.0F || yshift != 0.0F) {
         active = compute_active(state,
                                 state->last_move_row, state->last_move_col);
     } else {
--- a/samegame.c
+++ b/samegame.c
@@ -1554,7 +1554,7 @@
 	ds->started = true;
     }
 
-    if (flashtime > 0.0) {
+    if (flashtime > 0.0F) {
 	int frame = (int)(flashtime / FLASH_FRAME);
 	bgcolour = (frame % 2 ? COL_LOWLIGHT : COL_HIGHLIGHT);
     } else
--- a/twiddle.c
+++ b/twiddle.c
@@ -884,8 +884,8 @@
 	xf2 = rot->c * xf + rot->s * yf;
 	yf2 = - rot->s * xf + rot->c * yf;
 
-	xy[0] = (int)(xf2 + rot->ox + 0.5);   /* round to nearest */
-	xy[1] = (int)(yf2 + rot->oy + 0.5);   /* round to nearest */
+	xy[0] = (int)(xf2 + rot->ox + 0.5F);   /* round to nearest */
+	xy[1] = (int)(yf2 + rot->oy + 0.5F);   /* round to nearest */
     }
 }
 
@@ -1072,7 +1072,7 @@
 	COL_LOWLIGHT,
     };
 
-    return colours[(int)((angle + 2*PI) / (PI/16)) & 31];
+    return colours[(int)((angle + 2*(float)PI) / ((float)PI/16)) & 31];
 }
 
 static float game_anim_length_real(const game_state *oldstate,
@@ -1196,7 +1196,7 @@
 	rot->cw = rot->ch = TILE_SIZE * state->n;
 	rot->ox = rot->cx + rot->cw/2;
 	rot->oy = rot->cy + rot->ch/2;
-	angle = (float)((-PI/2 * lastr) * (1.0 - animtime / anim_max));
+	angle = ((-(float)PI/2 * lastr) * (1.0F - animtime / anim_max));
 	rot->c = (float)cos(angle);
 	rot->s = (float)sin(angle);
 
--- a/undead.c
+++ b/undead.c
@@ -1031,7 +1031,7 @@
         /* Monsters / Mirrors ratio should be balanced */
         ratio = (float)new->common->num_total /
             (float)(new->common->params.w * new->common->params.h);
-        if (ratio < 0.48 || ratio > 0.78) {
+        if (ratio < 0.48F || ratio > 0.78F) {
             free_game(new);
             continue;
         }