startrek: integerize
authorAlan Cox <alan@linux.intel.com>
Thu, 15 Mar 2018 19:44:30 +0000 (19:44 +0000)
committerAlan Cox <alan@linux.intel.com>
Thu, 15 Mar 2018 19:44:30 +0000 (19:44 +0000)
There are still some bugs notably the torp/base docking computer is wrong in
some cases.

Applications/games/startrek.c

index 0862c77..86b9ac3 100644 (file)
@@ -134,14 +134,13 @@ static void repair_damage(void);
 static void find_set_empty_place(uint8_t t);
 static const char *get_device_name(int n);
 static void quadrant_name(void);
-static int function_d(int i);
-static int cint(double d);
+static int distance_to(int i);
+static int square00(int16_t t);
 static int cint100(int16_t d);
 static void compute_vector(void);
 static void sub1(void);
 static void sub2(void);
 static void showfile(char *filename);
-static double rnd(void);
 
 /* Global Variables */
 
@@ -180,13 +179,13 @@ static uint16_t t9;                       /* End of time */
 static int z1, z2;                     /* Temporary Sector Coordinates */
 static int z4, z5;                     /* Temporary quadrant coordinates */
 
-static double a, c1;                   /* Used by Library Computer */
+static int16_t a, c1;                  /* Used by Library Computer */
 static int16_t d[9];                   /* Damage Array */
 static int16_t d4;                     /* Used for computing damage repair time */
-static double s1, s2;                  /* Current Sector Position of Enterprise */
+static int16_t s1, s2;                 /* Current Sector Position of Enterprise, fixed point */
 static uint16_t t;                     /* Current Stardate */
 static int16_t w1;                     /* Warp Factor */
-static double x, y, x1, x2;            /* Navigational coordinates */
+static int16_t x, y, x1, x2;           /* Navigational coordinates, fixed point */
 
 static char *sC;                       /* Condition */
 
@@ -249,14 +248,6 @@ static uint8_t yesno(void)
        return 0;
 }
 
