From d5c761515bd26f1f2a6b0f91e2b6f6762431566c Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Wed, 30 Dec 2015 04:49:43 -0500 Subject: Visible damage --- DAMAGED.DAT | Bin 0 -> 49 bytes characters | 36 ++++++++- convfont.c | 41 ++++++++++- draw_lorcha.s | 233 ++++++++++++++++++++++++++++++++++++++++++++-------------- lorchatest.c | 51 ++++++------- rand.s | 10 ++- taipan.c | 72 +++++++++--------- 7 files changed, 314 insertions(+), 129 deletions(-) create mode 100644 DAMAGED.DAT diff --git a/DAMAGED.DAT b/DAMAGED.DAT new file mode 100644 index 0000000..56673c0 Binary files /dev/null and b/DAMAGED.DAT differ diff --git a/characters b/characters index 19f3ced..9525010 100644 --- a/characters +++ b/characters @@ -37,9 +37,9 @@ Q, 47, f0 e0 c0 c0 c0 c0 80 80, 0x07 as screen data: -80 02 03 04 00 06 -80 1b 80 1c 1d 1e -80 1b 80 1c 1d 20 +00 02 03 04 00 06 +00 1b 80 1c 1d 1e +00 1b 80 1c 1d 20 3b 3c 3d 3e 3f 46 40 80 80 80 80 47 @@ -53,3 +53,33 @@ and its upper-right gets replaced with a custom char. The left sail can lose either of its F characters and have them replaced with a piece with a bite taken out of it. +damaged ship: + + 012345 + ______ +0 |.ABC.D +1 |.EXFGH +2 |.EXFGI +3 |JKLMNO +4 |PXXXXQ + +A, 50, 00 00 00 00 00 00 47 3e +B, 5b, 18 1f 1d 10 10 10 fb fd +C, 00 (space) +D, 00 (space) +E, 5e, 1f 0f 1f 3f 1f 3b ff 7f +F, 94 (inverse ball) +G, 5f, 00 01 03 07 03 03 07 06 +H, 60, f0 f8 fb fe fe f8 fe 7f +I, 7b, fe f8 be 97 8e be fc f8 +J, 7d, 00 00 03 1d 1f 37 3b 1f +K, 7e, 00 00 00 00 80 c1 e3 e3 +L, 7c, vertical bar +M, 7e, +N, 7e, +O, 7f, c0 c0 f0 e0 20 32 3c f1 +P, 46 (doesn't show damage) +Q, 47 (doesn't show damage) +The 4 X's across the bottom are the +upper left and lower right 1/4 blocks, 4c 49 4c 49 + diff --git a/convfont.c b/convfont.c index a2a2418..39c7a97 100644 --- a/convfont.c +++ b/convfont.c @@ -35,6 +35,7 @@ /* custom characters for ship graphics. 1st byte is screencode, the other 8 are the pixel data. */ char shipdata[][9] = { + /* healthy ship blocks */ {0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3f}, {0x03 , 0x18, 0x1f, 0x1f, 0x10, 0x10, 0x10, 0xff, 0xff}, {0x04 , 0x00, 0xf0, 0xfc, 0x3e, 0x00, 0x00, 0xfc, 0xf0}, @@ -52,6 +53,30 @@ char shipdata[][9] = { {0x40 , 0xc3, 0xcf, 0xff, 0xff, 0x3f, 0x3e, 0x3c, 0xf8}, {0x46 , 0x1f, 0x0f, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03}, {0x47 , 0xf0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80}, + + /* +A, 50, 00 00 00 00 00 00 47 3e +B, 5b, 18 1f 1d 10 10 10 fb fd +E, 5e, 1f 0f 1f 3f 1f 3b ff 7f +G, 5f, 00 01 03 07 03 03 07 06 +H, 60, f0 f8 fb fe fe f8 fe 7f +I, 7b, fe f8 be 97 8e be fc f8 +J, 7d, 00 00 03 1d 1f 37 3b 1f +K, 7e, 00 00 00 00 80 c1 e3 e3 +O, 7f, c0 c0 f0 e0 20 32 3c f1 +*/ + /* damaged ship blocks */ + { 0x50 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x3e}, + { 0x5b , 0x18, 0x1f, 0x1d, 0x10, 0x10, 0x10, 0xfb, 0xfd}, + { 0x5e , 0x1f, 0x0f, 0x1f, 0x3f, 0x1f, 0x3b, 0xff, 0x7f}, + { 0x5f , 0x00, 0x01, 0x03, 0x07, 0x03, 0x03, 0x07, 0x06}, + { 0x60 , 0xf0, 0xf8, 0xfb, 0xfe, 0xfe, 0xf8, 0xfe, 0x7f}, + { 0x7b , 0xfe, 0xf8, 0xbe, 0x97, 0x8e, 0xbe, 0xfc, 0xf8}, + { 0x7d , 0x00, 0x00, 0x03, 0x1d, 0x1f, 0x37, 0x3b, 0x1f}, + { 0x7e , 0x00, 0x00, 0x00, 0x00, 0x80, 0xc1, 0xe3, 0xe3}, + { 0x7f , 0xc0, 0xc0, 0xf0, 0xe0, 0x20, 0x32, 0x3c, 0xf1}, + + /* end of ship data marker */ { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; @@ -66,6 +91,16 @@ char shipshape[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +char damaged_shipshape[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x50, 0x5b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5e, 0xd4, 0x00, 0x5f, 0x1e, + 0x00, 0x00, 0x5e, 0xd4, 0x00, 0x5f, 0x60, + 0x00, 0x7d, 0x7e, 0x7c, 0x7e, 0x7e, 0x7f, + 0x00, 0x46, 0xcc, 0xc9, 0xcc, 0xc9, 0x47, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + void bitswap(unsigned char *b, int lim) { unsigned char j, k; // fprintf(stderr, "bitswap(%x, %d)\n", b, lim); @@ -138,9 +173,13 @@ int main(int argc, char **argv) { } write(1, font, 1024); - i = open("LORCHA.DAT", O_WRONLY | O_CREAT); + i = open("LORCHA.DAT", O_WRONLY | O_CREAT, 0666); write(i, shipshape, sizeof(shipshape)); close(i); + i = open("DAMAGED.DAT", O_WRONLY | O_CREAT, 0666); + write(i, damaged_shipshape, sizeof(damaged_shipshape)); + close(i); + return 0; } diff --git a/draw_lorcha.s b/draw_lorcha.s index 0f1a376..2abd196 100644 --- a/draw_lorcha.s +++ b/draw_lorcha.s @@ -1,6 +1,9 @@ +; Atari Taipan routines for rendering enemy lorchas. - .export _draw_lorcha - .import popax +; Lorcha (boat), a type of sailing vessel having a Chinese +; junk rig on a Portuguese or European style hull. + + .export _draw_lorcha, _sink_lorcha, _damage_lorcha, _clear_lorcha, _flash_lorcha ; TODO: maybe replace position tables with mul40? see ; libsrc/atari/mul40.s, which is getting linked anyway @@ -18,83 +21,203 @@ lorcha_pos_hi: SAVMSC = $58 ; ZP working variables start at $d4, aka FR0 (floating point reg 0). - mask = $d4 - displacement = $d5 + temp = $d4 + andmask = temp + flashing = temp+1 destptr = $d6 + lcount = $d8 + which = $d9 -; Lorcha (boat), a type of sailing vessel having a Chinese -; junk rig on a Portuguese or European style hull. ; Our lorcha is a 7x7 block of ATASCII characters. We're storing ; directly to screen RAM, so we use 'internal' codes. -; To edit the graphics, load up LORCHA.LST in atari800, with the H: -; device enabled, writable, set to current directory. Then edit the -; quoted strings in lines 10-70, and RUN the program. It will -; generate a new LORCHA.DAT, which must be 49 bytes long (so don't -; change the lengths of the strings in the BASIC code!) +; To edit the graphics, see shipshape[] in convfont.c. lorcha_data: .incbin "LORCHA.DAT" -; void __fastcall__ draw_lorcha(int which, int displacement, int mask); +; fully-damaged version of the lorcha, damaged_shipshape[] in convfont.c +damaged_data: + .incbin "DAMAGED.DAT" + +; void __fastcall__ flash_lorcha(int which); +_flash_lorcha: + ldx #$80 + stx flashing + bne drawit + +; void __fastcall__ clear_lorcha(int which); +_clear_lorcha: + ldx #0 + stx andmask + stx flashing + beq drawit + +; void __fastcall__ draw_lorcha(int which); _draw_lorcha: - sta mask ; stash mask (0 = normal, $80 = inverse) - jsr popax ; get displacement (0 = whole ship, 1..6 = sinking, 7 = blank) - sta displacement - jsr popax ; which ship position? + ldx #$ff + stx andmask + ldx #0 + stx flashing + +; the above 3 entry points set up flashing and/or andmask, +; then branch to the common routine here. +; flashing = 1: invert all the character codes (ignore andmask). turns +; ship inverse, or back to normal, using the data that's +; already in screen RAM (meaning, damage is preserved). +; flashing = 0: copy lorcha_data to destptr, ANDing with andmask: +; andmask = 0: clear lorcha +; andmask = $ff: draw lorcha + +drawit: tax + jsr setup_destptr + ldx #0 +line: + ldy #0 +char: + bit flashing + bpl noflash + lda (destptr),y + eor #$80 + clc + bcc storeit +noflash: + lda lorcha_data,x + and andmask +storeit: + sta (destptr),y + inx + iny + cpy #7 + bne char + jsr bump_destptr + cpx #49 + bne line + rts -; setup pointer to screen offset of upper left of ship - lda lorcha_pos_lo,x +; sinking the lorcha means copying each line of screen RAM +; from the one above it. has to be done in reverse order. +_sink_lorcha: + sta which + lda #6 + sta lcount + +sinkloop: + ldx which + jsr setup_destptr clc - adc SAVMSC + lda destptr + adc #200 ; 40 bytes/line * 5 lines sta destptr - lda lorcha_pos_hi,x - clc - adc SAVMSC+1 + lda destptr+1 + adc #0 sta destptr+1 - ; first, draw any blank lines - ldx displacement ; are there any? - beq shiplineloop ; no, draw ship -blanklineloop: - lda #0 ; screen code for space - ;ora mask ; apply mask ; don't need this here - ldy #6 ; ship is 7 columns wide (we count 6 to -1) -blankcolloop: - sta (destptr),y + ldx #6 ; line loop counter + ; delay for several jiffies + sei + lda #0 + sta 541 + lda #7 + sta 540 + cli +sdelay: + lda 541 + ora 540 + bne sdelay + + + ; at start of loop, destptr points to last line, and temp + ; is unitialized. +slineloop: + + ; temp=destptr; destptr-=40; + lda destptr + sta temp + sec + sbc #40 + sta destptr + lda destptr+1 + sta temp+1 + sbc #0 + sta destptr+1 + + ; now loop over 7 bytes + ldy #6 +sbyteloop: + lda (destptr),y + sta (temp),y dey - bpl blankcolloop - jsr bump_pointer ; add 40 (1 line) to dest pointer. + bpl sbyteloop dex - bne blanklineloop + bpl slineloop + dec lcount + bpl sinkloop - ; X is now 0, however we got here. -shiplineloop: - lda displacement - cmp #7 - beq done - ldy #0 -shipcolloop: - lda lorcha_data,x - eor mask - sta (destptr),y - iny - inx - cpy #7 - bne shipcolloop - jsr bump_pointer - inc displacement + rts ; end of _sink_lorcha +;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +_damage_lorcha: + tax + jsr setup_destptr + +xrand: + ; get random number 0-48 in X: + lda 53770 ; RANDOM + lsr + lsr + cmp #49 + bcs xrand + tax + +getpiece: + lda damaged_data,x + cmp lorcha_data,x + beq xrand ; if it's a piece that can't show damage, + ; ditch it and start over + sta temp ; stash the piece + + ; which row/col? call bump_destptr (x/7)-1 times. + txa +calcrow: + sec + sta temp+1 ; this holds the modulus (x%7) + sbc #7 + bcc rowdone + pha + jsr bump_destptr + pla clc - bcc shiplineloop + bcc calcrow -done: - rts +rowdone: + lda temp ; the piece + ldy temp+1 + sta (destptr),y + + rts ; end of _damage_lorcha + +; a couple of utility functions for dealing with destptr: -bump_pointer: +; add 40 to destptr. trashes A, preserves X/Y. +bump_destptr: lda destptr clc adc #40 sta destptr lda destptr+1 adc #0 - sta 215 + sta destptr+1 + rts + +; sets up destptr to point to correct position for the given +; ship number (0-9) in X reg. trashes A, preserves X/Y. +setup_destptr: + lda lorcha_pos_lo,x + clc + adc SAVMSC + sta destptr + lda lorcha_pos_hi,x + clc + adc SAVMSC+1 + sta destptr+1 rts diff --git a/lorchatest.c b/lorchatest.c index bc53d07..31d7f81 100644 --- a/lorchatest.c +++ b/lorchatest.c @@ -1,37 +1,32 @@ +#include #include -extern void __fastcall__ draw_lorcha(int which, int displacement, int mask); - -void jsleep(int jiffies) { - POKE(20,0); - while(PEEK(20) < jiffies) - ; -} +extern void __fastcall__ damage_lorcha(int which); +extern void __fastcall__ draw_lorcha(int which); +extern void __fastcall__ flash_lorcha(int which); +extern void __fastcall__ clear_lorcha(int which); +extern void __fastcall__ sink_lorcha(int which); int main(void) { int i, j; - - /* draw all 10 ships in normal state */ + POKE(756, 0xb8); for(i=0; i<10; i++) { - draw_lorcha(i, 0, 0); - } - - /* explode and sink all 10 ships */ - for(i=0; i<10; i++) { - /* blast effect */ - for(j=0; j<8; j++) { - draw_lorcha(i, 0, 0x80); - jsleep(2); - draw_lorcha(i, 0, 0); - jsleep(2); - } - - /* sinking */ - for(j=0; j<8; j++) { - draw_lorcha(i, j, 0); - jsleep(4); + // draw_lorcha(i); + // cgetc(); + // clear_lorcha(i); + // cgetc(); + draw_lorcha(i); + cgetc(); + sink_lorcha(i); + cgetc(); + draw_lorcha(i); + for(j=0; j<5; j++) { + cgetc(); + flash_lorcha(i); + cgetc(); + flash_lorcha(i); + cgetc(); + damage_lorcha(i); } } - -hang: goto hang; } diff --git a/rand.s b/rand.s index c48478e..3d64c74 100644 --- a/rand.s +++ b/rand.s @@ -5,10 +5,14 @@ RANDOM = 53770 ; POKEY LFSR read address, defined in the Atari OS ; void __fastcall__ randi(void); +; NB cc65's rand() returns a positive signed int, meaning +; 0 to 0x7fff. _randi: - lda #0 - sta sreg - beq randl1 + lda RANDOM + and #$7f + tax + lda RANDOM + rts ; void __fastcall__ randl(void); _randl: diff --git a/taipan.c b/taipan.c index b53ac1c..40cfb5d 100644 --- a/taipan.c +++ b/taipan.c @@ -8,7 +8,7 @@ /* define this for testing sea_battle(). it causes a pirate attack every time you leave port. Don't leave defined for a release!! */ -// #define COMBAT_TEST +#define COMBAT_TEST /**** atari-specific stuff */ @@ -126,10 +126,11 @@ void quit(void); void overload(void); void fancy_numbers(unsigned long num, char *fancy); int sea_battle(int id, int num_ships); -extern void __fastcall__ draw_lorcha(int which, int displacement, int mask); -void clear_lorcha(int x, int y); -void draw_blast(int x, int y); -void sink_lorcha(int which); +extern void __fastcall__ draw_lorcha(int which); +extern void __fastcall__ flash_lorcha(int which); +extern void __fastcall__ damage_lorcha(int which); +extern void __fastcall__ sink_lorcha(int which); +extern void __fastcall__ clear_lorcha(int which); void fight_stats(int ships, int orders); void mchenry(void); void retire(void); @@ -482,14 +483,6 @@ void fight_stats(int ships, int orders) return; } -void sink_lorcha(int which) { - int i; - for(i = 1; i < 8; i++) { - draw_lorcha(which, i, 0); - jsleep(5); - } -} - /* print an inverse video plus if there are offscreen ships, or clear it to a space if not. */ void plus_or_space(unsigned char b) { @@ -550,7 +543,7 @@ int sea_battle(int id, int num_ships) { if (ships_on_screen[i] == 0) { jsleep(5); ships_on_screen[i] = (randi() % ec) + 20; - draw_lorcha(i, 0, 0); + draw_lorcha(i); num_on_screen++; } } @@ -560,7 +553,7 @@ int sea_battle(int id, int num_ships) { gotoxy(0, 16); cputs("\r\n"); - timed_getch(TMOUT_3S); + input = timed_getch(TMOUT_3S); if(input == 'f') { orders = 1; @@ -571,7 +564,7 @@ int sea_battle(int id, int num_ships) { } if(orders == 0) { - timed_getch(TMOUT_3S); + input = timed_getch(TMOUT_3S); if (input == 'f') { @@ -635,7 +628,7 @@ int sea_battle(int id, int num_ships) { if (num_ships > num_on_screen) { if(ships_on_screen[j] == 0) { ships_on_screen[j] = randclamp(ec) + 20; - draw_lorcha(j, 0, 0); + draw_lorcha(j); num_on_screen++; } } @@ -653,17 +646,21 @@ int sea_battle(int id, int num_ships) { targeted = randi()%10; } - draw_lorcha(targeted, 0, 0x80); - jsleep(5); - - draw_lorcha(targeted, 0, 0); - jsleep(5); - - draw_lorcha(targeted, 0, 0x80); - jsleep(5); - - draw_lorcha(targeted, 0, 0); - jsleep(5); + /* flash_lorcha must be called an even number of times + to leave the lorcha in an unflashed state after. */ + flash_lorcha(targeted); + jsleep(2); + flash_lorcha(targeted); + jsleep(2); + flash_lorcha(targeted); + jsleep(2); + flash_lorcha(targeted); + jsleep(2); + flash_lorcha(targeted); + jsleep(2); + flash_lorcha(targeted); + jsleep(2); + damage_lorcha(targeted); ships_on_screen[targeted] -= randi()%30 + 10; @@ -676,12 +673,6 @@ int sea_battle(int id, int num_ships) { sink_lorcha(targeted); plus_or_space(num_ships > num_on_screen); - /* - if(num_ships == num_on_screen) { - gotoxy(39, 7); - cputc(' '); - } - */ fight_stats(num_ships, orders); } @@ -721,7 +712,7 @@ int sea_battle(int id, int num_ships) { ships_on_screen[i] = 0; num_on_screen--; - draw_lorcha(i, 7, 0); + clear_lorcha(i); jsleep(5); } } @@ -886,7 +877,7 @@ int sea_battle(int id, int num_ships) { ships_on_screen[i] = 0; num_on_screen--; - draw_lorcha(i, 7, 0); + clear_lorcha(i); jsleep(5); } } @@ -930,11 +921,13 @@ int sea_battle(int id, int num_ships) { } fight_stats(num_ships, orders); + /* XXX: I don't think this is needed at all! for(i = 0; i <= 9; i++) { if(ships_on_screen[i] > 0) { - draw_lorcha(i, 0, 0); + draw_lorcha(i); } } + */ plus_or_space(num_ships > num_on_screen); @@ -1270,8 +1263,8 @@ void splash_intro(void) { int i; - for(i=0; i<3; i++) draw_lorcha(i, 0, 0); - for(i=5; i<8; i++) draw_lorcha(i, 0, 0); + for(i=0; i<3; i++) draw_lorcha(i); + for(i=5; i<8; i++) draw_lorcha(i); timed_getch(TMOUT_5M); @@ -1726,6 +1719,7 @@ void quit(void) cputs(" I think we're going down!!\r\n\n"); timed_getch(TMOUT_3S); + // FIXME: the randclamp() version of this is broken badly! // if (((damage / capacity * 3) * ((float) randi() / RAND_MAX)) >= 1) if(randclamp(damage / capacity * 3) >= 1) { -- cgit v1.2.3