aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <yalhcru@gmail.com>2021-05-10 16:47:37 -0400
committerB. Watson <yalhcru@gmail.com>2021-05-10 16:47:37 -0400
commit9d59ca053dbfddb34a2a4eac8ebb0252460c0137 (patch)
treed7bd40834b73b5b6115ff0293cf6c22145b88245
parent2ff01881f4b7f0842a10e3c5ab7991c81f60861d (diff)
downloadtaipan-9d59ca053dbfddb34a2a4eac8ebb0252460c0137.tar.gz
Rewrite array handling, save 175 bytes
-rw-r--r--arrayutils.s106
-rw-r--r--taipan.c43
2 files changed, 99 insertions, 50 deletions
diff --git a/arrayutils.s b/arrayutils.s
index 188ace4..4e3babf 100644
--- a/arrayutils.s
+++ b/arrayutils.s
@@ -14,47 +14,95 @@
; the function, or around 1/3 the size of the for loop, or under 1/4
; the size of bzero() plus its function call.
- .import _ships_on_screen
- .export _have_ships_on_screen, _clear_ships_on_screen
+; we also have clear_hkw() and clear_hold().
+
+ .import _ships_on_screen, _hkw_, _hold_
+ .export _no_ships_on_screen
+ .export _hold_is_empty, _hkw_is_empty, _have_no_cargo
+ .export _clear_hkw, _clear_hold, _clear_ships_on_screen
.include "atari.inc"
- .proc _clear_ships_on_screen
- ldx #$14
+ .code
+_clear_ships_on_screen:
+ lda #<(_ships_on_screen-1)
+ ldx #>(_ships_on_screen-1)
+ ldy #$14
+ ; fall thru
+
+clr_array:
+ ; AX is array address minus one!
+ ; Y is sizeof(array)
+ sta FR0
+ stx FR0+1
lda #0
@l:
- sta _ships_on_screen-1,x
- dex
+ sta (FR0),y
+ dey
bne @l
rts
- .endproc
-; extern char have_ships_on_screen(void);
+_clear_hkw:
+ lda #<(_hkw_-1)
+ ldx #>(_hkw_-1)
+ ldy #$08
+ bne clr_array
+
+_clear_hold:
+ lda #<(_hold_-1)
+ ldx #>(_hold_-1)
+ ldy #$10
+ bne clr_array
-; optimized (both size and speed) replacement for:
+;;;;;
-; if ((ships_on_screen[0] == 0) && (ships_on_screen[1] == 0) &&
-; (ships_on_screen[2] == 0) && (ships_on_screen[3] == 0) &&
-; (ships_on_screen[4] == 0) && (ships_on_screen[5] == 0) &&
-; (ships_on_screen[6] == 0) && (ships_on_screen[7] == 0) &&
-; (ships_on_screen[8] == 0) && (ships_on_screen[9] == 0))
+; Several places in the Taipan C code we have to check whether an
+; array is all zero. A for loop in C takes up quite a bit of space,
+; so write an array-checker in asm.
-; ...which compiles to ~100 bytes of code. a for loop would be
-; around 64 bytes (like the clearing loop above). this is 3 bytes
-; for the function call plus 11 bytes for the function, plus a
-; couple more bytes for the ! in front of the function call (since
-; the result is opposite what the original code did).
-; I could save the 3 bytes by inlining this as asm() in the C code,
-; but it would be more fragile than making a separate function.
+; Wrappers for array_is_empty():
+; no_ships_on_screen()
+; hold_is_empty()
+; hkw_is_empty()
+; have_no_cargo();
- .proc _have_ships_on_screen
- ldx #$14 ; sizeof(ships_on_screen)
+_no_ships_on_screen:
+ lda #<(_ships_on_screen-1)
+ ldx #>(_ships_on_screen-1)
+ ldy #$14
+ ; fall thru
+
+array_is_empty:
+ ; AX is array address minus one!
+ ; Y is sizeof(array)
+ sta FR0
+ stx FR0+1
@l:
- lda _ships_on_screen-1,x
- bne @done ; found a non-0 byte, A and X are both non-zero
- dex
+ lda (FR0),y
+ bne ret0
+ dey
bne @l
- ; end of loop. if we get here, A and X are both zero
-@done:
+@ret1:
+ lda #1
rts
- .endproc
+ret0:
+ lda #0
+ tax ; need this or not?
+ rts
+
+_hkw_is_empty:
+ lda #<(_hkw_-1)
+ ldx #>(_hkw_-1)
+ ldy #$08
+ bne array_is_empty
+
+_hold_is_empty:
+ lda #<(_hold_-1)
+ ldx #>(_hold_-1)
+ ldy #$10
+ bne array_is_empty
+
+_have_no_cargo:
+ jsr _hkw_is_empty
+ beq ret0
+ bne _hold_is_empty
diff --git a/taipan.c b/taipan.c
index 367c7be..8221cc1 100644
--- a/taipan.c
+++ b/taipan.c
@@ -378,6 +378,17 @@ unsigned long __fastcall__ strtonum(const char* nptr);
unsigned char firmpos;
+int ships_on_screen[10];
+
+/* arrayutils.s */
+extern char no_ships_on_screen(void);
+extern void clear_ships_on_screen(void);
+extern char have_no_cargo(void);
+extern char hold_is_empty(void);
+extern char hkw_is_empty(void);
+extern void clear_hold(void);
+extern void clear_hkw(void);
+
/* use page 6 for these buffers, for .xex build. Otherwise they're BSS. */
#ifdef CART_TARGET
char firm[23];
@@ -637,14 +648,8 @@ void init_game(void) {
#else
bank = 0;
#endif
- hkw_[0] = 0;
- hkw_[1] = 0;
- hkw_[3] = 0;
- hkw_[4] = 0;
- hold_[0] = 0;
- hold_[1] = 0;
- hold_[2] = 0;
- hold_[3] = 0;
+ clear_hkw();
+ clear_hold();
hold = 0;
damage = 0;
wu_warn = 0;
@@ -1091,12 +1096,6 @@ void plus_or_space(unsigned char b) {
#endif
*/
-int ships_on_screen[10];
-extern char have_ships_on_screen(void);
-extern void clear_ships_on_screen(void);
-
-char have_no_cargo(void);
-
/* sea_battle only ever returns 1 to 4. making the
return type a char saved 61 bytes! */
char sea_battle(char id, int num_ships) {
@@ -1212,7 +1211,7 @@ char sea_battle(char id, int num_ships) {
set_orders();
for(i = 1; i <= guns; i++) {
- if(!have_ships_on_screen()) {
+ if(no_ships_on_screen()) {
static int j;
for (j = 0; j <= 9; j++) {
@@ -1332,7 +1331,7 @@ char sea_battle(char id, int num_ships) {
total = 0;
turbo = 0;
- if(have_no_cargo()) {
+ if(hold_is_empty()) {
print_combat_msg(M_you_have_no_cargo);
cprint_taipan_bangbang();
bad_joss_sound();
@@ -1407,10 +1406,7 @@ char sea_battle(char id, int num_ships) {
hold += amount;
ok += (amount / 10);
} else {
- hold_[0] = 0;
- hold_[1] = 0;
- hold_[2] = 0;
- hold_[3] = 0;
+ clear_hold();
hold += total;
ok += (total / 10);
}
@@ -2179,12 +2175,15 @@ void final_stats(void)
#endif
}
+/*
+ // rewritten in asm (arrayutils.s)
char have_no_cargo(void) {
char i;
for(i = 0; i < 4; ++i)
if(hkw_[i] || hold_[i]) return 0;
return 1;
}
+*/
/*
#ifdef CART_TARGET
@@ -3550,9 +3549,11 @@ int main(void) {
under_attack_timed_getch();
}
+ /*
if ((one_chance_in(50)) &&
((hkw_[0] + hkw_[1] + hkw_[2] + hkw_[3]) > 0))
- {
+ */
+ if(one_chance_in(50) && !hkw_is_empty()) {
int i;
for (i = 0; i < 4; i++)