1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
; Atari Taipan routines for rendering enemy lorchas.
; Lorcha (boat), a type of sailing vessel having a Chinese
; junk rig on a Portuguese or European style hull.
.include "atari.inc"
.import _jsleep
.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
; because conio uses it.
.rodata
; offset from start of screen for each ship position (0-9)
lorcha_pos_lo:
.byte <320, <328, <336, <344, <352
.byte <640, <648, <656, <664, <672
lorcha_pos_hi:
.byte >320, >328, >336, >344, >352
.byte >640, >648, >656, >664, >672
; ZP working variables start at $d4, aka FR0 (floating point reg 0).
temp = $d4
andmask = temp
flashing = temp+1
destptr = $d6
lcount = $d8
which = $d9
sinkdelay = $da
; clrtobot.s needs these:
.exportzp destptr
.export bump_destptr
; 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, see shipshape[] in convfont.c.
lorcha_data:
.incbin "LORCHA.DAT"
; fully-damaged version of the lorcha, damaged_shipshape[] in convfont.c
damaged_data:
.incbin "DAMAGED.DAT"
.ifdef CART_TARGET
.segment "HIGHCODE"
.else
.code
.endif
; 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:
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
; 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
; set sinkdelay to 3, 5, or 7 jiffies
@rnd:
lda RANDOM
eor RTCLOK+2
and #$06
beq @rnd
ora #1
sta sinkdelay
sinkloop:
ldx which
jsr setup_destptr
clc
lda destptr
adc #200 ; 40 bytes/line * 5 lines
sta destptr
lda destptr+1
adc #0
sta destptr+1
; delay for sinkdelay jiffies
ldx #0
lda sinkdelay
jsr _jsleep
ldx #6 ; line loop counter
; 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 sbyteloop
dex
bpl slineloop
dec lcount
bpl sinkloop
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 calcrow
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:
; add 40 to destptr. trashes A, preserves X/Y.
bump_destptr:
lda destptr
clc
adc #40
sta destptr
lda destptr+1
adc #0
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
|