From ddce52f2f6b09f6ada332c4061a3f55a490a886d Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Sat, 16 Jan 2016 19:23:57 -0500 Subject: cprintfancy_big() overhaul --- bignum.h | 11 ++++-- taipan.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 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(); -- cgit v1.2.3