forked from pkali/scorch_src
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrafproc.asm
1898 lines (1726 loc) · 41.2 KB
/
grafproc.asm
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
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
; @com.wudsn.ide.asm.mainsourcefile=scorch.asm
.IF *>0 ;this is a trick that prevents compiling this file alone
;--------------------------------------------------
.proc draw ;;fuxxing good draw :)
; xdraw,ydraw (word) - coordinates of first point
; xbyte,ybyte (word) - coordinates of last point
;--------------------------------------------------
;creditz to Dr Jankowski / MIM U.W.
; (xi,yi)-----(xk,yk)
;20 DX=XK-XI
;30 DY=YK-YI
;40 DP=2*DY
;50 DD=2*(DY-DX)
;60 DI=2*DY-DX
;70 REPEAT
;80 IF DI>=0
;90 DI=DI+DD
;100 YI=YI+1
;110 ELSE
;120 DI=DI+DP
;130 ENDIF
;140 plot XI,YI
;150 XI=XI+1
;160 UNTIL XI=XK
; begin: xdraw,ydraw - end: xbyte,ybyte
; let's store starting coordinates
; will be needed, because everything is calculated relatively
mwa #$ffff LineLength
mwa xdraw xtempDRAW
; It's a little crazy, but we don't have to check later to see if Y is out of screen
mva ydraw ytempDRAW
mva ydraw+1 ytempDRAW+1
bmi DrawOutOfTheScreen
; if line goes our of the screen we are not drawing it, but...
cpw xdraw #screenwidth
bcs DrawOutOfTheScreen
cpw xbyte #screenwidth
bcs DrawOutOfTheScreen
lda ybyte+1
bpl DrawOnTheScreen
DrawOutOfTheScreen
rts
DrawOnTheScreen
; constant parameters
; XI=0 ,YI=0
lda #0
sta XI
sta XI+1
sta YI
sta YI+1
sta HowToDraw ; reset flags
sta DrawDirFactor ; reset flags
; setting the direction controll bits
cpw ydraw ybyte
bcc LineDown
; here one line up
; we are subctracting Yend from Ybegin (reverse order)
; DY=YI-YK
sbw ydraw ybyte DY
; we are setting bit 7
lda #%10000000
sta HowToDraw ;here we can because it's first operation
bne CheckDirectionX ; JMP
LineDown
; one line down here
; we are clearing bit 7 (it's cleared :) )
; mva #0 HowToDraw ;here we can because it's first operation
; substract Ybegin from Yend (normal order)
; DY=YK-YI
sbw ybyte ydraw DY
CheckDirectionX
cpw xdraw xbyte
bcc LineRight
; here goes line to the left
; substract Xend from Xbegin (reverse)
; DX=XI-XK
sbw xdraw xbyte DX
; we set bit 6
lda HowToDraw
ora #%01000000
sta HowToDraw
bne CheckDirectionFactor ; JMP
LineRight
; here goes one line to the right
; we clear bit 6
; we can do nothing because the bit is cleared!
;lda HowToDraw
;and #%10111111
;sta HowToDraw
; substracting Xbegin from Xend (normal way)
; DX=XK-XI
sbw xbyte xdraw DX
CheckDirectionFactor
; here we check Direction Factor
; I do not know if we are using proper English word
; but the meaning is 'a' in y=ax+b
; lda DX
; we already have DX in A
cpw DX DY
bcs NoSwapXY
SwapXY
; not this half of a quarter! - parameters must be swapped
; XK=DY
; DY=DX
; DX=XK - because DY is there so DY and DX are swapped
; YK ... not used
mvy DY XK
mvx DY+1 XK+1
; now we have XK in Y and X for optimization
mwa DX DY
; DX=XK optimized (4 bytes saved!)
sty DX
stx DX+1
; and let's set bit 7 of DrawDirFactor
dec DrawDirFactor
; bmi LineParametersReady ; JMP - but we don't need JMP :)
NoSwapXY
; 'a' factor is fire, so we copy parameters
; XK=DX
mwa DX XK
; and clearing bit 7 of DrawDirFactor
; and bit 7 clear
; (is not needed because already cleared)
;lda #0
;sta DrawDirFactor
LineParametersReady
; let's check if length is not zero
lda DX
ora DX+1
ora DY
ora DY+1
bne NotOnePoint
; length=0
sta LineLength
sta LineLength+1
jmp EndOfDraw
NotOnePoint
; here we have DX,DY,XK and we know which operations
; are to be performed with these factors when doing PLOT
; (accordingly to given bits of 'HowToDraw')
; Now we must calculate DP, DD and DI
; DP=2*DY
; DD=2*(DY-DX)
; DI=2*DY-DX
mwa DY DP
aslw DP
sbw DY DX DD
aslw DD
mwa DY DI
aslw DI
sbw DI DX
DrawLoop
; REPEAT
; IF DI>=0
lda DI+1
bmi DINegative
; DI=DI+DD
; YI=YI+1
adw DI DD
inw YI
jmp drplot
DINegative
; ELSE
; DI=DI+DP
adw DI DP
drplot ; Our plot that checks how to calculate pixels.
; In xtempDRAW and ycircle there are begin coordinates
; of our line
; First we check the 'a' factor (like in y=ax+b)
; If necessary we swap XI and YI
; (as we can not change XI and YI we move XI to temp2
; and YI to temp)
bit DrawDirFactor
bmi SwappedXY
mwa XI temp
mwa YI temp2
jmp CheckPlotY
SwappedXY
mwa XI temp2
mwa YI temp
CheckPlotY
bit HowToDraw
bmi LineGoesUp
; here we know that line goes down and we are not changing Y
adw temp2 ytempDRAW ydraw ; YI
jmp CheckPlotX
LineGoesUp
; line goes up here - we are reversing Y
sbw ytempDRAW temp2 ydraw ; YI
CheckPlotX
bit HowToDraw
bvs LineGoesLeft
; here we know that line goes right and we are not changing X
adw temp xtempDRAW xdraw ; XI
jmp PutPixelinDraw
LineGoesLeft
; line goes left - we are reversing X
sbw xtempDRAW temp xdraw ; XI
PutPixelinDraw
; 0 - plot, %10000000 - LineLength (N), %01000000 - DrawCheck (V)
bit drawFunction
bpl @+
inw LineLength
bit Vdebug
bmi MeasureVisualisation
bpl ContinueDraw ; jmp
@
bvc @+
DrawCheck
lda tracerflag
ora SmokeTracerFlag
yestrace
beq notrace
jsr plot
notrace
;aftertrace
;key
lda HitFlag
bne StopHitChecking
CheckCollisionDraw
; checking collision!
lda ydraw+1
bmi StopHitChecking
jsr CheckCollisionWithTank
lda HitFlag
bne StopHitChecking
clc
lda xdraw
adc #<mountaintable
sta temp
lda xdraw+1
adc #>mountaintable
sta temp+1
ldy #0
lda ydraw
cmp (temp),y
bcc StopHitChecking
mwa xdraw XHit
lda (temp),y
sec
sbc #1
sta YHit
sty YHit+1
mva #$ff HitFlag
StopHitChecking
jmp ContinueDraw
@
MeasureVisualisation
jsr plot
ContinueDraw
; XI=XI+1
; UNTIL XI=XK
inw XI
cpw XI XK
jne DrawLoop
EndOfDraw
mwa xtempDRAW xdraw
mwa ytempDRAW ydraw
rts
.endp
; Circle is now in external file
icl 'circle2.asm'
;--------------------------------------------------
.proc placetanks
;--------------------------------------------------
ldx #(MaxPlayers-1) ;maxNumberOfPlayers-1
lda #0
@
; clearing the tables with coordinates of the tank
; it is necessary, because randomizing checks
; if the given tank is already placed
; after check if its position is not (0,0)
; I will be honest with you - I have no idea
; what the above comment was intending to mean :)
sta XtankstableL,x
sta XtankstableH,x
sta Ytankstable,x
dex
bpl @-
mwa #0 temptankX
sta temptankNr ;player number
StillRandomize
ldx NumberOfPlayers
lda random
and #$07
tay
cpy NumberOfPlayers
bcs StillRandomize
lda xtankstableL,y
bne StillRandomize
lda xtankstableH,y
bne StillRandomize
; here we know that we got a random number
; of the tank that is not in use
; this number is in Y
clc
lda temptankX
adc disktance,x
sta temptankX
sta xtankstableL,y
bcc NotHigherByte03
inc temptankX+1
NotHigherByte03
lda temptankX+1
sta xtankstableH,y
INC temptankNr
ldx temptankNr
Cpx NumberOfPlayers
bne StillRandomize
; getting random displacements relative to even positions
ldx #$00
StillRandomize02
lda random
and #$1f ; maximal displacement is 31 pixels
clc
adc xtankstableL,x
sta xtankstableL,x
bcc NotHigherByte02
inc xtankstableH,x
NotHigherByte02
; and we deduct 15 to make the displacement work two ways
sec
lda xtankstableL,x
sbc #$0f
; and clear lowest bit to be sure that the X coordinate is even
; (this is to have P/M background look nice)
; "AND" does not change "Carry" bit.
; x correction for P/M
; --
.IF XCORRECTION_FOR_PM = 1
and #$fe
.ENDIF
; --
sta xtankstableL,x
bcs NotHigherByte01
dec xtankstableH,x
NotHigherByte01
inx
Cpx NumberOfPlayers
bne StillRandomize02
rts
; during calculating heights of thw mountains
; check if the tank is not somewhere around
; if so, make horizontal line 8 pixels long
CheckTank
ldx NumberOfPlayers
dex
CheckNextTank
lda xtankstableL,x
cmp xdraw
bne UnequalTanks
lda xtankstableH,x
cmp xdraw+1
bne UnequalTanks
lda ydraw
;sec
;sbc #$01 ; minus 1, because it was 1 pixel too high
sta ytankstable,x ; what's the heck is that????!!!!
mva #7 deltaX
mwa #0 delta
UnequalTanks
dex
bpl CheckNextTank
rts
.endp
;-------------------------------------------------
.proc ClearTanks
jsr PMoutofScreen
lda #1 ; erase tanks flag
bne drawtanks.era
.endp
;-------------------------------------------------
.proc drawtanks
;-------------------------------------------------
lda #0 ; no erase tanks flag
era sta Erase
lda TankNr
pha
ldx NumberOfPlayers
dex
stx TankNr
DrawNextTank
jsr drawtanknr
dec TankNr
ldx TankNr
bpl DrawNextTank
pla
sta TankNr
rts
.endp
;---------
ClearTankNr
lda #1 ; erase tank flag
bne @er
PutTankNr
lda #0 ; no erase tank flag
@er sta Erase
.proc DrawTankNr
ldx tankNr
; let's check the energy
lda eXistenZ,x
bne SkipHidingPM ; if energy=0 then no tank
; hide P/M
lda TanksPMOrder,x
tax
lda #0
cpx #$4 ; 5th tank is defferent
bne No5thTankHide
sta hposp0+4
sta hposp0+5
beq @+
No5thTankHide
cpx #$5 ; 6th tank is defferent
bne No6thTankHide
sta hposp0+6
sta hposp0+7
beq @+
No6thTankHide
sta hposp0,x
@
ldx TankNr
jmp DoNotDrawTankNr
SkipHidingPM
ldy TankShape,x
lda TankShapesTable,y
tay
lda AngleTable,x
cmp #91 ; left or right tank shape
bcs LeftTank
:2 iny ; right tank
LeftTank
sty CharCode
jsr SetupXYdraw
jsr TypeChar.Fast
lda Erase
jne noTankNoPM
; now P/M graphics on the screen (only for 5 tanks)
; horizontal position
ldx TankNr
lda TanksPMOrder,x
tax
mwa xdraw xbyte
rorw xbyte ; divide by 2 (carry does not matter)
lda xbyte
clc
adc #PMOffsetX ; P/M to graphics offset
cpx #$4 ; 5th tank are joined missiles and offset is defferent
bne No5thTank
clc
adc #$04 ; missile offset offset
sta hposp0+4
sta hposp0+5
bne NoMissile
No5thTank
cpx #$5 ; 6th tank are joined missiles and offset is defferent
bne Tanks1to4
clc
adc #$04 ; missile offset offset
sta hposp0+6
sta hposp0+7
bne NoMissile
Tanks1to4
sta hposp0,x
NoMissile
; vertical position
lda pmtableL,x
sta xbyte
lda pmtableH,x
sta xbyte+1
; calculate start position of the tank
lda ydraw
clc
adc #PMOffsetY
sta temp
ldy #$00
cpx #$5
bcs PMForTank6
; clear sprite and put 3 lines on the tank at the same time
ldx #3 ; three lines of PM
ClearPM
cpy temp
bne ZeroesToGo
@ lda (xbyte),y
and #%11110000
ora #%00001111 ; (2 bits set) we set on two pixels in three lines
sta (xbyte),y
dey
dex
bne @-
ZeroesToGo
lda (xbyte),y
and #%11110000
sta (xbyte),y
dey
bne ClearPM
beq NoPlayerMissile
PMForTank6
; clear sprite and put 3 lines on the tank at the same time
ldx #3 ; three lines of PM
ClearPM6
cpy temp
bne ZeroesToGo6
@ lda (xbyte),y
and #%00001111
ora #%11110000 ; (2 bits set) we set on two pixels in three lines
sta (xbyte),y
dey
dex
bne @-
ZeroesToGo6
lda (xbyte),y
and #%00001111
sta (xbyte),y
dey
bne ClearPM6
NoPlayerMissile
noTankNoPM
ldy #$01
lda Erase
seq:dey
sty color
; draw defensive weapons like shield ( tank number in X )
; in xdraw, ydraw we have coordinates left LOWER corner of Tank char
ldx TankNr
lda ActiveDefenceWeapon,x
cmp #ind_Shield ; one shot shield
beq DrawTankSh
cmp #ind_Force_Shield ; shield with energy and parachute
beq DrawTankShieldBold
cmp #ind_Heavy_Shield ; shield with energy
beq DrawTankShieldBold
cmp #ind_Bouncy_Castle ; Auto Defence
beq DrawTankShieldWihHorns
cmp #ind_Mag_Deflector ; Mag Deflector
beq DrawTankShieldWihHorns
cmp #ind_White_Flag ; White Flag
beq DrawTankFlag
bne NoShieldDraw
DrawTankSh
jsr DrawTankShield
beq NoShieldDraw ; JMP
DrawTankShieldWihHorns
jsr DrawTankShield
jsr DrawTankShieldHorns
jmp NoShieldDraw
DrawTankShieldBold
jsr DrawTankShield
jsr DrawTankShieldBoldLine
beq NoShieldDraw ; JMP
DrawTankFlag
lda #char_flag ; flag symbol
sta CharCode
lda Ytankstable,x
sec
sbc #8
sta ydraw
jsr TypeChar.Fast
NoShieldDraw
BarrelChange
ldy #$01
lda Erase
seq:dey
sty color
jsr DrawBarrel
ldx TankNr
DoNotDrawTankNr
rts
.endp
; -------------------------------------
.proc FlashTank
; -------------------------------------
; number of blinking tank in TankNr
mva #18 fs ; temp, how many times flash the tank
tankflash_loop
jsr CheckStartKey ; START KEY
sne:mva #1 fs ; finish it
mva #1 Erase
ldx TankNr
jsr DrawTankNr.SkipHidingPM ; it's necessary becouse DrawTankNr skips tanks with no energy !
;PAUSE 2
ldy #1
jsr PauseYFrames
mva #0 Erase
ldx TankNr
jsr DrawTankNr.SkipHidingPM
;PAUSE 2
ldy #1
jsr PauseYFrames
dec fs
jne tankflash_loop
rts
.endp
;--------------------------------------------------
.proc DrawTankShield
; X - tank number
; if use DrawInPosition entry point then:
; xdraw, ydraw - coordinates left LOWER corner of Tank char
; values remain there after a DrawTankNr proc.
;
; this proc change xdraw, ydraw and temp!
;--------------------------------------------------
sbw xdraw #$03 ; 3 pixels to left
; draw left vertical line of shield ( | )
mva #7 temp ; strange !!!
@
jsr plot
.nowarn dew ydraw
dec temp
bne @-
; draw left oblique line of shield ( / )
mva #3 temp
@
jsr plot
.nowarn dew ydraw
inw xdraw
dec temp
bne @-
; draw top horizontal line of shield ( _ )
mva #7 temp
@
jsr plot
inw xdraw
dec temp
bne @-
; draw right oblique line of shield ( \ )
mva #3 temp
@
jsr plot
inw ydraw
inw xdraw
dec temp
bne @-
; draw right vertical line of shield ( | )
mva #7 temp
@
jsr plot
inw ydraw
dec temp
bne @-
rts ; Z allways set
.endp
;--------------------------------------------------
.proc DrawTankShieldHorns
; use only directly after DrawTankShield
; this proc draws a little "horns" on shield.
; Symbol of defensive but aggressive :) weapon
;--------------------------------------------------
.nowarn dew xdraw ; 1 pixel left
sbw ydraw #$0a ; 10 pixels up
jsr plot
.nowarn dew ydraw
inw xdraw
jsr plot
sbw xdraw #$0d ; 13 pixels left
jsr plot
inw xdraw
inw ydraw
jmp plot ; jsr:rts
; rts
.endp
;--------------------------------------------------
.proc DrawTankShieldBoldLine
; use only directly after DrawTankShield
; this proc draws bold top on shield.
; Symbol of ablative shield ? :)
;--------------------------------------------------
sbw xdraw #$04 ; 5 pixels left
sbw ydraw #$0b ; 11 pixels up
; draw additional top horizontal line of shield ( _ )
mva #6 temp
@
jsr plot
.nowarn dew xdraw
dec temp
bne @-
rts ; Z allways set
.endp
;--------------------------------------------------
.proc DrawTankParachute
;Tank number in X
;--------------------------------------------------
lda #char_parachute ; parachute symbol
sta CharCode
lda Ytankstable,x
cmp #16
bcc ToHighToParachute
;sec
sbc #8
sta ydraw
jsr SetupXYdraw.X
jsr TypeChar.Fast
ToHighToParachute
ldx TankNr
rts
.endp
;--------------------------------------------------
.proc DrawTankRocketEngine
; X - tank number
;
; this proc change xdraw, ydraw and temp!
;--------------------------------------------------
clc
lda Ytankstable,x
adc #2 ; 1 pixel down
sta ydraw
mva #0 ydraw+1
clc
lda XtanksTableL,x
adc #2 ; 2 pixels to right
sta xdraw
lda XtanksTableH,x
adc #0
sta xdraw+1
; draw first horizontal line
mva #5 temp
@
jsr plot
inw xdraw
dec temp
bne @-
sbw xdraw #2 ; 2 pixels left
inw ydraw ; 1 pixel down
; draw second horizontal line
mva #3 temp
@
jsr plot
.nowarn dew xdraw
dec temp
bne @-
adw xdraw #2 ; 2 pixels right
inw ydraw ; 1 pixel down
; and last pixel
jsr plot
ldx TankNr
rts
.endp
;--------------------------------------------------
.proc DrawTankEngine
; X - tank number
;
; this proc change xdraw, ydraw and temp!
;--------------------------------------------------
jsr SetupXYdraw.X
; one pixel under tank
clc
lda Ytankstable,x
adc #1
sta ydraw
mva #0 ydraw+1
; plot one (first - clear) and 6 random color pixels
mvy #7 temp
; clear first pixel under tank
bne @pl ; A=0
@ lda Erase
eor #%00000001
and random
and #%00000001
@pl sta color
jsr plot
inw xdraw
dec temp
bne @-
; clear last pixel under tank
mva #0 color
jsr plot
ldx TankNr
rts
.endp
;--------------------------------------------------
.proc TankFalls;
;--------------------------------------------------
lda #0
sta PreviousFall ; bit 7 - left, bit 6 - right
sta EndOfTheFallFlag
sta Parachute
mva #2 FallingSoundBit ; another trick for only one sfx initialization in loop
; let's check if the given tank has got the parachute
ldx TankNr
lda ActiveDefenceWeapon,x
cmp #ind_Parachute ; parachute
beq ParachuteActive
cmp #ind_StrongParachute ; strong parachute
beq ParachuteActive
cmp #ind_Force_Shield ; shield witch energy and parachute
bne TankFallsX
ParachuteActive
inc Parachute
TankFallsX
; sound only if really falls
lda Parachute
and FallingSoundBit ; bit 1
beq NoFallingSound
mva #0 FallingSoundBit
mva #sfx_shield_off sfx_effect
NoFallingSound
; clear previous position
mva #1 Erase
jsr ClearTankNr
; and the parachute (if present)
lda Parachute
and #01
beq DoNotClearParachute
; here we clear the parachute
; ldx TankNr
jsr DrawTankParachute
DoNotClearParachute
mva #0 Erase
; ldx TankNr
lda EndOfTheFallFlag ; We only get byte below the tank if still falling
bne NoGroundCheck
; coordinates of the first pixel under the tank
ldx TankNr
jsr SetupXYdraw.X
lda Ytankstable,x
clc
adc #1 ; in this point the comment helped us! For the very first
; time in our lives! Tada! It opens a new chapter!!!
sta ydraw
;
; UnderTank1 ; byte under tank
; UnderTank2 ; byte under tank reversed (for simple check right direction)
lda #08
sta temp ; Loop Counter
ByteBelowTank
jsr point_plot
bne EmptyPoint2
sec
ror UnderTank2
sec
bcs ROLPoint2
EmptyPoint2
clc
ror UnderTank2
clc
ROLPoint2
rol UnderTank1
inw xdraw
dec temp
bne ByteBelowTank
NoGroundCheck
ldx TankNr
lda Ytankstable,x
cmp #screenheight-1 ; tank on lowest position (no falling down)
jcs EndOfFall
lda UnderTank1
bne NoFallingDown
; Tank falling down ----
lda Parachute
and #1
bne ParachutePresent
; decreasing energy
ldy #2 ; how much energy to substract if no parachute
jsr DecreaseEnergyX
ParachutePresent
; check parachute type
lda ActiveDefenceWeapon,x
cmp #ind_StrongParachute ; strong parachute
bne OneTimeParachute
; decreasing energy of parachute
ldy #1 ; how much parachute energy to substract
jsr DecreaseShieldEnergyX
cpy #0 ; is necessary to reduce tenk energy ?
beq @+
jsr DecreaseEnergyX
@
; check energy of parachute
lda ShieldEnergy,x
bne OneTimeParachute
lda #$00
sta Parachute
sta ActiveDefenceWeapon,x ; deactivate defence
OneTimeParachute
lda Parachute
ora #2 ; we set bit nr 1 (nr 0 means that parachute is present)
sta Parachute
; tank is falling down - modify coorinates
lda Ytankstable,x
clc
adc #1
sta Ytankstable,x
jmp EndOfFCycle
NoFallingDown
; check direction (left or right)
ldy #SlideLeftTableLen-1 ; SlideLeftTable length -1 (from 0 to 7)
@ lda SlideLeftTable,y
cmp UnderTank1
beq FallingLeft
cmp UnderTank2
beq FallingRight
dey
bpl @-
bmi NoLeftOrRight
FallingRight
; tank is falling right
bit PreviousFall ; bit 6 - left
bvs EndRightFall
; we finish falling right if the tank reached the edge of the screen
lda XtanksTableH,x
cmp #>(screenwidth-TankWidth-2) ; 2 pixels correction due to a barrel wider than tank
bne @+
lda XtanksTableL,x
cmp #<(screenwidth-TankWidth-2) ; 2 pixels correction due to a barrel wider than tank
@ bcs EndRightFall
NotRightEdge
; tank is falling right - modify coorinates
clc
lda XtankstableL,x
adc #1
sta XtankstableL,x
scc
inc XtankstableH,x
mva #%10000000 PreviousFall ; set bit 7 - right
bne EndOfFCycle
FallingLeft
; tank is falling left
bit PreviousFall ; bit 7 - right
bmi EndLeftFall
; we finish falling left if the tank reached the edge of the screen
lda XtanksTableH,x
bne NotLeftEdge
lda XtanksTableL,x
cmp #3 ; 2 pixels correction due to a barrel wider than tank
bcc EndLeftFall
NotLeftEdge
; tank is falling left - modify coorinates
sec
lda XtankstableL,x
sbc #1
sta XtankstableL,x
scs
dec XtankstableH,x
mva #%01000000 PreviousFall ; set bit 6 - left
bne EndOfFCycle
EndLeftFall
EndRightFall
NoLeftOrRight
inc EndOfTheFallFlag ; after this is shouldn't fall
EndOfFCycle