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 */
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 */
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)
{
static void intro(void)
{
- /* FIXME: consider moving these into files and showfiling them */
-
showfile("startrek.intro");
if (yesno())
while (1) {
if (s + e <= 10 && (e < 10 || d[7] < 0)) {
- /* Could be a showfile FIXME */
showfile("startrek.fatal");
end_of_time();
}
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;
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++) {
{
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;
}
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"
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; */
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;
// 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();
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();
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 */
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) {
"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.
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) {
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)
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;
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",
{
/* @@@ 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");
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;
}
e = e - 2;
p--;
+#if 0
/* @@@ c2 = cint(c1); */
/* @@@ c3 = c2 + 1; */
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:");
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");
{
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:
avoid that round below FIXME */
t = t + (d3 + 5)/10 + 1;
}
+ return;
}
}
"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"
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;
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"
"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();
}
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)
/* 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();
}
static void klingons_shoot(void)
{
- int h, i;
+ uint32_t h;
+ uint8_t i;
if (k3 <= 0)
return;
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');
/* 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
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));
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;
}
/* 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;
fclose(fp);
}
-static double rnd(void)
-{
- double d;
-
- d = rand() / (double) RAND_MAX;
-
- return (d);
-}