aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <yalhcru@gmail.com>2015-12-30 04:49:43 -0500
committerB. Watson <yalhcru@gmail.com>2015-12-30 04:49:43 -0500
commitd5c761515bd26f1f2a6b0f91e2b6f6762431566c (patch)
tree2358efc0ce7bfa5c11956193ad67bdcc7468c623
parent2300d2813a524cbfeabac794335e7abe99263df6 (diff)
downloadtaipan-d5c761515bd26f1f2a6b0f91e2b6f6762431566c.tar.gz
Visible damage
-rw-r--r--DAMAGED.DATbin0 -> 49 bytes
-rw-r--r--characters36
-rw-r--r--convfont.c41
-rw-r--r--draw_lorcha.s233
-rw-r--r--lorchatest.c51
-rw-r--r--rand.s10
-rw-r--r--taipan.c72
7 files changed, 314 insertions, 129 deletions
diff --git a/DAMAGED.DAT b/DAMAGED.DAT
new file mode 100644
index 0000000..56673c0
--- /dev/null
+++ b/DAMAGED.DAT
Binary files 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 <conio.h>
#include <peekpoke.h>
-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)
{