aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bignum.h11
-rw-r--r--taipan.c118
2 files changed, 120 insertions, 9 deletions
diff --git a/bignum.h b/bignum.h
index 8794166..a79f60e 100644
--- a/bignum.h
+++ b/bignum.h
@@ -28,15 +28,22 @@
/* zero */
#define BIG_0 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
-/* constant initializer for 1.005 goes here */
+/* TODO: calculate bank interest differently: this bignum
+ implementation is floating point, but I might swap it out
+ for an int-based one! */
+/* 1.005 (bank interest) */
#define BIG_1_005 { 0x40, 0x01, 0x00, 0x50, 0x00, 0x00 }
/* bignum 100, used for score calculations in final_stats() */
#define BIG_100 { 0x41, 0x01, 0x00, 0x00, 0x00, 0x00 }
-/* one million, one hundred million, one billion, one trillion */
+/* one thousand, one million, one hundred million */
+#define BIG_1K { 0x41, 0x10, 0x00, 0x00, 0x00, 0x00 }
#define BIG_1M { 0x43, 0x01, 0x00, 0x00, 0x00, 0x00 }
#define BIG_100M { 0x44, 0x01, 0x00, 0x00, 0x00, 0x00 }
+
+/* 10 million, one billion, one trillion */
+#define BIG_10M { 0x43, 0x10, 0x00, 0x00, 0x00, 0x00 }
#define BIG_1B { 0x44, 0x10, 0x00, 0x00, 0x00, 0x00 }
#define BIG_1T { 0x46, 0x01, 0x00, 0x00, 0x00, 0x00 }
diff --git a/taipan.c b/taipan.c
index 4a0ebbd..3e3be6d 100644
--- a/taipan.c
+++ b/taipan.c
@@ -28,10 +28,6 @@
/* define this to show internals of damage calculation */
// #define DAMAGE_TEST
-/* define this to test the mchenry() routine by entering
- damage and capacity numbers directly */
-// #define MCHENRY_TEST
-
/* define this to start the game in the year 1869, with
1000 capacity, 20 guns, and 1 billion cash and bank. */
// #define TIMEWARP
@@ -39,6 +35,13 @@
/* define this to start the game in a 99% damaged ship */
// #define ALMOST_DEAD
+/* define this to test the mchenry() routine by entering
+ damage and capacity numbers directly */
+// #define MCHENRY_TEST
+
+/* define this to test the cprintfancy_big() routine */
+// #define BIGNUM_TEST
+
/**** atari-specific stuff */
/* values returned by cgetc() for backspace & enter keys */
@@ -305,10 +308,78 @@ unsigned char port = 1,
long damage = 0, capacity = 60, newdamage;
#ifdef BIGNUM
-bignum(big1M) = BIG_1M;
-bignum(big100M) = BIG_100M;
+bignum(big1T) = BIG_1T;
bignum(big1B) = BIG_1B;
+bignum(big1M) = BIG_1M;
+bignum(big1K) = BIG_1K;
bignum(big0) = BIG_0;
+// bignum(big100M) = BIG_100M;
+// bignum(big10M) = BIG_10M;
+
+/* what we should have:
+ For Million/Billion, 3 significant digits.
+ range printed as
+ 0..999999 stet
+ 1M..10M-1 1.23 Million
+ 10M..100M-1 10.2 Million, 100 Million
+ 100M..1B-1 100 Million, 999 Billion
+ 1B..10B-1 1.23 Billion
+ 10B..100B-1 10.2 Billion, 100 Billion
+ 100B..1T-1 100 Billion
+ 1T..inf 1 Trillion+!
+*/
+void cprintfancy_big(bignump b) {
+ bignum(tmp);
+ unsigned long leftdigits = 0L;
+ unsigned char rightdigits = 0, letter = 'M', leading0 = 0;
+
+ if(big_cmp(b, big1T) >= 0) {
+ revers(1);
+ cputs("1 Trillion+!");
+ revers(0);
+ return;
+ }
+
+ /* for >= 1B, divide by 1M */
+ if(big_cmp(b, big1B) >= 0) {
+ big_div(tmp, b, big1K);
+ letter = 'B';
+ } else {
+ big_copy(tmp, b);
+ }
+
+ big_to_ulong(tmp, &leftdigits);
+
+ if(big_cmp(b, big1M) < 0) { /* 0..999999 */
+ letter = 0;
+ } else if(leftdigits < 10000000L) { /* 1M..10M-1 */
+ leftdigits /= 10000L;
+ rightdigits = (unsigned char)(leftdigits % 100L);
+ leftdigits /= 100L;
+ if(rightdigits < 10) leading0 = 1;
+ } else if(leftdigits < 100000000L) { /* 10M..100M-1 */
+ leftdigits /= 100000L;
+ rightdigits = (unsigned char)(leftdigits % 10L);
+ leftdigits /= 10L;
+ } else {
+ leftdigits /= 1000000L;
+ }
+
+ cprintulong(leftdigits);
+ if(rightdigits) {
+ cputc('.');
+ if(leading0) cputc('0');
+ cprintulong((unsigned long)rightdigits);
+ }
+
+ if(letter) {
+ cputc(' ');
+ cputc(letter);
+ cputs("illion");
+ }
+
+ // cputs("\r\n"); // TODO: see if this can go away
+}
/*
Requires a bit of explanation. b's value will always be zero or
@@ -326,6 +397,7 @@ The calling code decides whether or not to print a decimal point
and 10ths digit (using integer math only).
*/
+#if 0
unsigned long cformat_big(char *magnitude, bignump b) {
bignum(tmp);
unsigned long ret;
@@ -365,6 +437,7 @@ void cprintfancy_big(bignump b) {
cputs("\r\n");
}
#endif
+#endif
int get_time(void) {
return ((year - 1860) * 12) + month;
@@ -1679,8 +1752,8 @@ void final_stats(void)
cprintfancy_big(bigscore);
#else
cprintulong(score);
- cputs(".\r\n");
#endif
+ cputs(".\r\n");
revers(0);
if ((score < 100) && (score >= 0))
{
@@ -2488,6 +2561,7 @@ int port_choices(void) {
char retire_ok = 0;
compradores_report();
+
cputs("Taipan, present prices per unit here are"); /* NB: exactly 40 cols */
cputs(" Opium: Silk:\r\n");
cputs(" Arms: General:\r\n");
@@ -2875,6 +2949,32 @@ void visit_bank(void)
return;
}
+#ifdef BIGNUM_TEST
+void bignum_test(void) {
+ int i;
+ bignum(n);
+ bignum(o);
+
+ ulong_to_big(1L, n);
+ ulong_to_big(11L, o);
+
+ for(i = 0; i < 14; i++) {
+ cprintfancy_big(n);
+ cputs("\r\n");
+ big_mul(n, n, o);
+ }
+ agetc();
+ ulong_to_big(1100000L, n);
+ cprintfancy_big(n);
+ ulong_to_big(1010000L, n);
+ cprintfancy_big(n);
+ ulong_to_big(1001000L, n);
+ cprintfancy_big(n);
+
+hangx: goto hangx;
+}
+#endif
+
/* N.B. cc65 is perfectly OK with main(void), and it avoids
warnings about argv/argc unused. */
int main(void) {
@@ -2896,6 +2996,10 @@ int main(void) {
atari_text_setup();
+#ifdef BIGNUM_TEST
+ bignum_test();
+#endif
+
initrand();
name_firm();
cash_or_guns();