mirror of
https://github.com/pkali/scorch_src.git
synced 2026-05-21 14:49:46 +02:00
91b613f166
Only for test. Now all players has active Shield with energy (99) and witch parachute before game. Alo added display name of active defensive weapon on statusbar, and some fixes.
1543 lines
29 KiB
NASM
1543 lines
29 KiB
NASM
; @com.wudsn.ide.asm.mainsourcefile=scorch.asm
|
|
|
|
.IF *>0 ;this is a trick that prevents compiling this file alone
|
|
|
|
|
|
;--------------------------------------------------
|
|
.proc draw ;;fuxxing good draw :)
|
|
;--------------------------------------------------
|
|
;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 #0 LineLength
|
|
mwa xdraw xtempDRAW
|
|
mwa ydraw ytempDRAW
|
|
|
|
; if line goes our of the screen we are not drawing it, but...
|
|
|
|
cpw xdraw #screenwidth
|
|
bcs DrawOutOfTheScreen
|
|
cpw xbyte #screenwidth
|
|
bcs DrawOutOfTheScreen
|
|
;cpw ydraw #screenheight
|
|
;bcs DrawOutOfTheScreen
|
|
;cpw ybyte #screenheight
|
|
;bcc DrawOnTheScreen
|
|
lda ydraw+1
|
|
bmi DrawOutOfTheScreen
|
|
lda ybyte+1
|
|
bpl DrawOnTheScreen
|
|
DrawOutOfTheScreen
|
|
;jsr DrawJumpPad
|
|
rts
|
|
DrawOnTheScreen
|
|
; constant parameters
|
|
; XI=0 ,YI=0
|
|
lda #0
|
|
sta XI
|
|
sta XI+1
|
|
sta YI
|
|
sta YI+1
|
|
|
|
; setting the direction controll bits
|
|
cpw ydraw ybyte
|
|
bcc LineDown
|
|
; here one line up
|
|
; we are setting bit 0
|
|
mva #1 HowToDraw ;here we can because it's first operation
|
|
; we are subctracting Yend from Ybegin (reverse order)
|
|
; DY=YI-YK
|
|
sbw ydraw ybyte DY
|
|
jmp CheckDirectionX
|
|
LineDown
|
|
; one line down here
|
|
; we are setting bit 0
|
|
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
|
|
; we set bit 1
|
|
|
|
lda HowToDraw
|
|
ora #$02
|
|
sta HowToDraw
|
|
; substract Xend from Xbegin (reverse)
|
|
; DX=XI-XK
|
|
sbw xdraw xbyte DX
|
|
jmp CheckDirectionFactor
|
|
LineRight
|
|
; here goes one line to the right
|
|
; we clear bit 0
|
|
; we can do nothing because the bit is cleared!
|
|
|
|
;lda HowToDraw
|
|
;and #$FD
|
|
;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
|
|
|
|
bcc SwapXY
|
|
; 'a' factor is fire, so we copy parameters
|
|
; XK=DX
|
|
mwa DX XK
|
|
; and clearing bit 2
|
|
; and bit 2 clear
|
|
; (is not needed because already cleared)
|
|
;lda HowToDraw
|
|
;and #$FB
|
|
;sta HowToDraw
|
|
jmp LineParametersReady
|
|
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
|
|
mwa DY XK
|
|
mwa DX DY
|
|
mwa XK DX
|
|
|
|
; and let's set bit 2
|
|
lda HowToDraw
|
|
ora #$04
|
|
sta HowToDraw
|
|
LineParametersReady
|
|
; let's check if length is not zero
|
|
lda DX
|
|
ora DX+1
|
|
ora DY
|
|
ora DY+1
|
|
jeq EndOfDraw
|
|
|
|
; 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)
|
|
|
|
|
|
lda HowToDraw
|
|
and #$04
|
|
bne SwappedXY
|
|
mwa XI temp
|
|
mwa YI temp2
|
|
jmp CheckPlotY
|
|
SwappedXY
|
|
mwa XI temp2
|
|
mwa YI temp
|
|
CheckPlotY
|
|
lda HowToDraw
|
|
and #01
|
|
bne 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
|
|
lda HowToDraw
|
|
and #02
|
|
bne 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
|
|
bne 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
|
|
;mwa ydraw YHit
|
|
mva #1 HitFlag
|
|
StopHitChecking
|
|
jmp ContinueDraw
|
|
@
|
|
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
|
|
|
|
;--------------------------------------------------
|
|
.proc circle ;fxxxing good circle drawing :)
|
|
;--------------------------------------------------
|
|
;Turbo Basic source
|
|
; R=30
|
|
; XC=0:YC=R
|
|
; FX=0:FY=8*R:FS=4*R+3
|
|
; WHILE FX<FY
|
|
; splot8 //splot8 are eight plotz around the circle
|
|
; XC=XC+1
|
|
; FX=FX+8
|
|
; IF FS>0
|
|
; FS=FS-FX-4
|
|
; ELSE
|
|
; YC=YC-1
|
|
; FY=FY-8
|
|
; FS=FS-FX-4+FY
|
|
; ENDIF
|
|
; WEND
|
|
; splot8
|
|
|
|
mwa xdraw xcircle
|
|
mwa ydraw ycircle
|
|
|
|
mwa #0 xc
|
|
mva radius yc
|
|
mva #0 fx
|
|
mva radius fy
|
|
asl FY
|
|
asl FY
|
|
mva FY FS
|
|
asl FY
|
|
clc
|
|
lda FS
|
|
adc #3
|
|
sta FS
|
|
|
|
circleloop
|
|
lda FX
|
|
cmp FY
|
|
bcs endcircleloop
|
|
jsr splot8
|
|
inc XC
|
|
|
|
clc
|
|
lda FX
|
|
adc #8
|
|
sta FX
|
|
|
|
lda FS
|
|
beq else01
|
|
bmi else01
|
|
sec
|
|
sbc FX
|
|
sbc #4
|
|
sta FS
|
|
jmp endif01
|
|
else01
|
|
dec YC
|
|
sec
|
|
lda FY
|
|
sbc #8
|
|
sta FY
|
|
|
|
lda FS
|
|
sec
|
|
sbc FX
|
|
sbc #4
|
|
clc
|
|
adc FY
|
|
sta FS
|
|
endif01
|
|
jmp circleloop
|
|
endcircleloop
|
|
|
|
jsr splot8
|
|
|
|
mwa xcircle xdraw
|
|
mwa ycircle ydraw
|
|
rts
|
|
.endp
|
|
;----
|
|
splot8 .proc
|
|
; plot xcircle+XC,ycircle+YC
|
|
; plot xcircle+XC,ycircle-YC
|
|
; plot xcircle-XC,ycircle-YC
|
|
; plot xcircle-XC,ycircle+YC
|
|
|
|
; plot xcircle+YC,ycircle+XC
|
|
; plot xcircle+YC,ycircle-XC
|
|
; plot xcircle-YC,ycircle-XC
|
|
; plot xcircle-YC,ycircle+XC
|
|
|
|
clc
|
|
lda xcircle
|
|
adc XC
|
|
sta xdraw
|
|
lda xcircle+1
|
|
adc #0
|
|
sta xdraw+1
|
|
;clc
|
|
lda ycircle
|
|
adc YC
|
|
sta ydraw
|
|
sta tempcir
|
|
lda ycircle+1
|
|
adc #$00
|
|
sta ydraw+1
|
|
sta tempcir+1
|
|
jsr plot
|
|
|
|
sec
|
|
lda ycircle
|
|
sbc YC
|
|
sta ydraw
|
|
lda ycircle+1
|
|
sbc #$00
|
|
sta ydraw+1
|
|
jsr plot
|
|
|
|
sec
|
|
lda xcircle
|
|
sbc XC
|
|
sta xdraw
|
|
lda xcircle+1
|
|
sbc #0
|
|
sta xdraw+1
|
|
jsr plot
|
|
|
|
lda tempcir
|
|
sta ydraw
|
|
lda tempcir+1
|
|
sta ydraw+1
|
|
jsr plot
|
|
;---
|
|
clc
|
|
lda xcircle
|
|
adc yC
|
|
sta xdraw
|
|
lda xcircle+1
|
|
adc #0
|
|
sta xdraw+1
|
|
;clc
|
|
lda ycircle
|
|
adc xC
|
|
sta ydraw
|
|
sta tempcir
|
|
lda ycircle+1
|
|
adc #$00
|
|
sta ydraw+1
|
|
sta tempcir+1
|
|
jsr plot
|
|
|
|
sec
|
|
lda ycircle
|
|
sbc xC
|
|
sta ydraw
|
|
lda ycircle+1
|
|
sbc #$00
|
|
sta ydraw+1
|
|
jsr plot
|
|
|
|
sec
|
|
lda xcircle
|
|
sbc yC
|
|
sta xdraw
|
|
lda xcircle+1
|
|
sbc #0
|
|
sta xdraw+1
|
|
jsr plot
|
|
|
|
lda tempcir
|
|
sta ydraw
|
|
lda tempcir+1
|
|
sta ydraw+1
|
|
jsr plot
|
|
|
|
RTS
|
|
.endp
|
|
|
|
;--------------------------------------------------
|
|
clearscreen .proc
|
|
;--------------------------------------------------
|
|
|
|
lda #$ff
|
|
ldx #0
|
|
@
|
|
:31 sta display+($100*#),x
|
|
sta display+$1e50,x ; this is so no space outside of the screen is cleared
|
|
; of course we are clearing $100 instead of $50, but who cares :]
|
|
inx
|
|
bne @-
|
|
rts
|
|
.endp
|
|
;-------------------------------*------------------
|
|
placetanks .proc
|
|
;--------------------------------------------------
|
|
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
|
|
mva #0 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
|
|
sta xtankstableL,x
|
|
bcs NotHigherByte01
|
|
dec xtankstableH,x
|
|
NotHigherByte01
|
|
|
|
; and clear lowest bit to be sure that the X coordinate is even
|
|
; (this is to have P/M background look nice)
|
|
lda xtankstableL,x
|
|
and #$fe
|
|
sta xtankstableL,x
|
|
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 drawtanks
|
|
;-------------------------------------------------
|
|
lda tanknr
|
|
pha
|
|
ldx #$00
|
|
stx tanknr
|
|
|
|
DrawNextTank
|
|
jsr drawtanknr
|
|
inc tanknr
|
|
ldx tanknr
|
|
Cpx NumberOfPlayers
|
|
bne DrawNextTank
|
|
|
|
pla
|
|
sta tankNr
|
|
|
|
rts
|
|
.endp
|
|
;---------
|
|
.proc DrawTankNr
|
|
ldx tankNr
|
|
; let's check the energy
|
|
lda eXistenZ,x
|
|
bne SkipRemovigPM ; if energy=0 then no tank
|
|
|
|
; hide P/M
|
|
lda #0
|
|
sta hposp0,x
|
|
jmp DoNotDrawTankNr
|
|
SkipRemovigPM
|
|
|
|
|
|
lda AngleTable,x
|
|
bmi AngleToLeft01
|
|
lda #90
|
|
sec
|
|
sbc AngleTable,x
|
|
tay
|
|
lda BarrelTableR,y
|
|
jmp CharacterAlreadyKnown
|
|
AngleToLeft01
|
|
sec
|
|
sbc #(255-90)
|
|
tay
|
|
lda BarrelTableL,y
|
|
CharacterAlreadyKnown
|
|
sta CharCode
|
|
DrawTankNrX
|
|
ldx tanknr
|
|
lda xtankstableL,x
|
|
sta xdraw
|
|
lda xtankstableH,x
|
|
sta xdraw+1
|
|
lda ytankstable,x
|
|
sta ydraw
|
|
mva #0 ydraw+1
|
|
|
|
jsr TypeChar
|
|
|
|
; now P/M graphics on the screen (only for 5 tanks)
|
|
; horizontal position
|
|
mwa xdraw xbyte
|
|
ldx tanknr
|
|
cpx #$5
|
|
bcs NoPlayerMissile
|
|
rorw xbyte ; divide by 2 (carry does not matter)
|
|
lda xbyte
|
|
clc
|
|
adc #$24 ; P/M to graphics offset
|
|
cpx #$4 ; 5th tank are joined missiles and offset is defferent
|
|
bne NoMissile
|
|
clc
|
|
adc #$0C
|
|
NoMissile
|
|
sta hposp0,x
|
|
; vertical position
|
|
lda pmtableL,x
|
|
sta xbyte
|
|
lda pmtableH,x
|
|
sta xbyte+1
|
|
|
|
; calculate start position of the tank
|
|
lda ydraw
|
|
clc
|
|
adc #PMOffset
|
|
sta temp
|
|
; clear sprite and put 3 lines on the tank at the same time
|
|
ldy #$00
|
|
tya
|
|
ClearPM
|
|
cpy temp
|
|
bne ZeroesToGo
|
|
lda #$03 ; (2 bits set) we set on two pixels in three lines
|
|
sta (xbyte),y
|
|
dey
|
|
sta (xbyte),y
|
|
dey
|
|
sta (xbyte),y
|
|
dey
|
|
lda #$00
|
|
ZeroesToGo
|
|
sta (xbyte),y
|
|
dey
|
|
bne ClearPM
|
|
NoPlayerMissile
|
|
; draw defensive weapons like shield ( tank number in X )
|
|
; in xdraw, ydraw we have coordinates left LOWER corner of Tank char
|
|
lda ActiveDefenceWeapon,x
|
|
cmp #56 ; one shot shield activation
|
|
beq ShieldDraw
|
|
cmp #57 ; shield with energy and parachute activation
|
|
beq ShieldDraw
|
|
cmp #58 ; shield with energy activation
|
|
bne NoShieldDraw
|
|
ShieldDraw
|
|
jsr DrawTankShield.DrawInPosition
|
|
NoShieldDraw
|
|
DoNotDrawTankNr
|
|
rts
|
|
.endp
|
|
|
|
; -------------------------------------
|
|
.proc FlashTank
|
|
; -------------------------------------
|
|
; number of blinking tank in TankNr
|
|
mva #18 fs ; temp, how many times flash the tank
|
|
tankflash_loop
|
|
lda CONSOL ; turbo mode
|
|
cmp #6 ; START
|
|
sne:mva #1 fs ; finish it
|
|
mva #1 Erase
|
|
ldx TankNr
|
|
jsr DrawTankNr.SkipRemovigPM ; it's necessary becouse DrawTankNr skips tanks with no energy !
|
|
PAUSE 2
|
|
mva #0 Erase
|
|
ldx TankNr
|
|
jsr DrawTankNr.SkipRemovigPM
|
|
PAUSE 2
|
|
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!
|
|
;--------------------------------------------------
|
|
lda xtankstableL,x
|
|
sta xdraw
|
|
lda xtankstableH,x
|
|
sta xdraw+1
|
|
lda ytankstable,x
|
|
sta ydraw
|
|
mva #0 ydraw+1
|
|
DrawInPosition
|
|
mva #1 color
|
|
lda erase
|
|
beq ShieldVisible
|
|
dec color
|
|
ShieldVisible
|
|
sbw xdraw #$03 ; 3 pixels to left
|
|
; draw left vertical line of shield ( | )
|
|
mva #6 temp ; strange !!!
|
|
@
|
|
jsr plot
|
|
.nowarn dew ydraw
|
|
dec temp
|
|
bne @-
|
|
; draw left oblique line of shield ( / )
|
|
mva #4 temp
|
|
@
|
|
jsr plot
|
|
.nowarn dew ydraw
|
|
inw xdraw
|
|
dec temp
|
|
bne @-
|
|
; draw top horizontal line of shield ( _ )
|
|
mva #5 temp
|
|
@
|
|
jsr plot
|
|
inw xdraw
|
|
dec temp
|
|
bne @-
|
|
; draw right oblique line of shield ( \ )
|
|
mva #4 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
|
|
.endp
|
|
|
|
;--------------------------------------------------
|
|
.proc drawmountains
|
|
;--------------------------------------------------
|
|
mwa #0 xdraw
|
|
mwa #mountaintable modify
|
|
mva #1 color
|
|
|
|
drawmountainsloop
|
|
ldy #0
|
|
lda (modify),y
|
|
cmp #screenheight
|
|
beq NoMountain
|
|
sta ydraw
|
|
sty ydraw+1
|
|
jsr DrawLine
|
|
NoMountain
|
|
inw modify
|
|
inw xdraw
|
|
cpw xdraw #screenwidth
|
|
bne drawmountainsloop
|
|
rts
|
|
;--------------------------------------------------
|
|
drawmountainspixel
|
|
;--------------------------------------------------
|
|
mwa #0 xdraw
|
|
mwa #mountaintable modify
|
|
|
|
|
|
drawmountainspixelloop
|
|
ldy #0
|
|
lda (modify),y
|
|
sta ydraw
|
|
sty ydraw+1
|
|
jsr plot
|
|
inw modify
|
|
inw xdraw
|
|
cpw xdraw #screenwidth
|
|
bne drawmountainspixelloop
|
|
|
|
rts
|
|
.endp
|
|
;--------------------------------------------------
|
|
.proc SoilDown2
|
|
;--------------------------------------------------
|
|
|
|
; how it is supposed to work:
|
|
; first loop is looking for the highest pixels
|
|
; and fills with their Y coordinates both temporary tables
|
|
;
|
|
; second (main) loop works this way:
|
|
; sets end-of-soil-fall-down-flag to 1 ( IsEndOfTheFallFlag=1 )
|
|
; goes through the horizontal line checking if
|
|
; Y coordinate from the first table equals to height of the peak
|
|
; if so, it goes further
|
|
; if not:
|
|
; sets end-of-soil-fall-down-flag to 0
|
|
; increases Y from the first table
|
|
; if there is no pixel there it plots here and
|
|
; zeroes pixel from the second table and after that
|
|
; increases Y of the second table
|
|
; repeats with next pixels au to the end of the line
|
|
; if the flag is 0 then repeat the main loop
|
|
; and that's it :)
|
|
;
|
|
; I am sorry but after these 4 years I have no idea
|
|
; how it works. I have just translated Polish comment
|
|
; but I do not understand a word of it :)
|
|
; If you know how it works, please write here :))))
|
|
|
|
jsr PMoutofscreen
|
|
|
|
; First we look for highest pixels and fill with their coordinates
|
|
; both tables
|
|
|
|
mwa RangeLeft xdraw
|
|
adw RangeLeft #mountaintable temp
|
|
adw RangeLeft #mountaintable2 tempor2
|
|
|
|
NextColumn1
|
|
mwa #0 ydraw
|
|
NextPoint1
|
|
jsr point
|
|
beq StillNothing
|
|
ldy #0
|
|
lda ydraw
|
|
sta (tempor2),y
|
|
sta (temp),y
|
|
jmp FoundPeek1
|
|
StillNothing
|
|
inc ydraw
|
|
lda ydraw
|
|
cmp #screenheight
|
|
bne NextPoint1
|
|
; no pixels on whole column !!!
|
|
ldy #0
|
|
lda ydraw
|
|
sta (tempor2),y
|
|
sta (temp),y
|
|
jmp FoundPeek1
|
|
FoundPeek1
|
|
inw tempor2
|
|
inw temp
|
|
inw xdraw
|
|
;vcmp xdraw,screenwidth,NextColumn1
|
|
cpw xdraw RangeRight
|
|
bcc NextColumn1
|
|
beq NextColumn1
|
|
; we have both tables filled with starting values
|
|
|
|
; main loop starts here
|
|
MainFallout2
|
|
mwa RangeLeft xdraw
|
|
adw RangeLeft #mountaintable temp
|
|
adw RangeLeft #mountaintable2 tempor2
|
|
|
|
mva #1 IsEndOfTheFallFlag
|
|
FalloutOfLine
|
|
ldy #0
|
|
|
|
; is Y coordinate from the first table
|
|
; equal to peak height, if so, go ahead
|
|
lda (tempor2),y
|
|
cmp #screenheight-1 ;cmp (temp),y
|
|
bcs ColumnIsReady
|
|
; in the other case there are things to be done
|
|
sty IsEndOfTheFallFlag ; flag to 0
|
|
; we are increasing Y in the first table
|
|
;lda (tempor2),y
|
|
clc
|
|
adc #1
|
|
sta (tempor2),y
|
|
; and checking if there is a pixel there
|
|
sta ydraw
|
|
jsr point
|
|
bne ThereIsPixelHere
|
|
; if no pixel we plot it
|
|
mva #1 color
|
|
jsr plot.MakePlot
|
|
; zeroing pixel from the second table
|
|
; and increase Y in second table
|
|
ldy #0
|
|
lda (temp),y
|
|
sta ydraw
|
|
lda (temp),y
|
|
clc
|
|
adc #1
|
|
sta (temp),y
|
|
sty color
|
|
jsr plot.MakePlot
|
|
mva #sfx_silencer sfx_effect
|
|
|
|
ThereIsPixelHere
|
|
ColumnIsReady
|
|
inw temp
|
|
inw tempor2
|
|
inw xdraw
|
|
;vcmp xdraw,screenwidth,FalloutOfLine
|
|
cpw xdraw RangeRight
|
|
bcc FalloutOfLine
|
|
beq FalloutOfLine
|
|
|
|
lda IsEndOfTheFallFlag
|
|
; we repeat untill at some point first table reaches
|
|
; level of the mountains
|
|
jeq MainFallout2
|
|
; now correct heights are in the mountaintable
|
|
mva #1 color
|
|
mva #sfx_silencer sfx_effect
|
|
rts
|
|
.endp
|
|
|
|
;--------------------------------------------------
|
|
.proc calculatemountains
|
|
;--------------------------------------------------
|
|
mwa #0 xdraw
|
|
|
|
; starting point
|
|
getrandomY ;getting random Y coordinate
|
|
sec
|
|
lda random
|
|
cmp #screenheight-(margin*4) ;it means that max line=199
|
|
bcs getrandomY
|
|
clc
|
|
adc #(margin*2)
|
|
sta ydraw
|
|
sta yfloat+1
|
|
mva #0 yfloat ;yfloat equals to e.g. 140.0
|
|
|
|
; how to make nice looking mountains?
|
|
; randomize points and join them with lines
|
|
; Here we do it simpler way - we randomize X (or deltaX)
|
|
; and "delta" (change of Y coordinate)
|
|
|
|
NextPart
|
|
lda random
|
|
sta delta ; it is after the dot (xxx.delta)
|
|
lda random
|
|
and #$03 ;(max delta)
|
|
sta delta+1 ; before the dot (delta+1.delta)
|
|
|
|
lda random
|
|
and #$01 ;random sign (+/- or up/down)
|
|
sta UpNdown
|
|
|
|
; theoretically we have here ready
|
|
; fixed-point delta value
|
|
; (-1*(UpNdown))*(delta+1.delta)
|
|
|
|
;loop drawing one line
|
|
|
|
ChangingDirection
|
|
lda random ;length of the line
|
|
and #$0f ;max line length
|
|
tax
|
|
inx
|
|
inx
|
|
inx
|
|
stx deltaX
|
|
|
|
OnePart
|
|
jsr placeTanks.CheckTank
|
|
; checks if at a given X coordinate
|
|
; is any tank and if so
|
|
; changes parameters of drawing
|
|
; to generate flat 8 pixels
|
|
; (it will be the place for the tank)
|
|
; it also stores Y position of the tank
|
|
adw xdraw #mountaintable modify
|
|
|
|
lda ydraw
|
|
ldy #0
|
|
sta (modify),y
|
|
|
|
; Up or Down
|
|
lda UpNdown
|
|
beq ToBottom
|
|
|
|
ToTop ;it means substracting
|
|
|
|
sbw yfloat delta
|
|
lda yfloat+1
|
|
cmp #margin
|
|
bcs @+
|
|
; if smaller than 10
|
|
ldx #$00
|
|
stx UpNdown
|
|
jmp @+
|
|
|
|
ToBottom
|
|
adw yfloat delta
|
|
lda yfloat+1
|
|
cmp #screenheight-margin
|
|
bcc @+
|
|
; if higher than screen
|
|
ldx #$01
|
|
stx UpNdown
|
|
@
|
|
sta ydraw
|
|
|
|
inw xdraw
|
|
|
|
cpw xdraw #screenwidth
|
|
beq EndDrawing
|
|
|
|
dec deltaX
|
|
bne OnePart
|
|
|
|
jmp NextPart
|
|
EndDrawing
|
|
|
|
rts
|
|
.endp
|
|
; ****************************************************
|
|
;--------------------------------------------------
|
|
.proc calculatemountains0
|
|
; Only for testing - makes ground flat (0 pixels)
|
|
; and places tanks on it
|
|
; remember to remove in final compilation :)
|
|
;--------------------------------------------------
|
|
mwa #0 xdraw
|
|
nextPointDrawing
|
|
adw xdraw #mountaintable modify
|
|
lda #screenheight
|
|
ldy #0
|
|
sta (modify),y
|
|
inw xdraw
|
|
cpw xdraw #screenwidth
|
|
bne nextPointDrawing
|
|
ldx NumberOfPlayers
|
|
dex
|
|
SetYofNextTank
|
|
lda #screenheight-1
|
|
sta ytankstable,x
|
|
dex
|
|
bpl SetYofNextTank
|
|
rts
|
|
.endp
|
|
; ****************************************************
|
|
|
|
; -----------------------------------------
|
|
.proc unPlot
|
|
; plots a point and saves the plotted byte, reverts the previous plot.
|
|
; -----------------------------------------
|
|
ldx #0 ; only one pixel
|
|
unPlotAfterX
|
|
stx WhichUnPlot
|
|
|
|
; first remake the oldie
|
|
lda oldplotL,x
|
|
sta oldplot
|
|
lda oldplotH,x
|
|
sta oldplot+1
|
|
|
|
lda oldply,x
|
|
tay
|
|
lda oldora,x
|
|
sta (oldplot),y
|
|
|
|
|
|
; is it not out of the screen ????
|
|
cpw ydraw #screenheight
|
|
jcc CheckX
|
|
mwa #0 ydraw
|
|
CheckX
|
|
cpw xdraw #screenwidth
|
|
jcs EndOfUnPlot
|
|
MakeUnPlot
|
|
; let's count coordinates taken from xdraw and ydraw
|
|
mwa xdraw xbyte
|
|
|
|
lda xbyte
|
|
and #$7
|
|
sta ybit
|
|
|
|
lsrw xbyte
|
|
rorw xbyte
|
|
rorw xbyte
|
|
;---
|
|
ldy xbyte
|
|
|
|
ldx WhichUnPlot
|
|
tya
|
|
sta oldply,x
|
|
|
|
|
|
ldx ydraw
|
|
lda linetableL,x
|
|
sta xbyte
|
|
sta oldplot
|
|
lda linetableH,x
|
|
sta xbyte+1
|
|
sta oldplot+1
|
|
ldx ybit
|
|
|
|
|
|
lda color
|
|
bne ClearUnPlot
|
|
|
|
;plotting here
|
|
lda (xbyte),y
|
|
sta OldOraTemp
|
|
ora bittable,x
|
|
sta (xbyte),y
|
|
jmp ContinueUnPlot
|
|
ClearUnPlot
|
|
lda (xbyte),y
|
|
sta OldOraTemp
|
|
and bittable2,x
|
|
sta (xbyte),y
|
|
ContinueUnPlot
|
|
ldx WhichUnPlot
|
|
lda OldOraTemp
|
|
sta oldora,x
|
|
lda oldplot
|
|
sta oldplotL,x
|
|
lda oldplot+1
|
|
sta oldplotH,x
|
|
; and now we must solve the problem of several plots
|
|
; in one byte
|
|
ldx #4
|
|
ldy WhichUnPlot
|
|
LetsCheckOverlapping
|
|
cpx WhichUnPlot
|
|
beq SkipThisPlot
|
|
lda oldplotL,x
|
|
cmp oldplotL,y
|
|
bne NotTheSamePlot
|
|
lda oldplotH,x
|
|
cmp oldplotH,y
|
|
bne NotTheSamePlot
|
|
lda oldply,x
|
|
cmp oldply,y
|
|
bne NotTheSamePlot
|
|
; the pixel is in the same byte so let's take correct contents
|
|
lda oldora,x
|
|
sta oldora,y
|
|
NotTheSamePlot
|
|
SkipThisPlot
|
|
dex
|
|
bpl LetsCheckOverlapping
|
|
EndOfUnPlot
|
|
rts
|
|
.endp
|
|
|
|
; -----------------------------------------
|
|
.proc plot ;plot (xdraw, ydraw, color)
|
|
; color == 1 --> put pixel
|
|
; color == 0 --> erase pixel
|
|
; this is one of the most important routines in the whole
|
|
; game. If you are going to speed up the game, start with
|
|
; plot - it is used by every single effect starting from explosions
|
|
; through line drawing and small text output!!!
|
|
; We tried to keep it clear and therefore it is far from
|
|
; optimal speed.
|
|
|
|
; -----------------------------------------
|
|
; is it not over the screen ???
|
|
cpw ydraw #(screenheight+1); changed for one additional line. cpw ydraw #(screenheight-1)
|
|
bcs unPlot.EndOfUnPlot
|
|
CheckX02
|
|
cpw xdraw #screenwidth
|
|
bcs EndOfPlot ;nearest RTS
|
|
MakePlot
|
|
; let's calculate coordinates from xdraw and ydraw
|
|
mwa xdraw xbyte
|
|
|
|
|
|
lda xbyte
|
|
and #$7
|
|
sta ybit
|
|
|
|
;xbyte = xbyte/8
|
|
lda xbyte
|
|
lsr xbyte+1
|
|
ror ;just one bit over 256. Max screenwidth = 512!!!
|
|
lsr
|
|
lsr
|
|
tay ;save
|
|
;---
|
|
ldx ydraw
|
|
lda linetableL,x
|
|
sta xbyte
|
|
lda linetableH,x
|
|
sta xbyte+1
|
|
|
|
ldx ybit
|
|
lda color
|
|
bne ClearPlot
|
|
|
|
lda (xbyte),y
|
|
ora bittable,x
|
|
sta (xbyte),y
|
|
EndOfPlot
|
|
rts
|
|
ClearPlot
|
|
lda (xbyte),y
|
|
and bittable2,x
|
|
sta (xbyte),y
|
|
rts
|
|
.endp
|
|
|
|
; -----------------------------------------
|
|
.proc point
|
|
; -----------------------------------------
|
|
; checks state of the pixel (coordinates in xdraw and ydraw)
|
|
; result is in A (zero or appropriate bit is set)
|
|
|
|
; let's calculate coordinates from xdraw and ydraw
|
|
mwa xdraw xbyte
|
|
|
|
lda xbyte
|
|
and #$7
|
|
sta ybit
|
|
|
|
;xbyte = xbyte/8
|
|
lda xbyte
|
|
lsr xbyte+1
|
|
ror ;just one bit over 256. Max screenwidht = 512!!!
|
|
lsr
|
|
lsr
|
|
tay ;save
|
|
;---
|
|
ldx ydraw
|
|
lda linetableL,x
|
|
sta xbyte
|
|
lda linetableH,x
|
|
sta xbyte+1
|
|
|
|
ldx ybit
|
|
|
|
lda (xbyte),y
|
|
and bittable,x
|
|
eor bittable,x
|
|
rts
|
|
.endp
|
|
|
|
;--------------------------------------------------
|
|
.proc DrawLine
|
|
;--------------------------------------------------
|
|
mva #0 ydraw+1
|
|
lda #screenheight
|
|
sec
|
|
sbc ydraw
|
|
sta tempbyte01
|
|
jsr plot.MakePlot
|
|
;rts
|
|
jmp IntoDraw ; jumps inside Draw routine
|
|
; because one pixel is already plotted
|
|
|
|
@
|
|
lda (xbyte),y
|
|
and bittable2,x
|
|
sta (xbyte),y
|
|
IntoDraw
|
|
adw xbyte #screenBytes
|
|
dec tempbyte01
|
|
bne @-
|
|
rts
|
|
.endp
|
|
|
|
; ------------------------------------------
|
|
.proc TypeChar
|
|
; puts char on the graphics screen
|
|
; in: CharCode
|
|
; in: left LOWER corner of the char coordinates (xdraw, ydraw)
|
|
;--------------------------------------------------
|
|
; char to the table
|
|
lda CharCode
|
|
sta fontind
|
|
lda #$00
|
|
sta fontind+1
|
|
; char intex times 8
|
|
aslw fontind
|
|
rolw fontind
|
|
rolw fontind
|
|
|
|
adw fontind #TankFont
|
|
|
|
; and 8 bytes to the table
|
|
ldy #7
|
|
CopyChar
|
|
lda (fontind),y
|
|
eor #$ff
|
|
sta char1,y
|
|
lda #$ff
|
|
sta char2,y
|
|
dey
|
|
bpl CopyChar
|
|
; and 8 subsequent bytes as a mask
|
|
adw fontind #8
|
|
ldy #7
|
|
CopyMask
|
|
lda (fontind),y
|
|
eor #$ff
|
|
sta mask1,y
|
|
lda #$00
|
|
sta mask2,y
|
|
dey
|
|
bpl CopyMask
|
|
|
|
; calculating coordinates from xdraw and ydraw
|
|
mwa xdraw xbyte
|
|
|
|
lda xbyte
|
|
and #$7
|
|
sta ybit
|
|
|
|
lsrw xbyte ; div 8
|
|
rorw xbyte
|
|
rorw xbyte
|
|
;---
|
|
ldy xbyte
|
|
|
|
lda ydraw ; y = y - 7 because left lower. shouldn't it be 8?
|
|
sec
|
|
sbc #7
|
|
tax
|
|
|
|
lda linetableL,x
|
|
sta xbyte
|
|
lda linetableH,x
|
|
sta xbyte+1
|
|
; mask preparation and character shifting
|
|
ldx ybit
|
|
beq MaskOK00
|
|
MakeMask00
|
|
.rept 8
|
|
lsr mask1+#
|
|
ror mask2+#
|
|
.endr
|
|
sec
|
|
.rept 8
|
|
ror char1+# ; in second (and next) lines we have C=1 - one SEC enough
|
|
ror char2+#
|
|
.endr
|
|
dex
|
|
bne MakeMask00
|
|
MaskOK00
|
|
; here x=0
|
|
lda Erase
|
|
beq CharLoopi ; it works, because x=0
|
|
lda #$ff
|
|
ldx #7
|
|
EmptyChar
|
|
sta char1,x
|
|
sta char2,x
|
|
dex
|
|
bpl EmptyChar
|
|
ldx #0
|
|
CharLoopi
|
|
lda (xbyte),y
|
|
ora mask1,x
|
|
and char1,x
|
|
sta (xbyte),y
|
|
iny
|
|
lda (xbyte),y
|
|
ora mask2,x
|
|
and char2,x
|
|
sta (xbyte),y
|
|
dey
|
|
adw xbyte #screenBytes
|
|
inx
|
|
cpx #8
|
|
bne CharLoopi
|
|
EndPutChar
|
|
rts
|
|
.endp
|
|
|
|
; ------------------------------------------
|
|
.proc PutChar4x4
|
|
; puts 4x4 pixels char on the graphics screen
|
|
; in: xdraw, ydraw (LOWER left corner of the char)
|
|
; in: CharCode4x4 (.sbyte)
|
|
; in: plot4x4color (0/1)
|
|
; all pixels are being drawn
|
|
; (empty and not empty)
|
|
;--------------------------------------------------
|
|
; cpw ydraw #(screenheight-4)
|
|
; jcs TypeChar.EndPutChar ;nearest RTS
|
|
; cpw xdraw #(screenwidth-4)
|
|
; jcs TypeChar.EndPutChar ;nearest RTS
|
|
; checks ommited.
|
|
lda plot4x4color
|
|
beq FontColor0
|
|
lda #$ff ; better option to check (plot4x4color = $00 or $ff)
|
|
sta plot4x4color
|
|
FontColor0
|
|
; char to the table
|
|
lda CharCode4x4
|
|
and #1
|
|
beq Upper4bits
|
|
lda #$ff ; better option to check (nibbler4x4 = $00 or $ff)
|
|
Upper4bits
|
|
sta nibbler4x4
|
|
lda CharCode4x4
|
|
lsr
|
|
sta fontind
|
|
lda #$00
|
|
sta fontind+1
|
|
|
|
adw fontind #font4x4
|
|
|
|
; and 4 bytes to the table
|
|
ldy #0
|
|
ldx #3
|
|
CopyChar
|
|
lda (fontind),y ; Y must be 0 !!!!
|
|
bit nibbler4x4
|
|
bpl GetUpper4bits
|
|
:4 rol
|
|
GetUpper4bits
|
|
ora #$0f
|
|
sta char1,x
|
|
lda #$ff
|
|
sta char2,x
|
|
; and 4 bytes as a mask
|
|
lda #$f0
|
|
sta mask1,x
|
|
lda #$00
|
|
sta mask2,x
|
|
adw fontind #32 ; next byte of 4x4 font
|
|
dex
|
|
bpl CopyChar
|
|
|
|
; calculating coordinates from xdraw and ydraw
|
|
mwa xdraw xbyte
|
|
|
|
lda xbyte
|
|
and #$7
|
|
sta ybit
|
|
|
|
lsrw xbyte ; div 8
|
|
rorw xbyte
|
|
rorw xbyte
|
|
;---
|
|
ldy xbyte
|
|
lda ydraw ; y = y - 3 because left lower.
|
|
sec
|
|
sbc #3
|
|
tax
|
|
|
|
lda linetableL,x
|
|
sta xbyte
|
|
lda linetableH,x
|
|
sta xbyte+1
|
|
; mask preparation and character shifting
|
|
ldx ybit
|
|
beq MaskOK01
|
|
MakeMask01
|
|
.rept 4
|
|
lsr mask1+#
|
|
ror mask2+#
|
|
.endr
|
|
sec
|
|
.rept 4
|
|
ror char1+# ; in second (and next) lines we have C=1 - one SEC enough
|
|
ror char2+#
|
|
.endr
|
|
dex
|
|
bne MakeMask01
|
|
MaskOK01
|
|
ldx #0
|
|
CharLoopi4x4
|
|
lda (xbyte),y
|
|
ora mask1,x
|
|
bit plot4x4color
|
|
bpl PutInColor0_1 ; only mask - no char
|
|
and char1,x
|
|
PutInColor0_1
|
|
sta (xbyte),y
|
|
iny
|
|
lda (xbyte),y
|
|
ora mask2,x
|
|
bit plot4x4color
|
|
bpl PutInColor0_2 ; only mask - no char
|
|
and char2,x
|
|
PutInColor0_2
|
|
sta (xbyte),y
|
|
dey
|
|
adw xbyte #screenBytes
|
|
inx
|
|
cpx #4
|
|
bne CharLoopi4x4
|
|
EndPut4x4
|
|
rts
|
|
.endp
|
|
|
|
.endif |