Files
scorch_src/weapons.asm
T
2022-02-14 00:19:27 -05:00

2165 lines
44 KiB
NASM
Executable File

; @com.wudsn.ide.asm.mainsourcefile=scorch.asm
.IF *>0 ;this is a trick that prevents compiling this file alone
; ------------------------
babymissile
inc FallDown2
mva #11 ExplosionRadius
jsr CalculateExplosionRange
jmp xmissile
; ------------------------
missile ;
inc FallDown2
mva #17 ExplosionRadius
jsr CalculateExplosionRange
jmp xmissile
; ------------------------
babynuke
inc FallDown2
mva #25 ExplosionRadius
jsr CalculateExplosionRange
jmp xmissile
; ------------------------
nuke
inc FallDown2
mva #31 ExplosionRadius
jsr CalculateExplosionRange
jmp xmissile
; ------------------------
leapfrog
inc FallDown2
mva #17 ExplosionRadius
jsr CalculateExplosionRange
jsr xmissile
; soil must fall down now! there is no other way...
;first clean the offensive text...
ldy TankNr
mva #0 plot4x4color
jsr DisplayOffensiveTextNr
; hide tanks or they fall down with soil
lda TankNr
pha
mva #1 Erase
jsr drawtanks
mva #0 Erase
jsr SoilDown2
jsr drawtanks
pla
sta TankNr
; it looks like force is divided by 4 here BUT"
; in Flight routine force is multiplied by 2 and left
; so, we have Force divided by 2 here (not accurately)
lsr Force+1
ror Force
;lsr Force+1
;ror Force
lda LeapFrogAngle
sta Angle
jsr Flight
lda HitFlag
beq EndOfLeapping
mva #15 ExplosionRadius
jsr CalculateExplosionRange0
jsr xmissile
; soil must fall down now! there is no other way...
; hide tanks or they fall down with soil
lda TankNr
pha
mva #1 Erase
jsr drawtanks
mva #0 Erase
jsr SoilDown2
jsr drawtanks
pla
sta TankNr
; it looks like force is divided by 4 here BUT"
; in Flight routine force is multiplied by 2 and left
; so, we have Force divided by 2 here (not accurately)
;lsr Force+1
;ror Force
lsr Force+1
ror Force
lda LeapFrogAngle
sta Angle
jsr Flight
lda HitFlag
beq EndOfLeapping
mva #13 ExplosionRadius
jsr CalculateExplosionRange0
jmp xmissile
EndOfLeapping
rts
; ------------------------
mirv ; the whole mirv is performed by Flight routine
inc FallDown2
rts
; ------------------------
funkybomb ;
mwa xtraj+1 xtrajfb
mwa ytraj+1 ytrajfb
inc FallDown2
;central Explosion
mva #21 ExplosionRadius
jsr CalculateExplosionRange0
jsr xmissile
ldy TankNr
mva #0 plot4x4color
jsr DisplayOffensiveTextNr
lda TankNr
pha
mva #1 Erase
jsr drawtanks
mva #0 Erase
jsr SoilDown2
;
mva #1 Erase
jsr drawtanks
mva #0 Erase
pla
sta TankNr
mva #5 FunkyBombCounter
FunkyBombLoop
mva #1 tracerflag
;force randomization (range: 256-511)
lda random
sta Force
mva #1 Force+1
;Angle randomization Range: (-16..+16)
lda random
lsr
and #%00011111
bcc DoNotEor
eor #$ff
DoNotEor
sta Angle
lda #0
sta xtraj
sta ytraj
mwa xtrajfb xtraj+1
mwa ytrajfb ytraj+1
jsr Flight
lda HitFlag
beq NoExplosionInFunkyBomb
jsr CalculateExplosionRange
jsr xmissile
NoExplosionInFunkyBomb
dec FunkyBombCounter
bne FunkyBombLoop
mva #0 tracerflag
rts
; ------------------------
deathshead
inc FallDown2
mva #31 ExplosionRadius
jsr CalculateExplosionRange
jsr xmissile
sbw xdraw #35
jsr CalculateExplosionRange
jsr xmissile
adw xdraw #70
jsr CalculateExplosionRange
jsr xmissile
sbw xdraw #35
;
sbw ydraw #35
;jsr CalculateExplosionRange
cpw ydraw #screenHeight
bcs NoUpperCircle
jsr xmissile
NoUpperCircle
adw ydraw #70
;jsr CalculateExplosionRange
cpw ydraw #screenHeight
bcs NoLowerCircle
jsr xmissile
NoLowerCircle
rts
; ------------------------
tracer
rts
; ------------------------
babyroller
inc FallDown2
mva #11 ExplosionRadius
jmp xroller
; ------------------------
roller ;
inc FallDown2
mva #21 ExplosionRadius
jmp xroller
; ------------------------
heavyroller
inc FallDown2
mva #31 ExplosionRadius
jmp xroller
; ------------------------
riotbomb
inc FallDown2
mva #17 ExplosionRadius
jsr CalculateExplosionRange
jmp xriotbomb
; ------------------------
heavyriotbomb
inc FallDown2
mva #29 ExplosionRadius
jsr CalculateExplosionRange
jmp xriotbomb
; ------------------------
babydigger
mva #0 sandhogflag
inc FallDown2
mva #13 DigLong
mva #1 diggery ; how many branches (-1)
jmp xdigger
; ------------------------
digger ;
mva #0 sandhogflag
inc FallDown2
mva #13 DigLong
mva #3 diggery ; how many branches (-1)
jmp xdigger
; ------------------------
heavydigger
mva #0 sandhogflag
inc FallDown2
mva #13 DigLong
mva #7 diggery ; how many branches (-1)
jmp xdigger
; ------------------------
xdigger
mwa xdraw digstartx
mwa ydraw digstarty
ldx diggery
WriteToBranches
lda xdraw
sta digtabxL,x
lda xdraw+1
sta digtabxH,x
lda ydraw
sta digtabyL,x
lda ydraw+1
sta digtabyH,x
dex
bpl WriteToBranches
jsr DiggerCharacter ; start character
adw xdraw #4
lda DigLong
; looks strange, but it is (DigLong+2)*4
clc
adc #$2
asl
asl
sta ExplosionRadius
jsr CalculateExplosionRange
BranchNotFinished
ldx diggery
CalculateBranches
txa
and #$01
bne DigRight
diglewy ; even branches go left
sec
lda digtabxL,x
sbc #$04
sta digtabxL,x
lda digtabxH,x
sbc #$00
sta digtabxH,x
jmp DigRandomize
DigRight ; odd go right (everytime 4 pixels)
clc
lda digtabxL,x
adc #$04
sta digtabxL,x
lda digtabxH,x
adc #$00
sta digtabxH,x
DigRandomize
lda random
and #$87
bmi DigUp
digwdol
and #$07
clc
adc digtabyL,x
sta digtabyL,x
lda digtabyH,x
adc #$00
sta digtabyH,x
jmp DigCalculateNext
DigUp
and #$07
sta temp
sec
lda digtabyL,x
sbc temp
sta digtabyL,x
lda digtabyH,x
sbc #$00
sta digtabyH,x
DigCalculateNext
dex
bpl CalculateBranches
; here we draw...
ldx diggery
DigDrawing
lda digtabxL,x
sta xdraw
lda digtabxH,x
sta xdraw+1
lda digtabyL,x
sta ydraw
lda digtabyH,x
sta ydraw+1
phx
jsr DiggerCharacter
plx
dex
bpl DigDrawing
dec:lda DigLong
jpl BranchNotFinished
rts
DiggerCharacter
lda random
and #$06
clc
adc #$36
adc sandhogflag
sta CharCode
cpw xdraw #(screenwidth-6)
bcs DoNotPutDig
jmp TypeChar
DoNotPutDig
rts
; ------------------------
babysandhog
mva #8 sandhogflag
inc FallDown2
mva #13 DigLong
mva #1 diggery ; how many branches (-1)
jmp xdigger
; ------------------------
sandhog
mva #8 sandhogflag
inc FallDown2
mva #13 DigLong
mva #3 diggery ; how many branches (-1)
jmp xdigger
; ------------------------
heavysandhog
mva #8 sandhogflag
inc FallDown2
mva #13 DigLong
mva #5 diggery ; how many branches (-1)
jmp xdigger
; ------------------------
dirtclod
inc FallDown2
mva #12 ExplosionRadius
jsr CalculateExplosionRange
jmp xdirt
; ------------------------
dirtball
inc FallDown2
mva #22 ExplosionRadius
jsr CalculateExplosionRange
jmp xdirt
; ------------------------
tonofdirt
inc FallDown2
mva #31 ExplosionRadius
jsr CalculateExplosionRange
jmp xdirt
; ------------------------
dirtcharge
inc FallDown2
mva #61 ExplosionRadius
jsr CalculateExplosionRange
jmp ofdirt
; ------------------------
laser
ldx TankNr
lda AngleTable,x
tay
clc
lda xtankstableL,x
adc EndOfTheBarrelX,y ; correction of the end of the barrel point
sta xbyte
lda xtankstableH,x
adc #0
sta xbyte+1
sec
lda ytankstable,x
sbc EndOfTheBarrelY,y
sta ybyte
mva #0 ybyte+1
mwa #Drawplot DrawJumpAddr
mwa xdraw LaserCoordinate
mwa ydraw LaserCoordinate+2
mwa xbyte LaserCoordinate+4
mwa ybyte LaserCoordinate+6
jsr draw
mva #0 color
mwa LaserCoordinate xdraw
mwa LaserCoordinate+2 ydraw
mwa LaserCoordinate+4 xbyte
mwa LaserCoordinate+6 ybyte
jsr draw
mva #1 color
mwa LaserCoordinate xdraw
mwa LaserCoordinate+2 ydraw
mwa LaserCoordinate+4 xbyte
mwa LaserCoordinate+6 ybyte
jsr draw
mva #0 color
mwa LaserCoordinate xdraw
mwa LaserCoordinate+2 ydraw
mwa LaserCoordinate+4 xbyte
mwa LaserCoordinate+6 ybyte
jsr draw
mva #1 color
mwa LaserCoordinate xdraw
mwa LaserCoordinate+2 ydraw
jsr plot
mva #0 HitFlag
jsr CheckCollisionWithTank
lda HitFlag
beq LaserMisses
; here we hit a tank (X)
ldy #100
jsr DecreaseEnergyX
LaserMisses
rts
; -----------------
xmissile ;
; -----------------
lda #1
sta radius
sta color
;ora ExplosionRadius ;making sure the ExplosionRadius is odd
;sta ExplosionRadius
ExplosionLoop
jsr circle
inc ydraw
jsr circle
dec ydraw
inc:inc radius
lda radius
cmp ExplosionRadius
bne ExplosionLoop
lda #0
sta color
ExplosionLoop2
jsr circle
inc ydraw
jsr circle
dec ydraw
dec radius
lda radius
bne ExplosionLoop2
lda #1
sta color
;check tanks' distance from the centre of the explosion
mwa #DrawLen DrawJumpAddr
;the above switches Draw to measuring length
;trick is easy - how many pixels does it take to draw
;a line from one point to another
;it must be somehow easier than regular Pitagoras
;calculation
ldx NumberOfPlayers
DistanceCheckLoop
dex
lda eXistenZ,x
beq EndOfDistanceCheckLoop
;here the tank exist
lda XtankstableL,x
clc
adc #3 ;measure from middle of the tank
sta xbyte
lda XtankstableH,x
clc
adc #0 ;measure from middle of the tank
sta xbyte+1
lda Ytankstable,x
sec
sbc #2 ;measure from middle of the tank
sta ybyte
lda #0
sta ybyte+1
phx
jsr draw
plx
;if tank within range of the explosion?
lda LineLength+1
bne TankIsNotWithinTheRange
lda LineLength
cmp ExplosionRadius
bcs TankIsNotWithinTheRange
lda ExplosionRadius
sec
sbc LineLength
;multiply difference by 8
clc
adc #1
asl
asl
asl
tay
jsr DecreaseEnergyX
TankIsNotWithinTheRange
EndOfDistanceCheckLoop
txa
bne DistanceCheckLoop
rts
; -----------------
xdirt ;
; -----------------
lda #1
sta radius
sta color
dirtLoop
jsr circle
inc ydraw
jsr circle
dec ydraw
inc radius
lda radius
cmp ExplosionRadius
bne dirtLoop
rts
; -----------------
xriotbomb ;
; -----------------
lda #0
sta radius
sta color
rbombLoop
jsr circle
inc radius
lda radius
cmp ExplosionRadius
bne rbombLoop
mva #1 color
rts
; ----------------
xroller ;
; now collisions are detected with modified draw routine
; therefore YDRAW value must be taken from mountaintable
ldy #0
mwa #mountaintable tempXROLLER
adw tempXROLLER xdraw
lda (tempXROLLER),y
sta ydraw
lda vx+3
; if horizontal velocity is negative then change the direction
bpl PositiveVelocity
lda goleft
ora #$01
sta goleft
PositiveVelocity
; first we look for the left slope
; then righ slope and set the flag
; $FF - we are in a hole (flighting in missile direction)
; 1 - right, 2 - left
mva #$ff HowMuchToFall
mva ydraw HeightRol
mwa #mountaintable tempXROLLER
adw tempXROLLER xdraw
SeekLeft
sbw tempXROLLER #1
lda (tempXROLLER),y ;fukk! beware of Y value
cmp HeightRol
bne HowMuchToFallLeft
lda tempXROLLER
cmp #<mountaintable
bne SeekLeft
lda tempXROLLER+1
cmp #>mountaintable
beq GoRightNow
HowMuchToFallLeft
bcs GoRightNow
mva #1 HowMuchToFall
GoRightNow
mwa #mountaintable tempXROLLER
adw tempXROLLER xdraw
SeekRight
adw tempXROLLER #1
lda (tempXROLLER),y
cmp HeightRol
bne HowMuchToFallRight
lda tempXROLLER
cmp #<(mountaintable+screenwidth)
bne SeekRight
lda tempXROLLER+1
cmp #>(mountaintable+screenwidth)
beq HowMuchToFallKnown
HowMuchToFallRight
; check if up or down
bcs HowMuchToFallKnown
lda HowMuchToFall
bpl ItIsLeftAlready
mva #2 HowMuchToFall
bne HowMuchToFallKnown
ItIsLeftAlready
mva #$ff HowMuchToFall
HowMuchToFallKnown
lda HowMuchToFall
bpl Rollin
lda #1
clc
adc goleft
sta HowMuchToFall
Rollin
adw xdraw #mountaintable tempXROLLER
ldy #0
lda (tempXROLLER),y
sta HeightRol ; relative point
RollinContinues
wait
wait
; new point is set
adw xdraw #mountaintable tempXROLLER
ldy #0
lda (tempXROLLER),y
sta ydraw
beq ExplodeNow
cmp HeightRol
beq UpNotYet
bcc ExplodeNow
UpNotYet
sec ;clc
sta HeightRol
sbc #1
sta ydraw
;check tank collision prior to PLOT
sty HitFlag
mwa xdraw xtraj+1
mwa ydraw ytraj+1
jsr CheckCollisionWithTank
lda HitFlag
bne ExplodeNow
jsr unPlot
; let's go the right direction
lda HowMuchToFall
cmp #1
beq HowMuchToFallRight2
sbw xdraw #1
lda xdraw
bne RollinContinues
lda xdraw+1
jne RollinContinues
beq ExplodeNow
HowMuchToFallRight2
adw xdraw #1
cpw xdraw screenwidth
jne RollinContinues
ExplodeNow
mwa xdraw xcircle ; we must store somewhere (BAD)
mva ydraw ycircle ; xdraw and ydraw (BAD)
mwa #0 xdraw
mva #screenheight-1 ydraw
jsr unPlot
mwa xcircle xdraw ;(bad)
mva ycircle ydraw ;(bad)
; finally a little explosion
jsr CalculateExplosionRange
jmp xmissile
rts
; --------------------------------------------------
ofdirt ;
; --------------------------------------------------
; makes dirt on xdraw,ydraw position and of ExplosionRadius height
mwa xdraw xcircle
mva ydraw ycircle
lda #1
; current dirt width
sta magic
sta color
NextRow
wait
ldy magic
NextLine
lda random
and #$01
beq DoNotPlot
sty magic+1
jsr plot
ldy magic+1
DoNotPlot
adw xdraw #1
dey
bne NextLine
dec ydraw ; 1 line up
lda ydraw
cmp #$ff
beq EndOfTheDirt ;if horizontal Counter wraps
inc magic ; width+2
inc magic
lda magic
sta magic+1 ; just for a second
lsr magic+1
sec
lda xcircle
sbc magic+1
sta xdraw
lda xcircle+1
sbc #0
sta xdraw+1 ; new starting coordinate in a given row
dec ExplosionRadius
bne NextRow
EndOfTheDirt
mwa xcircle xdraw
mva ycircle ydraw
rts
;--------------------------------------------------
BeforeFire .proc ;TankNr (byte)
;--------------------------------------------------
;this nice routine makes the whole shooting
;preparation: aiming and displaying
;angle and shooting force values
;
;first, get current parameters (angle+force)
;for an active tank and display them
;(these values are taken from the previous round)
ldx TankNr
;Checking the maximal force
lda MaxEnergyTableH,x
cmp EnergyTableH,x
bne ContinueToCheckMaxForce2
lda MaxEnergyTableL,x
cmp EnergyTableL,x
ContinueToCheckMaxForce2
bcs skip15
lda MaxEnergyTableH,x
sta EnergyTableH,x
lda MaxEnergyTableL,x
sta EnergyTableL,x
skip15
jsr DisplayingSymbols ;all digital values like force, angle, wind, etc.
jsr PutTankNameOnScreen
jsr DrawTankNr
wait ; best after drawing a tank
;wait
;keyboard reading
; KBCODE keeps code of last keybi
; SKSTAT $ff - nothing pressed
; $FB - any key
; $f7 - shift
; $f3 - shift+key
notpressed
lda SKSTAT
cmp #$ff
beq checkJoy
cmp #$f7
beq checkJoy
lda kbcode
and #$Bf
cmp #$8e
jeq CTRLPressedUp
cmp #$8f
jeq CTRLPressedDown
cmp #$ac
jeq CTRLPressedTAB
and #$3f ;CTRL and SHIFT ellimination
jumpFromStick
cmp #$e
jeq pressedUp
cmp #$f
jeq pressedDown
cmp #$6
jeq pressedLeft
cmp #$7
jeq pressedRight
cmp #$21
jeq pressedSpace
cmp #$2c
jeq pressedTAB
jmp notpressed
checkJoy
;------------JOY-------------
;happy happy joy joy
;check for joystick now
lda JSTICK0
and #$0f
cmp #$0f
beq notpressedJoy
tay
lda joyToKeyTable,y
jmp jumpFromStick
notpressedJoy
;fire
lda TRIG0
bne JNotFire
lda #$21
jmp jumpFromStick
JNotFire
jmp notpressed
;
pressedUp
;force increaseeee!
ldx TankNr
inc EnergyTableL,x
bne CheckingMaxForce
inc EnergyTableH,x
CheckingMaxForce
lda MaxEnergyTableH,x
cmp EnergyTableH,x
bne FurtherCheckMaxForce
lda MaxEnergyTableL,x
cmp EnergyTableL,x
FurtherCheckMaxForce
jcs BeforeFire
lda MaxEnergyTableH,x
sta EnergyTableH,x
lda MaxEnergyTableL,x
sta EnergyTableL,x
jmp BeforeFire
CTRLPressedUp
ldx TankNr
lda EnergyTableL,x
clc
adc #10
sta EnergyTableL,x
bcc CheckingMaxForce
inc EnergyTableH,x
jmp CheckingMaxForce
pressedDown
ldx TankNr
dec EnergyTableL,x
lda EnergyTableL,x
cmp #$ff
bne skip04
dec EnergyTableH,x
bpl skip04
ForceGoesZero
lda #0
sta EnergyTableH,x
sta EnergyTableL,x
skip04
jmp BeforeFire
CTRLPressedDown
ldx TankNr
sec
lda EnergyTableL,x
sbc #10
sta EnergyTableL,x
jcs BeforeFire
dec EnergyTableH,x
bmi ForceGoesZero
jmp BeforeFire
pressedLeft
ldx TankNr
dec AngleTable,x
lda AngleTable,x
cmp #$ff ; if angle goes through 0 we clear the barrel
bne NotThrough90DegreesLeft
mva #$2e CharCode
jsr drawtankNrX
NotThrough90DegreesLeft
cmp #(255-91)
jne BeforeFire
lda #90
sta AngleTable,x
jmp BeforeFire
pressedRight
ldx TankNr
INC AngleTable,x
lda AngleTable,x
bne NotThrough90DegreesRight
mva #$30 CharCode ; if angle goes through 0 we clear the barrel
jsr drawtankNrX
NotThrough90DegreesRight
cmp #91
jne BeforeFire
lda #(255-90)
sta AngleTable,x
jmp BeforeFire
pressedTAB
ldx TankNr
inc ActiveWeapon,x
lda ActiveWeapon,x
cmp #$30 ; number of offensive weapons
bne skip14
lda #0
sta ActiveWeapon,x
skip14
lda ActiveWeapon,x
jsr HowManyBullets ; and we have qty of owned shells. Ufff....
beq pressedTAB
jsr WaitForKeyRelease
jmp BeforeFire
CTRLpressedTAB
ldx TankNr
dec ActiveWeapon,x
bpl skip14CT
lda #$2f ; the last possible offensive weapon
sta ActiveWeapon,x
skip14CT
lda ActiveWeapon,x
jsr HowManyBullets ; and we have qty of owned shells. Ufff....
beq CTRLpressedTAB
jsr WaitForKeyRelease
jmp BeforeFire
pressedSpace
;=================================
;we shoot here!!!
RTS
.endp
;--------------------------------------------------
Shoot .proc ;TankNr (byte)
;--------------------------------------------------
;it looks like this routine is too big -
;- more and more functions were being added...
;good idea would be to rewrite it completely
;with much more separate blocks, but you know -
;- do not touch it if it works...
;the latest addition to this routine is
;displaying offensive texts!
RandomizeOffensiveText
lda random
cmp #talk.NumberOfOffensiveTexts
bcs RandomizeOffensiveText
sta TextNumberOff
ldy TankNr
mva #1 plot4x4color
jsr DisplayOffensiveTextNr
ldx TankNr
lda ActiveWeapon,x
cmp #$20 ; laser
bne NotStrongShoot
mva #0 color
lda #7
sta Force
sta Force+1
bne AfterStrongShoot
NotStrongShoot
lda EnergyTableL,x
sta Force
lda EnergyTableH,x
sta Force+1
AfterStrongShoot
lda #$0
sta Force+2
lda AngleTable,x
sta Angle
lda #0
sta xtraj
sta ytraj
; Shoots tank nr X !!! :)
;ldx TankNr
lda xtankstableL,x
sta xtraj+1
lda xtankstableH,x
sta xtraj+2
lda ytankstable,x
sta ytraj+1
lda #$00
sta ytraj+2
; correction of the starting coordinates of bullet
; to start where the tank's barrel ends
; (without it bullet would go from the left lower corner of the tank)
ldy Angle
clc
lda xtraj+1
adc EndOfTheBarrelX,y ; correction of X
;adc #4
sta xtraj+1
lda xtraj+2
adc #0
sta xtraj+2
sec
lda ytraj+1
sbc EndOfTheBarrelY,y ; correction of Y
;sbc #7
sta ytraj+1
lda ytraj+2
sbc #0
sta ytraj+2
ldy #100
jsr Flight
mva #1 color
;jsr WaitForKeyRelease
rts
.endp
;--------------------------------------------------
TankFalls .proc;
;--------------------------------------------------
lda #0
sta PreviousFall
sta EndOfTheFallFlag
sta Parachute
; let's check if the given tank has got the parachute
lda #$35 ; parachute
jsr HowManyBullets
beq TankFallsX
inc Parachute
TankFallsX
; coordinates of the first pixel under the tank
ldx TankNr
lda XtankstableL,x
sta xdraw
lda XtankstableH,x
sta xdraw+1
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
;
lda #08
sta mask2 ; Loop Counter
ByteBelowTank
jsr point
beq EmptyPoint2
sec
bcs ROLPoint2
EmptyPoint2
clc
ROLPoint2
rol mask1
adw xdraw #1
dec mask2
bne ByteBelowTank
ldx mask1
lda WhereToSlideTable,x
sta IfFallDown ; taking directions of falling down from the table
bne ItStillFalls
; Tank falling down already finished, but it is not sure that
; the horizontal coordinate is even.
; If it is odd then it must be corrected because otherwise
; P/M graphics background would not look OK
ldx TankNr
lda XtanksTableL,x
and #$01
jeq EndOfFall ; if it is even then it is the end
; and if not, we push it one pixel the way it was falling before
lda PreviousFall
sta IfFallDown
inc EndOfTheFallFlag ; because after this correction is shouldn't fall anymore
; we have 3 bits: 0 - go down, 1 - go right, 2 - go left
;---
ItStillFalls
lda Parachute
and #1
bne ParachutePresent
; decreasing energy - if the vertical fall, substract 2
; and if at an angle then substract 1
ldy #1 ; how much energy to substract
lda IfFallDown
and #1
beq NoFallingDown
ldx TankNr
jsr DecreaseEnergyX
lda IfFallDown
and #6
bne FallDiagonally
ldx TankNr
jsr DecreaseEnergyX
FallDiagonally
NoFallingDown
ParachutePresent
; we must set flag meaning that the tank was falling down
; because later maybe the number of parachutes will decrease
; (if there were parachutes and they were ON)
lda Parachute
ora #2 ; we set bit nr 1 (nr 0 means that parachute is present)
sta Parachute
; storing last direction of falling
; (it is not necessarily the direction from the previous
; iteraction, so we must check directional bits before storing)
lda IfFallDown
and #$06
beq FallStraightDown
sta PreviousFall
FallStraightDown
lda Parachute
and #01
beq RapidFalling
wait
RapidFalling
; we finish falling down if the tank reached the edge of the screen
; but if it falls straight down or the other way than the edge,
; then continue falling!
ldx TankNr
lda XtanksTableL,x
bne NotLeftEdge
lda XtanksTableH,x
bne NotLeftEdge
lda IfFallDown
and #$04 ; check if it does not fall left
jne EndOfFall ; if so then maybe we finish
NotLeftEdge
clc
lda XtanksTableL,x
adc #$08 ; we'll check right side of the char
sta temp
lda XtanksTableH,x
adc #0
sta temp+1
cpw temp #screenwidth
bne NotRightEdge
lda IfFallDown
and #$02 ; check if it does not fall right
jne EndOfFall ; if so then maybe we finish
NotRightEdge
; clear previous position
mva #1 Erase
jsr DrawTankNr
; and the parachute (if present)
lda Parachute
and #01
beq DoNotClearParachute
; here we clear the parachute
ldx TankNr
lda #$34
sta CharCode
lda Ytankstable,x
sec
sbc #8
sta ydraw
lda XtanksTableL,x
sta xdraw
lda XtanksTableH,x
sta xdraw+1
jsr TypeChar
DoNotClearParachute
mva #0 Erase
ldx TankNr
lsr IfFallDown ; bit nr 0 (down)
bcc DoesNotFallDown
; tank is falling down
lda Ytankstable,x
clc
adc #1
sta Ytankstable,x
DoesNotFallDown
lsr IfFallDown ; bit nr 1 (right)
bcc DoesNotFallLeft
; tank is falling left
clc
lda XtankstableL,x
adc #1
sta XtankstableL,x
lda XtankstableH,x
adc #0
sta XtankstableH,x
DoesNotFallLeft
lsr IfFallDown ; bit nr 2 (left)
bcc DoesNotFallRight
; tank is falling right
sec
lda XtankstableL,x
sbc #1
sta XtankstableL,x
lda XtankstableH,x
sbc #0
sta XtankstableH,x
DoesNotFallRight
jsr DrawTankNr
; checking is parachute present and if so, draw it
lda Parachute
and #01
beq DoNotDrawParachute
; here we draw parachute
ldx TankNr
lda #$34
sta CharCode
lda Ytankstable,x
sec
sbc #8
sta ydraw
lda XtanksTableL,x
sta xdraw
lda XtanksTableH,x
sta xdraw+1
jsr TypeChar
DoNotDrawParachute
lda EndOfTheFallFlag
jeq TankFallsX
EndOfFall
jsr DrawTankNr
; if tank was falling down having parachute,
; we must deduct one parachute
lda Parachute
cmp #$03 ; was falling down and the parachute
bne ThereWasNoParachute
; first we clear parachute on the screen
mva #1 Erase
ldx TankNr
lda #$34
sta CharCode
lda Ytankstable,x
sec
sbc #8
sta ydraw
lda XtanksTableL,x
sta xdraw
lda XtanksTableH,x
sta xdraw+1
jsr TypeChar
mva #0 Erase
; now we can deduct one parachute from the list of weapons
lda #$35 ; parachute
jsr DecreaseWeapon
ThereWasNoParachute
rts
.endp
;--------------------------------------------------
Flight .proc ;Force(byte.byte), Angle(byte), Wind(.byte) 128=0, 255=maxright, 0=maxleft
;--------------------------------------------------
;g=-0.1
;vx=Force*sin(Angle)
;vy=Force*cos(Angle)
;
;:begin
;ytraj=ytray-vy
;vy=vy-g
;xtraj=xtraj+vx - without Wind
;vx=vx+Wind (Wind is a small fraction)
;plot xtraj,ytraj - there is clearing in plot
;goto begin
; smoke tracer :)
ldy #0
ldx TankNr
lda ActiveWeapon,x
cmp #11 ; Smoke tracer
bne noSmokeTracer
iny
noSmokeTracer
sty SmokeTracerFlag
RepeatIfSmokeTracer
mwa ytraj+1 Ytrajold+1
mwa xtraj+1 Xtrajold+1
mwa #DrawCheck DrawJumpAddr
lda #0
sta Result
sta Result+1
sta Result+2
sta HitFlag
sta xdraw
sta xdraw+1
sta ydraw
sta ydraw+1
;vx calculation
aslw Force ;Force=Force*4 ... *2
;aslw Force
;sin(Angle)
ldx Angle
stx LeapFrogAngle ; we will need it later
;Angle works like this:
;0 'degrees' is sraight up
;90 'degrees' is horizontally right
;255 is straight up (same as 0)
;255-90 (165) horizontally left
bpl FlightRight
;and if the highest bit is set then
;Flight to LEFT
;calculate Angle with this formula:
;Angle=90-(Angle-165)
sec
txa
sbc #165 ;(Angle-165)
sta temp ;dirty trick with selfmodifying code (REMOVED)
lda #90 ;
sbc temp ;90-(Angle-165)
;and we have rady angle here ... and we go LEFT!
tax
sta Angle
mva #1 goleft
; and now we contine as if nothing happened
; (but we have goleft set to 1!!!)
bne dontzerogoleft
FlightRight
mva #0 goleft
dontzerogoleft
lda sintable,x ;sin(Angle)
sta Multiplee ;sin(Angle)*Force
mwa Force Multiplier
lda #$0
sta Multiplier+2
ldx #8
MultiplyLoop
ror Multiplee
bcc DoNotAdd
clc
lda Multiplier
adc Result
sta Result
lda Multiplier+1
adc Result+1
sta Result+1
lda Multiplier+2
adc Result+2
sta Result+2
DoNotAdd
;clc ;carry always cleared here (anyway we hope so :)
rol Multiplier
rol Multiplier+1
rol Multiplier+2
dex
bne MultiplyLoop
; here in Result there is a number xxxx.yyy = sin(Angle)*Force
lda Result ;vx=sin(Angle)*Force
sta vx
lda Result+1
sta vx+1
lda Result+2
sta vx+2
mva #0 vx+3
;======vy
lda #0 ;cos(Angle)
sta Result
sta Result+1
sta Result+2
;--
ldx Angle
lda costable,x
sta Multiplee ;cos(Angle)*Force
mwa Force Multiplier
lda #$0
sta Multiplier+2
ldx #8
MultiplyLoopY
ror Multiplee
bcc DoNotAddY
clc
lda Multiplier
adc Result
sta Result
lda Multiplier+1
adc Result+1
sta Result+1
lda Multiplier+2
adc Result+2
sta Result+2
DoNotAddY
;clc ;carry always cleared here (anyway we hope so :)
rol Multiplier
rol Multiplier+1
rol Multiplier+2
dex
bne MultiplyLoopY
; here in Result there is a number xxxx.yyy=cos(Angle)*Force
lda Result ;vy=cos(Angle)*Force
sta vy
lda Result+1
sta vy+1
lda Result+2
sta vy+2
mva #0 vy+3
Loopi
;ytraj=ytraj-vy (skipping least significant byte of vy)
sec
lda ytraj
sbc vy+1
sta ytraj
lda ytraj+1
sbc vy+2
sta ytraj+1
lda ytraj+2
sbc vy+3
sta ytraj+2
;vy=vy-g (again without least significant byte of vy)
sec
lda vy+1
sbc gravity
sta vy+1
lda vy+2
sbc #0
sta vy+2
lda vy+3
sbc #0
sta vy+3
bpl StillUp
; where we know that the bullet starts to fall down
; we check if it is MIRV and if so, jump to MIRV routine
ldx TankNr
lda ActiveWeapon,x
cmp #6 ; MIRV
jeq MIRVdownLoop
StillUp
lda goleft
bne FlightLeft
clc ;xtraj=xtraj+vx (skipping least significant byte of vx)
lda xtraj ;here of course Fight to right
adc vx+1
sta xtraj
lda xtraj+1
adc vx+2
sta xtraj+1
lda xtraj+2
adc vx+3
sta xtraj+2
jmp skip07 ;skipping substracting for Flight to left
FlightLeft
sec ;xtraj=xtraj-vx (skipping least significant byte of vx)
lda xtraj ;here of course Fight to left
sbc vx+1
sta xtraj
lda xtraj+1
sbc vx+2
sta xtraj+1
lda xtraj+2
sbc vx+3
sta xtraj+2
skip07
;vx=vx-Wind (also without least significan byte of vx)
lda goleft
bne FlightsLeft ;blow on bullet flighting left
lda WindOrientation
bne WindToLeft
beq LWindToLeft
FlightsLeft
lda WindOrientation
beq LWindToRight
LWindToLeft
; here Wind to right, bullet goes right as well, so vx=vx+Wind
; here Wind to left, bullet goes left as well, so vx=vx+Wind
clc
lda vx
adc Wind
sta vx
lda vx+1
adc Wind+1
sta vx+1
lda vx+2
adc #0
sta vx+2
lda vx+3
adc #0
sta vx+3
Jmp skip08
WindToLeft
LWindToRight
;Wind to left, bullet right, so vx=vx-Wind
;Wind to right, bullet left, so vx=vx-Wind
sec
lda vx
sbc Wind
sta vx
lda vx+1
sbc Wind+1
sta vx+1
lda vx+2
sbc #0
sta vx+2
lda vx+3
sbc #0
sta vx+3
skip08
mwa xtrajold+1 xdraw
mwa ytrajold+1 ydraw
mwa xtraj+1 xbyte
mwa ytraj+1 ybyte
jsr draw
;key
mwa xtraj+1 XtrajOld+1
mwa ytraj+1 YtrajOld+1
lda tracerflag
bne nowait
lda color
beq nowait
;wait
;this is where program slows down the flight of a missile
;possibly it is too slow to wait till next frame...
;we will see.
;---2003-08-01 yes, it is too slow!!! shorter delay
; must be here like few sta wsync's
; half a frame would be the best...
ldx #FlyDelay
DelayLoop
sta wsync
dex
bne DelayLoop
nowait
lda HitFlag
bne Hit
cpw ytraj+1 #screenheight
bcc YTrayLowerThanScreenHeight
lda ytraj+2
bpl EndOfFlight
YTrayLowerThanScreenHeight ; it means it is still on screen and not above
SkipCollisionCheck
mwa xtraj+1 xdraw
mwa ytraj+1 ydraw
lda tracerflag
bne NoUnPlot
jsr UnPlot
NoUnPlot
jsr PlotPointer
jmp Loopi
Hit
mwa XHit xdraw
mwa YHit ydraw
jsr unPlot
EndOfFlight
mwa xdraw xcircle ; we must store for a little while
mva ydraw ycircle ; xdraw and ydraw
mwa #0 xdraw
mva #screenheight-1 ydraw
jsr unPlot
mwa xcircle xdraw
mva ycircle ydraw
ldy SmokeTracerFlag
beq EndOfFlight2
dey
sty SmokeTracerFlag
jmp SecondFlight
EndOfFlight2
lda #0 ; nie wiem czemu
sta tracerflag ;
rts
.endp
SecondFlight .proc
; ---------------- copied code fragment from before firing. not too elegant.
; ---------------- get fire parameters again
ldx TankNr
lda EnergyTableL,x
sta Force
lda EnergyTableH,x
sta Force+1
lda #$0
sta Force+2
lda AngleTable,x
sta Angle
lda #0
sta color
sta xtraj
sta ytraj
lda xtankstableL,x
sta xtraj+1
lda xtankstableH,x
sta xtraj+2
lda ytankstable,x
sta ytraj+1
lda #$00
sta ytraj+2
ldy Angle
clc
lda xtraj+1
adc EndOfTheBarrelX,y ; correction of X
sta xtraj+1
lda xtraj+2
adc #0
sta xtraj+2
sec
lda ytraj+1
sbc EndOfTheBarrelY,y ; correction of Y
sta ytraj+1
lda ytraj+2
sbc #0
sta ytraj+2
ldy #100
lda #1 ; I do not know (I mean I think I know ;) )
sta tracerflag ; 10 years later - I do not know!!!
jmp Flight.RepeatIfSmokeTracer
.endp
; -------------------------------------------------
MIRVdownLoop .proc
; MIRV loop - here mirv bullets fall down
; -------------------------------------------------
; copy Flight parameters to the table
ldx #4
MIRVcopyParameters
lda xtraj
sta xtraj00,x
lda xtraj+1
sta xtraj01,x
lda xtraj+2
sta xtraj02,x
lda vx
sta vx00,x
lda vx+1
sta vx01,x
lda vx+2
sta vx02,x
lda vx+3
sta vx03,x
lda #0
sta MirvDown,x
dex
bpl MIRVcopyParameters
; modification (to make bullets "split away" and go different directions)
; bullet indexed 0 is in the middle
; bullet 1
clc
lda vx+1
adc #100
sta vx01+1
lda vx+2
adc #0
sta vx02+1
lda vx+3
adc #0
sta vx03+1
; bullet 2
sec
lda vx+1
sbc #100
sta vx01+2
lda vx+2
sbc #0
sta vx02+2
lda vx+3
sbc #0
sta vx03+2
; bullet 3
clc
lda vx+1
adc #200
sta vx01+3
lda vx+2
adc #0
sta vx02+3
lda vx+3
adc #0
sta vx03+3
; bullet 4
sec
lda vx+1
sbc #200
sta vx01+4
lda vx+2
sbc #0
sta vx02+4
lda vx+3
sbc #0
sta vx03+4
; clearing ranges of soil down registers
mwa #screenwidth RangeLeft
lda #0
sta RangeRight
sta RangeRight+1
ldx #$FF ; it will turn 0 in a moment anyway
stx MirvMissileCounter
mrLoopi
inc MirvMissileCounter
lda MirvMissileCounter
cmp #5
bne mrLoopix
mva #0 MirvMissileCounter
mrLoopix
ldx MirvMissileCounter
; Y changes only for bullet number 0
; because rest of the bullets have the same Y (height)
bne MIRVdoNotChangeY
; Y is the same for all falling bullets
;ytraj=ytraj-vy (skipping least significant byte of vy)
sec
lda ytraj
sbc vy+1
sta ytraj
lda ytraj+1
sbc vy+2
sta ytraj+1
lda ytraj+2
sbc vy+3
sta ytraj+2
;vy=vy-g (also without least significant byte of vy)
sec
lda vy+1
sbc gravity
sta vy+1
lda vy+2
sbc #0
sta vy+2
lda vy+3
sbc #0
sta vy+3
; 2 waits for 5 bullets
wait
wait
MIRVdoNotChangeY
lda MirvDown,x ; if bullet is already down we go with the next one
jne MIRVnextBullet
lda goleft
bne mrFlightLeft
clc ;xtraj=xtraj+vx (skipping the least significant byte of vx)
lda xtraj00,x ;and here of course Flight to the right
adc vx01,x
sta xtraj00,x
lda xtraj01,x
adc vx02,x
sta xtraj01,x
lda xtraj02,x
adc vx03,x
sta xtraj02,x
jmp mrskip07 ;skip substracting for Flight to the left
mrFlightLeft
sec ;xtraj=xtraj-vx (skipping the least significant byte of vx)
lda xtraj00,x ;here of course Flight to the left
sbc vx01,x
sta xtraj00,x
lda xtraj01,x
sbc vx02,x
sta xtraj01,x
lda xtraj02,x
sbc vx03,x
sta xtraj02,x
mrskip07
;vx=vx-Wind (also without least significan byte of vx)
lda goleft
bne mrFlightsLeft ;blow on bullet flighting left
lda WindOrientation
bne mrWindToLeft
beq mrLWindToLeft
mrFlightsLeft
lda WindOrientation
beq mrLWindToRight
mrLWindToLeft
; here Wind to right, bullet goes right as well, so vx=vx+Wind
; here Wind to left, bullet goes left as well, so vx=vx+Wind
clc
lda vx00,x
adc Wind
sta vx00,x
lda vx01,x
adc Wind+1
sta vx01,x
lda vx02,x
adc #0
sta vx02,x
lda vx03,x
adc #0
sta vx03,x
Jmp mrskip08
mrWindToLeft
mrLWindToRight
;Wind to left, bullet right, so vx=vx-Wind
;Wind to right, bullet left, so vx=vx-Wind
sec
lda vx00,x
sbc Wind
sta vx00,x
lda vx01,x
sbc Wind+1
sta vx01,x
lda vx02,x
sbc #0
sta vx02,x
lda vx03,x
sbc #0
sta vx03,x
mrskip08
; isn't it over the screen????
lda ytraj+2 ;attention! this checks getting out of the screen through bottom
bmi MIRVcheckX ;but not that accurately....
lda ytraj+1
cmp #screenheight
jcs mrEndOfFlight ; if smaller than screenheight then continue (and it will always fall down...)
MIRVcheckX
lda xtraj02,x
cmp #>screenwidth
beq MIRVcheckLowerX
bcc MIRVcheckCollision
; it's over the screen horizontally (to the left or right)
mwa #0 xdraw
mva #screenheight-1 ydraw
jsr unPlot.unPlotAfterX
jmp mrLoopi
MIRVcheckLowerX
lda xtraj01,x
cmp #<screenwidth
bcc MIRVcheckCollision
; it's over the screen horizontally (to the left or right)
mwa #0 xdraw
mva #screenheight-1 ydraw
jsr unPlot.unPlotAfterX
jmp mrLoopi
MIRVcheckCollision
; checking the collision!
lda ytraj+2
bne mrSkipCollisionCheck
; checking works only with xtraj so copy there all we need
lda xtraj01,x
sta xtraj+1
lda xtraj02,x
sta xtraj+2
mva #0 HitFlag
jsr CheckCollisionWithTank
ldx MirvMissileCounter
lda HitFlag
bne mrHit
;mwa xtraj01 temp
clc
lda xtraj01,x
adc #<mountaintable
sta temp
lda xtraj02,x
adc #>mountaintable
sta temp+1
; adw mountaintable --- it does not work!!!!!!!! and should! (OMC bug?) #temp
ldy #0
lda ytraj+1
cmp (temp),y
bcs mrHit
mrSkipCollisionCheck
;mwa xtraj01 xdraw
lda xtraj01,x
sta xdraw
lda xtraj02,x
sta xdraw+1
mwa ytraj+1 ydraw
jsr unPlot.unPlotAfterX
ldx MirvMissileCounter
jne mrLoopi
jsr PlotPointer ; pointer only for bullet nr 0
jmp mrLoopi
mrHit
; we have to make unPlot over the screen (to initialise it)
; before actual explosion
mwa #0 xdraw
mva #screenheight-1 ydraw
jsr unPlot.unPlotAfterX
ldx MirvMissileCounter
ldy #0
; concurrent moving xtraj+1 -> xdraw and calculating temp
clc
lda xtraj01,x
sta xdraw
adc #<mountaintable
sta temp
lda xtraj02,x
sta xdraw+1
adc #>mountaintable
sta temp+1
lda (temp),y
sta ydraw
sty ydraw+1 ;we know that y=0
jsr missile ; explode ....
mrEndOfFlight
ldx MirvMissileCounter
mwa #0 xdraw
mva #screenheight-1 ydraw
jsr unPlot.unPlotAfterX
ldx MirvMissileCounter
lda #1
sta MirvDown,x
MIRVnextBullet
; checking if all bullets already fallen down
ldx #4
MIRVcheckIfEnd
lda MirvDown,x
beq MIRVstillNotAll
dex
bpl MIRVcheckIfEnd
bmi MIRValreadyAll
MIRVstillNotAll
jmp mrLoopi
MIRValreadyAll
mwa xdraw xcircle ; we must store them (for a while)
mva ydraw ycircle ; xdraw and ydraw
mwa #0 xdraw
mva #screenheight-1 ydraw
ldx MirvMissileCounter
jsr unPlot.unPlotAfterX
mwa xcircle xdraw
mva ycircle ydraw
; we must do it manually because of the VOID pointer
;first clean the offensive text...
ldy TankNr
mva #0 plot4x4color
jsr DisplayOffensiveTextNr
; temporary removing tanks from the screen (otherwise they will fall down with soil)
mva TankNr tempor2
mva #1 Erase
jsr drawtanks
mva tempor2 TankNr
mva #0 Erase
jsr SoilDown2
mva #1 HitFlag
;jsr drawtanks
rts
.endp
; -------------------------------------------------
CheckCollisionWithTank .proc
; -------------------------------------------------
ldx #0
CheckCollisionWithTankLoop
lda xtankstableH,x
cmp xtraj+2
bne Condition01
lda xtankstableL,x
cmp xtraj+1
Condition01
bcs LeftFromTheTank ;add 8 double byte
clc
adc #8
tay
lda xtankstableH,x
adc #0
cmp xtraj+2
bne Condition02
cpy xtraj+1
Condition02
bcc RightFromTheTank
lda ytankstable,x
cmp ytraj+1 ; check range
bcc BelowTheTank ;(ytankstable,ytankstable+3)
sbc #4
cmp ytraj+1
bcs OverTheTank
mva #1 HitFlag
mwa xtraj+1 XHit
mwa ytraj+1 YHit
rts ; in X there is an index of the hit tank
RightFromTheTank
LeftFromTheTank
OverTheTank
BelowTheTank
inx
cpx NumberOfPlayers
bne CheckCollisionWithTankLoop
rts
.endp
;--------------------------------------------------
CalculateExplosionRange0
;--------------------------------------------------
;the same as below, but without summing up
;(for the first or single explosion)
;zero soil fall out ranges
mwa #screenwidth RangeLeft
lda #0
sta RangeRight
sta RangeRight+1
mva #11 ExplosionRadius
;--------------------------------------------------
CalculateExplosionRange .proc
;--------------------------------------------------
;calculates total horizontal range of explosion by
;"summing up" ranges of all separate explosions
adw xdraw ExplosionRadius WeaponRangeRight
cpw WeaponRangeRight #screenwidth-1
bcc NotOutOfTheScreenRight
mwa #screenwidth-1 WeaponRangeRight
NotOutOfTheScreenRight
sbw xdraw ExplosionRadius WeaponRangeLeft
lda WeaponRangeLeft+1
bpl NotOutOfTheScreenLeft
lda #0
sta WeaponRangeLeft
sta WeaponRangeLeft+1
NotOutOfTheScreenLeft
cpw RangeLeft WeaponRangeLeft
bcc CheckRangeRight
mwa WeaponRangeLeft RangeLeft
CheckRangeRight
cpw RangeRight WeaponRangeRight
bcs RangesChecked
mwa WeaponRangeRight RangeRight
RangesChecked
rts
.endp
;--------------------------------------------------
DecreaseWeaponAfterShoot .proc
;--------------------------------------------------
ldx TankNr
lda ActiveWeapon,x
jsr DecreaseWeapon
; and here we have amount of possessed ammo for given weapon
cmp #0
bne AmmunitionDecreased
lda #0 ;if ammo for given weapon ends
sta ActiveWeapon,x ;then set to default weapon (baby missile)
AmmunitionDecreased
lda #99
ldy #0
sta (weaponPointer),y ;baby missile - always 99 pieces
;there is a good value in temp after jsr DecreaseWeapon
rts
.endp
;--------------------------------------------------
DecreaseWeapon .proc
; in: A <-- Weapon number, TankNr
; decreases 1 bullet from a weapon(A) of tank(TankNr)
;--------------------------------------------------
jsr HowManyBullets
sec
sbc #1
sta (weaponPointer),y ; we have good values after HowManyBullets
rts
.endp
;--------------------------------------------------
HowManyBullets .proc
; in: A <-- Weapon number, TankNr
; out: A <-- How many bullets in the weapon
; how many bullets weapon of tank(TankNr) has, Result w A
;--------------------------------------------------
tay
ldx TankNr
lda TanksWeaponsTableL,x
sta weaponPointer
lda TanksWeaponsTableH,x
sta weaponPointer+1
;ldy #$35 ; parachute
lda (weaponPointer),y ; and we have number of bullets in A
rts
.endp
.ENDIF