diff options
| -rw-r--r-- | bignum.h | 11 | ||||
| -rw-r--r-- | taipan.c | 118 | 
2 files changed, 120 insertions, 9 deletions
| @@ -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 } @@ -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(); | 
