mirror of
https://github.com/pkali/scorch_src.git
synced 2026-05-20 22:34:21 +02:00
1468 lines
28 KiB
NASM
1468 lines
28 KiB
NASM
; @com.wudsn.ide.asm.mainsourcefile=scorch.asm
|
|
|
|
.IF *>0 ;this is a trick that prevents compiling this file alone
|
|
|
|
|
|
;--------------------------------------------------
|
|
draw .proc ;;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
|
|
bne DrawOutOfTheScreen
|
|
lda ybyte+1
|
|
beq 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
|
|
jsr DrawJumpPad
|
|
; end of the special PLOT for DRAW
|
|
|
|
; XI=XI+1
|
|
; UNTIL XI=XK
|
|
inw XI
|
|
cpw XI XK
|
|
jne DrawLoop
|
|
|
|
EndOfDraw
|
|
mwa xtempDRAW xdraw
|
|
mva ytempDRAW ydraw
|
|
rts
|
|
.endp
|
|
|
|
;-------------JumpPad-------------
|
|
DrawJumpPad
|
|
jmp (DrawJumpAddr)
|
|
Drawplot
|
|
jmp plot
|
|
DrawLen
|
|
inw LineLength
|
|
rts
|
|
;-------------JumpPad-------------
|
|
|
|
DrawCheck .proc
|
|
lda tracerflag
|
|
ora SmokeTracerFlag
|
|
yestrace
|
|
beq notrace
|
|
jsr plot
|
|
notrace
|
|
;aftertrace
|
|
lda HitFlag
|
|
bne StopHitChecking
|
|
|
|
CheckCollisionDraw
|
|
; checking collision!
|
|
lda ydraw+1
|
|
bne StopHitChecking
|
|
|
|
jsr CheckCollisionWithTank
|
|
lda HitFlag
|
|
bne StopHitChecking
|
|
|
|
mwa xdraw temp
|
|
adw temp #mountaintable
|
|
|
|
ldy #0
|
|
lda ydraw
|
|
cmp (temp),y
|
|
bcc StopHitChecking
|
|
|
|
mva #1 HitFlag
|
|
mwa xdraw XHit
|
|
mwa ydraw YHit
|
|
|
|
|
|
StopHitChecking
|
|
rts
|
|
.endp
|
|
|
|
;--------------------------------------------------
|
|
circle .proc ;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
|
|
mva 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
|
|
mva 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
|
|
jsr plot
|
|
|
|
sec
|
|
lda ycircle
|
|
sbc YC
|
|
sta ydraw
|
|
jsr plot
|
|
|
|
sec
|
|
lda xcircle
|
|
sbc XC
|
|
sta xdraw
|
|
lda xcircle+1
|
|
sbc #0
|
|
sta xdraw+1
|
|
jsr plot
|
|
|
|
lda tempcir
|
|
sta ydraw
|
|
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
|
|
jsr plot
|
|
|
|
sec
|
|
lda ycircle
|
|
sbc xC
|
|
sta ydraw
|
|
jsr plot
|
|
|
|
sec
|
|
lda xcircle
|
|
sbc yC
|
|
sta xdraw
|
|
lda xcircle+1
|
|
sbc #0
|
|
sta xdraw+1
|
|
jsr plot
|
|
|
|
lda tempcir
|
|
sta ydraw
|
|
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
|
|
;-------------------------------------------------
|
|
drawtanks
|
|
;-------------------------------------------------
|
|
|
|
|
|
lda tanknr
|
|
pha
|
|
ldx #$00
|
|
stx tanknr
|
|
|
|
DrawNextTank
|
|
jsr drawtanknr
|
|
inc tanknr
|
|
ldx tanknr
|
|
Cpx NumberOfPlayers
|
|
bne DrawNextTank
|
|
|
|
pla
|
|
sta tankNr
|
|
|
|
rts
|
|
;---------
|
|
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
|
|
|
|
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
|
|
DoNotDrawTankNr
|
|
rts
|
|
|
|
;--------------------------------------------------
|
|
.proc drawmountains
|
|
;--------------------------------------------------
|
|
|
|
mwa #0 xdraw
|
|
mwa #mountaintable modify
|
|
mva #1 color
|
|
|
|
drawmountainsloop
|
|
ldy #0
|
|
lda (modify),y
|
|
cmp #screenheight
|
|
beq NoMountain
|
|
sta ydraw
|
|
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
|
|
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
|
|
mva #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
|
|
|
|
loopdraw
|
|
|
|
lda (xbyte),y
|
|
and bittable2,x
|
|
sta (xbyte),y
|
|
IntoDraw
|
|
adw xbyte #screenBytes
|
|
dec tempbyte01
|
|
bne loopdraw
|
|
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
|
|
lsr mask1
|
|
ror mask2
|
|
lsr mask1+1
|
|
ror mask2+1
|
|
lsr mask1+2
|
|
ror mask2+2
|
|
lsr mask1+3
|
|
ror mask2+3
|
|
lsr mask1+4
|
|
ror mask2+4
|
|
lsr mask1+5
|
|
ror mask2+5
|
|
lsr mask1+6
|
|
ror mask2+6
|
|
lsr mask1+7
|
|
ror mask2+7
|
|
sec
|
|
ror char1
|
|
ror char2
|
|
sec
|
|
ror char1+1
|
|
ror char2+1
|
|
sec
|
|
ror char1+2
|
|
ror char2+2
|
|
sec
|
|
ror char1+3
|
|
ror char2+3
|
|
sec
|
|
ror char1+4
|
|
ror char2+4
|
|
sec
|
|
ror char1+5
|
|
ror char2+5
|
|
sec
|
|
ror char1+6
|
|
ror char2+6
|
|
sec
|
|
ror char1+7
|
|
ror char2+7
|
|
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
|
|
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
|
|
rol
|
|
rol
|
|
rol
|
|
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
|
|
lsr mask1
|
|
ror mask2
|
|
lsr mask1+1
|
|
ror mask2+1
|
|
lsr mask1+2
|
|
ror mask2+2
|
|
lsr mask1+3
|
|
ror mask2+3
|
|
sec
|
|
ror char1
|
|
ror char2
|
|
sec
|
|
ror char1+1
|
|
ror char2+1
|
|
sec
|
|
ror char1+2
|
|
ror char2+2
|
|
sec
|
|
ror char1+3
|
|
ror char2+3
|
|
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 |