-/* We'll turn this fixed point in time */
-static double input_dec(void)
-{
-       char x[8];
-       input(x, 8);
-       return atof(x);
-}
-
 /* Input a value between 0.00 and 9.99 */
 static int16_t input_f00(void)
 {
@@ -331,8 +322,6 @@ static uint8_t inoperable(uint8_t u)
 
 static void intro(void)
 {
-       /* FIXME: consider moving these into files and showfiling them */
-
        showfile("startrek.intro");
 
        if (yesno())
@@ -360,7 +349,6 @@ static void new_game(void)
 
        while (1) {
                if (s + e <= 10 && (e < 10 || d[7] < 0)) {
-                       /* Could be a showfile FIXME */
                        showfile("startrek.fatal");
                        end_of_time();
                }
@@ -425,8 +413,8 @@ static void initialize(void)
 
        q1 = rand8();
        q2 = rand8();
-       s1 = (double) rand8();
-       s2 = (double) rand8();
+       s1 = TO_FIXED00(rand8());
+       s2 = TO_FIXED00(rand8());
 
        for (i = 1; i <= 8; i++)
                d[i] = 0;
@@ -545,7 +533,7 @@ static void new_quadrant(void)
        memset(quad, Q_SPACE, 64);
 
        /* FIXME: do we need 0.5 shifts ? */
-       quad[(int)s1 - 1][(int)s2 - 1] = Q_SHIP;
+       quad[FROM_FIXED00(s1) - 1][FROM_FIXED00(s2) - 1] = Q_SHIP;
        
        if (k3 > 0) {
                for (i = 1; i <= k3; i++) {
@@ -573,17 +561,18 @@ static void course_control(void)
 {
        register int i;
        /* @@@ int c2, c3, q4, q5; */
-       double c1;
+       int16_t c1;
+       int c2, c3, c4;
        char sX[4] = "8";
 
        fputs("Course (0-9): ", stdout);
 
-       c1 = input_dec();
+       c1 = input_f00();
 
-       if (c1 == 9.0)
-               c1 = 1.0;
+       if (c1 == 900)
+               c1 = 100;
 
-       if (c1 < 0 || c1 > 9.0) {
+       if (c1 < 0 || c1 > 900) {
                printf("Lt. Sulu%s", inc_1);
                return;
        }
@@ -614,6 +603,7 @@ static void course_control(void)
 
        n = cint100(n); /* @@@ note: this is a real round in the original basic */
 
+       /* FIXME: should be  s + e - n > 0 iff shield control undamaged */
        if (e - n < 0) {
                printf("Engineering reports:\n"
                       "  Insufficient energy available for maneuvering"
@@ -632,11 +622,12 @@ static void course_control(void)
        repair_damage();
 
        /* @@@ z1 = cint(s1); */
-       z1 = (int) s1;
+       z1 = FROM_FIXED00(s1);
        /* @@@ z2 = cint(s2); */
-       z2 = (int) s2;
+       z2 = FROM_FIXED00(s2);
        quad[z1-1][z2-1] = Q_SPACE;
 
+#if 0
        /* @@@ c2 = cint(c1); */
        /* @@@ c3 = c2 + 1; */
 
@@ -645,6 +636,19 @@ static void course_control(void)
 
        x1 = c[1][(int) c1] + (c[1][(int) c1 + 1] - c[1][(int) c1]) * (c1 - (int) c1);
        x2 = c[2][(int) c1] + (c[2][(int) c1 + 1] - c[2][(int) c1]) * (c1 - (int) c1);
+#else
+
+       c2 = FROM_FIXED00(c1);  /* Integer part */
+//     printf("C2 = %d\n", c2);
+       c3 = c2 + 1;            /* Next integer part */
+       c4 = (c1 - TO_FIXED00(c2));     /* Fractional element in fixed point */
+
+       x1 = 100 * c[1][c2] + (c[1][c3] - c[1][c2]) * c4;
+       x2 = 100 * c[2][c2] + (c[2][c3] - c[2][c2]) * c4;
+
+//     printf("x1 = %d x2 = %d\n", x1, x2);
+
+#endif
 
        x = s1;
        y = s2;
@@ -659,9 +663,9 @@ static void course_control(void)
 //                     i, s1, s2, x1, x2);
 
                /* @@@ z1 = cint(s1); */
-               z1 = (int) s1;
+               z1 = FROM_FIXED00(s1);
                /* @@@ z2 = cint(s2); */
-               z2 = (int) s2;
+               z2 = FROM_FIXED00(s2);  /* ?? cint100 ?? */
 
                if (z1 < 1 || z1 >= 9 || z2 < 1 || z2 >= 9) {
                        exceed_quadrant_limits();
@@ -686,9 +690,9 @@ static void complete_maneuver(void)
        int t8;
 
        /* @@@ z1 = cint(s1); */
-       z1 = (int) s1;
+       z1 = FROM_FIXED00(s1);
        /* @@@ z2 = cint(s2); */
-       z2 = (int) s2;
+       z2 = FROM_FIXED00(s2);
        quad[z1-1][z2-1] = Q_SHIP;
 
        maneuver_energy();
@@ -712,30 +716,36 @@ static void exceed_quadrant_limits(void)
        int x5 = 0;             /* Outside galaxy flag */
 
        /* @@@ x = (8 * (q1 - 1)) + x + (n * x1); */
-       x = (8 * q1) + x + (n * x1);
+       x = (800 * q1) + x + (n * x1);
        /* @@@ y = (8 * (q2 - 1)) + y + (n * x2); */
-       y = (8 * q2) + y + (n * x2);
+       y = (800 * q2) + y + (n * x2);
+
+//     printf("X %d Y %d\n", x, y);
 
        /* @@@ q1 = cint(x / 8.0); */
-       q1 = (int) (x / 8.0);
+       q1 = x / 800;   /* Fixed point to int and divide by 8 */
        /* @@@ q2 = cint(y / 8.0); */
-       q2 = (int) (y / 8.0);
+       q2 = y / 800;   /* Ditto */
+
+//     printf("Q %d %d\n", q1, q2);
 
        /* @@@ s1 = x - ((q1 - 1) * 8); */
-       s1 = x - (q1 * 8);
+       s1 = x - (q1 * 800);
        /* @@@ s2 = y - ((q2 - 1) * 8); */
-       s2 = y - (q2 * 8);
+       s2 = y - (q2 * 800);
+
+//     printf("S %d %d\n", s1, s2);
 
        /* @@@ if (cint(s1) == 0) */
-       if ((int) s1 == 0) {
+       if (s1 < 100) {
                q1 = q1 - 1;
-               s1 = s1 + 8.0;
+               s1 = s1 + 800;
        }
 
        /* @@@ if (cint(s2) == 0) */
-       if ((int) s2 == 0) {
+       if (s2 < 100) {
                q2 = q2 - 1;
-               s2 = s2 + 8.0;
+               s2 = s2 + 800;
        }
 
        /* check if outside galaxy */
@@ -743,25 +753,25 @@ static void exceed_quadrant_limits(void)
        if (q1 < 1) {
                x5 = 1;
                q1 = 1;
-               s1 = 1.0;
+               s1 = 100;
        }
 
        if (q1 > 8) {
                x5 = 1;
                q1 = 8;
-               s1 = 8.0;
+               s1 = 800;
        }
 
        if (q2 < 1) {
                x5 = 1;
                q2 = 1;
-               s2 = 1.0;
+               s2 = 100;
        }
 
        if (q2 > 8) {
                x5 = 1;
                q2 = 8;
-               s2 = 8.0;
+               s2 = 800;
        }
 
        if (x5 == 1) {
@@ -773,7 +783,7 @@ static void exceed_quadrant_limits(void)
                       "Chief Engineer Scott reports:\n"
                       "  Warp Engines shut down at sector %d, "
                       "%d of quadrant %d, %d.\n\n",
-                      (int) s1, (int) s2, q1, q2);
+                      FROM_FIXED00(s1), FROM_FIXED00(s2), q1, q2);
        }
        /* else 
           new_quadrant(); @@@ this causes bugs when bouncing off galaxy walls.
@@ -847,9 +857,9 @@ static void short_range_scan(void)
        d0 = 0;
 
        /* @@@ for (i = s1 - 1; i <= s1 + 1; i++) */
-       for (i = (int) (s1 - 1); i <= (int) (s1 + 1); i++)
+       for (i = (int) (FROM_FIXED00(s1) - 1); i <= (int) (FROM_FIXED00(s1) + 1); i++)
                /* @@@ for (j = s2 - 1; j <= s2 + 1; j++) */
-               for (j = (int) (s2 - 1); j <= (int) (s2 + 1); j++)
+               for (j = (int) (FROM_FIXED00(s2) - 1); j <= (int) (FROM_FIXED00(s2) + 1); j++)
                        if (i >= 1 && i <= 8 && j >= 1 && j <= 8) {
                                /* This is dumb - we store the base co-ords! */
                                if (quad[i-1][j-1] == Q_BASE) {
@@ -880,7 +890,7 @@ static void short_range_scan(void)
                        printf("    Quadrant            %d, %d\n", q1, q2);
                if (i == 3)
                        /* @@@ printf("    Sector              %d, %d\n", cint(s1), cint(s2)); */
-                       printf("    Sector              %d, %d\n", (int) s1, (int) s2);
+                       printf("    Sector              %d, %d\n", FROM_FIXED00(s1), FROM_FIXED00(s2));
                if (i == 4)
                        printf("    Photon Torpedoes    %d\n", p);
                if (i == 5)
@@ -940,8 +950,9 @@ static void long_range_scan(void)
 static void phaser_control(void)
 {
        register int i;
-       int iEnergy;
-       int h1, h;
+       uint32_t iEnergy;
+       uint32_t h1;
+       int h;
 
        if (inoperable(4))
                return;
@@ -972,20 +983,37 @@ static void phaser_control(void)
 
        e = e - iEnergy;
 
+       /* We can fire up to nearly 3000 points of energy so we do this
+          bit in 32bit math */
+
        if (d[8] < 0)
                /* @@@ iEnergy = iEnergy * rnd(); */
-               iEnergy = (int) (iEnergy * rnd());
+               iEnergy = iEnergy * get_rand(100);
+       else
+               iEnergy *= 100;
 
        h1 = iEnergy / k3;
 
+//     printf("h1 = %d\n", h1);
+
        for (i = 1; i <= 3; i++) {
                if (k[i][3] > 0) {
-                       /* @@@ h = (h1 / function_d(0) * (rnd() + 2)); */
-                       h = (int) (h1 / function_d(0) * (rnd() + 2));
-                       if (h <= .15 * k[i][3]) {
+                       /* @@@ h = (h1 / distance_to(0) * (rnd() + 2)); */
+                       /* We are now 32bit with four digits accuracy */
+                       h = h1 * (get_rand(100) + 200);
+                       /* Takes us down to 2 digit accuracy */
+
+//                     printf("distance_to = %d\n", distance_to(i));
+
+                       h /= distance_to(i);
+
+//                     printf("damage base %d\n", h);
+
+                       if (h <= 15 * k[i][3]) {        /* was 0.15 */
                                printf("Sensors show no damage to enemy at "
                                       "%d, %d\n\n", k[i][1], k[i][2]);
                        } else {
+                               h = FROM_FIXED00(h);
                                k[i][3] = k[i][3] - h;
                                printf("%d unit hit on Klingon at sector "
                                       "%d, %d\n",
@@ -1016,7 +1044,8 @@ static void photon_torpedoes(void)
 {
        /* @@@ int c2, c3, x3, y3, x5; */
        int x3, y3;
-       double c1;
+       int16_t c1;
+       int c2, c3, c4;
 
        if (p <= 0) {
                puts("All photon torpedoes expended");
@@ -1028,13 +1057,13 @@ static void photon_torpedoes(void)
 
        fputs("Course (0-9): ", stdout);
 
-       c1 = input_dec();
+       c1 = input_f00();
 
-       if (c1 == 9.0)
-               c1 = 1.0;
+       if (c1 == 900)
+               c1 = 100;
 
        /* @@@ if (c1 < 0 || c1 > 9.0) */
-       if (c1 < 1.0 || c1 > 9.0) {
+       if (c1 < 100 || c1 > 900) {
                printf("Ensign Chekov%s", inc_1);
                return;
        }
@@ -1042,6 +1071,7 @@ static void photon_torpedoes(void)
        e = e - 2;
        p--;
 
+#if 0
        /* @@@ c2 = cint(c1); */
        /* @@@ c3 = c2 + 1; */
 
@@ -1050,12 +1080,24 @@ static void photon_torpedoes(void)
 
        x1 = c[1][(int) c1] + (c[1][(int) c1 + 1] - c[1][(int) c1]) * (c1 - (int) c1);
        x2 = c[2][(int) c1] + (c[2][(int) c1 + 1] - c[2][(int) c1]) * (c1 - (int) c1);
+#else
+
+       c2 = FROM_FIXED00(c1);  /* Integer part */
+       c3 = c2 + 1;            /* Next integer part */
+       c4 = (c1 - TO_FIXED00(c2));     /* Fractional element in fixed point */
+
+       x1 = 100 * c[1][c2] + (c[1][c3] - c[1][c2]) * c4;
+       x2 = 100 * c[2][c2] + (c[2][c3] - c[2][c2]) * c4;
+
+#endif
 
        x = s1 + x1;
        y = s2 + x2;
 
-       x3 = cint(x);           /* @@@ note: this is a true integer round in the MS BASIC version */
-       y3 = cint(y);           /* @@@ note: this is a true integer round in the MS BASIC version */
+       /* If the ship is not rounded this is wrong FIXME */
+
+       x3 = cint100(x);        /* @@@ note: this is a true integer round in the MS BASIC version */
+       y3 = cint100(y);        /* @@@ note: this is a true integer round in the MS BASIC version */
 
        puts("Torpedo Track:");
 
@@ -1076,8 +1118,8 @@ static void photon_torpedoes(void)
                x = x + x1;
                y = y + x2;
 
-               x3 = cint(x);   /* @@@ note: this is a true integer round in the MS BASIC version */
-               y3 = cint(y);   /* @@@ note: this is a true integer round in the MS BASIC version */
+               x3 = cint100(x);    /* @@@ note: this is a true integer round in the MS BASIC version */
+               y3 = cint100(y);    /* @@@ note: this is a true integer round in the MS BASIC version */
        }
 
        puts("Torpedo Missed\n");
@@ -1089,8 +1131,8 @@ static void torpedo_hit(void)
 {
        int i, x3, y3;
 
-       x3 = cint(x);           /* @@@ note: this is a true integer round in the MS BASIC version */
-       y3 = cint(y);           /* @@@ note: this is a true integer round in the MS BASIC version */
+       x3 = cint100(x);        /* @@@ note: this is a true integer round in the MS BASIC version */
+       y3 = cint100(y);        /* @@@ note: this is a true integer round in the MS BASIC version */
 
        switch(quad[x3-1][y3-1]) {
        case Q_STAR:
@@ -1171,6 +1213,7 @@ static void damage_control(void)
                                   avoid that round below FIXME */
                                t = t + (d3 + 5)/10 + 1;
                        }
+                       return;
                }
        }
 
@@ -1301,12 +1344,6 @@ static void status_report(void)
               "Mission must be completed in %d.%d stardates\n",
                plural, k9,
                FROM_FIXED(left), left%10);
-#if 0          
-              /* @@@ .1 * cint((t0 + t9 - t) * 10)); */
-              /* Force long to avoid overflows: FIXME clean this all up
-                 into fixed point forms */
-              .1 * (int) ((t0 + t9 - FROM_FIXED(t)) * 10L));
-#endif        
 
        if (b9 < 1) {
                puts("Your stupidity has left you on your own in the galaxy\n"
@@ -1338,8 +1375,8 @@ static void torpedo_data(void)
 
        for (i = 1; i <= 3; i++) {
                if (k[i][3] > 0) {
-                       w1 = k[i][1];
-                       x = k[i][2];
+                       w1 = TO_FIXED00(k[i][1]);
+                       x = TO_FIXED00(k[i][2]);
                        c1 = s1;
                        a = s2;
 
@@ -1356,14 +1393,15 @@ static void nav_data(void)
                return;
        }
 
-       w1 = b4;
-       x = b5;
+       w1 = TO_FIXED00(b4);
+       x = TO_FIXED00(b5);
        c1 = s1;
        a = s2;
 
        compute_vector();
 }
 
+/* Q: do we want to support fractional co-ords ? */
 static void dirdist_calc(void)
 {
        printf("Direction/Distance Calculator\n"
@@ -1371,25 +1409,25 @@ static void dirdist_calc(void)
               "Please enter initial X coordinate: ",
               q1, q2,
               /* @@@ cint(s1), cint(s2)); */
-              (int) s1, (int) s2);
+              FROM_FIXED00(s1), FROM_FIXED00(s2));
 
-       c1 = input_int();
-       if (c1 < 0)
+       c1 = TO_FIXED00(input_int());
+       if (c1 < 0 || c1 > 900 )
                return;
 
        fputs("Please enter initial Y coordinate: ", stdout);
-       a = input_int();
-       if (a < 0)
+       a = TO_FIXED00(input_int());
+       if (a < 0 || a > 900)
                return;
 
        fputs("Please enter final X coordinate: ", stdout);
-       w1 = input_int();
-       if (w1 < 0)
+       w1 = TO_FIXED00(input_int());
+       if (w1 < 0 || w1 > 900)
                return;
 
        fputs("Please enter final Y coordinate: ", stdout);
-       x = input_int();
-       if (x < 0)
+       x = TO_FIXED00(input_int());
+       if (x < 0 || x > 900)
                return;
        compute_vector();
 }
@@ -1442,63 +1480,65 @@ static void galaxy_map(void)
 
 static void compute_vector(void)
 {
+       /* All this is happening in fixed point */
        x = x - a;
-       /* FIXME: until we finish the job */
-       a = c1 - (double)w1;
+       a = c1 - w1;
 
-       if (x <= 0.0) {
-               if (a > 0.0) {
-                       c1 = 3.0;
+       if (x <= 0) {
+               if (a > 0) {
+                       c1 = 300;
                        sub2();
                        return;
                } else {
-                       c1 = 5.0;
+                       c1 = 500;
                        sub1();
                        return;
                }
-       } else if (a < 0.0) {
-               c1 = 7.0;
+       } else if (a < 0) {
+               c1 = 700;
                sub2();
                return;
        } else {
-               c1 = 1.0;
+               c1 = 100;
                sub1();
                return;
        }
 }
 
 static const char *dir_1 = "  DIRECTION = ";
-static const char *dist_1 = "  DISTANCE = %4.2f\n\n";
-static const char *f42 = "%4.2f\n";
+static const char *dist_1 = "  DISTANCE = %s\n\n";
 
 static void sub1(void)
 {
-       x = fabs(x);
-       a = fabs(a);
+       uint32_t xl = abs(x);
+       uint32_t al = abs(a);
 
        fputs(dir_1, stdout);
-       if (a <= x)
-               printf(f42, c1 + (a / x));
+       /* Multiply the top half by 100 as well so that we keep it in fixed00
+          format. Our larget value is int 9 (900) so we must do this 32bit */
+       if (al <= xl)
+               printf("%s", print100(c1 + ((al * 100) / xl)));
        else
-               printf(f42, c1 + (((a * 2) - x) / a));
+               printf("%s", print100(c1 + ((((al * 2) - xl) * 100) / al)));
 
-       printf(dist_1, (x > a) ? x : a);
+       printf(dist_1, print100((xl > al) ? xl : al));
 }
 
 static void sub2(void)
 {
-       x = fabs(x);
-       a = fabs(a);
+       uint32_t xl = abs(x);
+       uint32_t al = abs(a);
 
        fputs(dir_1, stdout);
-       if (a >= x)
-               printf(f42, c1 + (x / a));
+       /* Multiply the top half by 100 to keep in fixed0 */
+       if (al >= xl)
+               printf("%s", print100(c1 + ((xl * 100) / al)));
        else
                /* @@@ printf("  DIRECTION = %4.2f\n\n", c1 + (((x * 2) - a) / x)); */
-               printf(f42, c1 + (((x * 2) - a) / x));
+               printf("%s", print100(c1 + ((((xl * 2) - al) * 100)  / x)));
 
        /* @@@ printf("  DISTANCE = %4.2f\n", (x > a) ? x : a); */
-       printf(dist_1, (x > a) ? x : a);
+       printf(dist_1, print100((x > a) ? x : a));
 }
 
 static void ship_destroyed(void)
@@ -1531,8 +1571,9 @@ static void won_game(void)
 
        /* FIXME: finish integerising this */
        if (FROM_FIXED(t) - t0 > 0)
-               printf("Your efficiency rating is %4.2f\n", 1000 * pow(k7 / (float)(FROM_FIXED(t) - t0), 2));
-
+               printf("Your efficiency rating is %s\n",
+                       print100(square00(TO_FIXED00(k7)/(FROM_FIXED(t) - t0))));
+               // 1000 * pow(k7 / (float)(FROM_FIXED(t) - t0), 2));
        end_of_game();
 }
 
@@ -1577,7 +1618,8 @@ static const char *dcr_1 = "Damage Control report:";
 
 static void klingons_shoot(void)
 {
-       int h, i;
+       uint32_t h;
+       uint8_t i;
 
        if (k3 <= 0)
                return;
@@ -1589,13 +1631,17 @@ static void klingons_shoot(void)
 
        for (i = 1; i <= 3; i++) {
                if (k[i][3] > 0) {
-                       h = (int) ((k[i][3] / function_d(i)) * (2 + rnd()));
-                       s = s - h;
+                       h = k[i][3] * (200 + get_rand(100));
+                       h *= 100;       /* Ready for division in fixed */
+                       h /= distance_to(i);
+                       /* Takes us back into FIXED00 */
+                       s = s - FROM_FIXED00(h);
                        /* @@@ k[i][3] = k[i][3] / (3 + rnd()); */
-                       k[i][3] = (int) (k[i][3] / (3 + rnd()));
+
+                       k[i][3] = (k[i][3] * 100) / (300 + get_rand(100));
 
                        printf("%d unit hit on Enterprise from sector "
-                              "%d, %d\n", h, k[i][1], k[i][2]);
+                              "%d, %d\n", FROM_FIXED00(h), k[i][1], k[i][2]);
 
                        if (s <= 0) {
                                putchar('\n');
@@ -1608,7 +1654,7 @@ static void klingons_shoot(void)
                                /* The check in basic is float and is h/s >.02. We
                                   have to use 32bit values here to avoid an overflow
                                   FIXME: use a better algorithm perhaps ? */
-                               uint32_t ratio = TO_FIXED00((uint32_t)h)/s;
+                               uint32_t ratio = ((uint32_t)h)/s;
                                if (get_rand(10) <= 6 || ratio > 2) {
                                        r1 = rand8();
                                        /* The original basic code computed h/s in
@@ -1654,7 +1700,7 @@ static void repair_damage(void)
        if (get_rand(10) <= 2) {
                r1 = rand8();
 
-               if (rnd() < .6) {
+               if (get_rand(10) < 6) {
                        /* Working in 1/100ths */
                        d[r1] = d[r1] - (get_rand(500) + 100);
                        //TO_FIXED00((rnd() * 5.0 + 1.0));
@@ -1725,12 +1771,56 @@ static void quadrant_name(void)
        return;
 }
 
-static int function_d(int i)
+/* An unsigned sqrt is all we need.
+
+   What we are actually doing here is a smart version of calculating n^2
+   repeatedly until we find the right one */
+static int16_t isqrt(int16_t i)
+{
+       uint16_t b = 0x4000, q = 0, r = i, t;
+//     printf("isqrt %d=", i);
+       while (b) {
+               t = q + b;
+               q >>= 1;
+               if (r >= t) {
+                       r -= t;
+                       q += b;
+               }
+               b >>= 2;
+       }
+//     printf("%d\n", q);
+       return q;
+}
+
+static int square00(int16_t t)
+{
+//     printf("square00 %d = ", t);
+       if (t > 181) {
+               t /= 10;
+               t *= t;
+       } else {
+               t *= t;
+               t /= 100;
+       }
+//     printf("%d\n", t);
+       return t;
+}
+
+/* Return the distance to an object in x.xx fixed point */
+static int distance_to(int i)
 {
        int j;
 
+       /* We do the squares in fixed point maths */
+       j = square00(TO_FIXED00(k[i][1]) - s1);
+       j += square00(TO_FIXED00(k[i][2]) - s2);
+
+       /* Find the integer square root */
+       j = isqrt(j);
+       /* Correct back into 0.00 fixed point */
+       j *= 10;
        /* @@@ j = sqrt(pow((k[i][1] - s1), 2) + pow((k[i][2] - s2), 2)); */
-       j = (int) sqrt(pow((k[i][1] - s1), 2) + pow((k[i][2] - s2), 2));
+//     j = (int) sqrt(pow((k[i][1] - s1), 2) + pow((k[i][2] - s2), 2));
 
        return j;
 }
@@ -1738,15 +1828,6 @@ static int function_d(int i)
 
 /* Round off floating point numbers instead of truncating */
 
-static int cint(double d)
-{
-       int i;
-
-       i = (int) (d + 0.5);
-
-       return (i);
-}
-
 static int cint100(int16_t d)
 {
        return (d + 50) / 100;
@@ -1773,11 +1854,3 @@ static void showfile(char *filename)
        fclose(fp);
 }
 
-static double rnd(void)
-{
-       double d;
-
-       d = rand() / (double) RAND_MAX;
-
-       return (d);
-}