diff --git a/README.md b/README.md index 0bba3f0..1e90a99 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Contributors: - Adam (@6502adam) - font, ideas, QA - Bocianu (@bocianu) - important ideas, FujiNet implementation, QA - Emkay - splash screen music +- Fox (@pfusik) - plot and point optimization QA: Probabilitydragon, KrzysRog, Beeblebrox, EnderDude, lopezpb, Dracon, brad-colbert, archon800, Shaggy the Atarian @@ -47,6 +48,18 @@ With the advent of fujinet (https://fujinet.online/) we are thinking about makin ## Changes: +###### Build 148 +2022-07-17 +WHAT DOES THE FOX SAY? + +Fox (x0f, @pfusik) says plots and points can be optimized by 18 clock cycles each and thanks to his 6502 wizardry the game is noticeably nicer. Thank you! +Other changes: +- https://github.com/pkali/scorch_src/issues/99, https://github.com/pkali/scorch_src/issues/98 - tank number 6 has got a color now! No one is monochrome now! +- https://github.com/pkali/scorch_src/issues/110 much improved laser - previously it was almost useless, now it looks and works much better +- fixed an interesting roller bug +- Auto Defense angle fix +- multiple improvements in AI routines, preparation for the final opponents. + ###### Build 147 2022-07-10 LOST build. We were watching [LOST party](https://www.lostparty.pl/2022/) streams so maybe a little less done, but still some nice improvements. diff --git a/ai.asm b/ai.asm index 6c01bb6..ca248b2 100644 --- a/ai.asm +++ b/ai.asm @@ -186,15 +186,15 @@ EnoughEnergy beq NoUseDefensive lda (temp),y ; has address of TanksWeaponsTable beq @- - tya - ; activate defensive weapon - sta ActiveDefenceWeapon,x - lda DefensiveEnergy,y - sta ShieldEnergy,x ; decrease in inventory clc sbc #1 sta (temp),y ; has address of TanksWeaponsTable + ; activate defensive weapon + tya ; number of selectet defensive weapon + sta ActiveDefenceWeapon,x + lda DefensiveEnergy,y + sta ShieldEnergy,x NoUseDefensive DefensiveInUse firstShoot @@ -299,15 +299,15 @@ AngleTable ; 16 bytes ;ba w $348b L$3350 beq NoUseDefensive lda (temp),y ; has address of TanksWeaponsTable beq @- - tya - ; activate defensive weapon - sta ActiveDefenceWeapon,x - lda DefensiveEnergy,y - sta ShieldEnergy,x ; decrease in inventory clc sbc #1 - sta (temp),y + sta (temp),y ; has address of TanksWeaponsTable + ; activate defensive weapon + tya ; number of selectet defensive weapon + sta ActiveDefenceWeapon,x + lda DefensiveEnergy,y + sta ShieldEnergy,x DefensiveInUse NoUseDefensive ; Toosser is like Poolshark but allways uses defensives diff --git a/constants.asm b/constants.asm index c6a4c10..7721be5 100644 --- a/constants.asm +++ b/constants.asm @@ -5,14 +5,12 @@ ;=================================================================================== ;==========================CONSTANT TABLES, do not erase!=========================== ;=================================================================================== -TankColoursTable .BYTE $88,$cc,$38,$1c,$6a,$02 -TankStatusColoursTable .BYTE $80,$c0,$30,$10,$60,$00 +TankColoursTable .BYTE $86,$46,$c6,$28,$c6,$ee +TankStatusColoursTable .BYTE $80,$40,$c4,$20,$c0,$e4 dliColorsBack :10 .by $02,$00 dliColorsFore .by $0a -TextBackgroundColor = $02 ; REAL constans - use: LDA #TextBackgroundColor -TextForegroundColor = $0c CashOptionL ;(one zero less than on the screen) .by 0,<200,<800,<1200,<2000 CashOptionH @@ -59,18 +57,20 @@ lineClear dta d" ", $ff ;----------- -pmtableL ; addressess of the P/M memory for 5 tanks (6th is without P/M background) +pmtableL ; addressess of the P/M memory for 6 tanks .by <(pmgraph+$400) .by <(pmgraph+$500) .by <(pmgraph+$600) .by <(pmgraph+$700) .by <(pmgraph+$300) ; this is a missile background + .by <(pmgraph+$300) ; this is a missile background pmtableH .by >(pmgraph+$400) .by >(pmgraph+$500) .by >(pmgraph+$600) .by >(pmgraph+$700) .by >(pmgraph+$300) + .by >(pmgraph+$300) ;----------- sintable .by 0 diff --git a/definitions.asm b/definitions.asm index 25e041f..f257c4d 100644 --- a/definitions.asm +++ b/definitions.asm @@ -7,9 +7,13 @@ margin = 40 ;mountain drawing Y variable margin display = $1010 ;screen takes $2K due to clearing routine MaxPlayers = 6 maxOptions = 8 ;number of all options -PMOffset = $23 ; P/M to graphics offset +PMOffsetX = $2C ; P/M to graphics offset +PMOffsetY = $23 ; P/M to graphics offset napalmRadius = 10 +TextBackgroundColor = $02 ; REAL constans - use: LDA #TextBackgroundColor +TextForegroundColor = $0c + ;Weapon prices (*10 on screen) price_Baby_Missile___ = 0 ;_0 price_Missile________ = 96 ;_1 diff --git a/grafproc.asm b/grafproc.asm index d2ecee1..79e977e 100644 --- a/grafproc.asm +++ b/grafproc.asm @@ -28,7 +28,7 @@ ; begin: xdraw,ydraw - end: xbyte,ybyte ; let's store starting coordinates ; will be needed, because everything is calculated relatively - mwa #0 LineLength + mwa #$ffff LineLength mwa xdraw xtempDRAW mwa ydraw ytempDRAW @@ -611,10 +611,23 @@ DrawNextTank lda eXistenZ,x bne SkipHidingPM ; if energy=0 then no tank - ; hide P/M - lda #0 - sta hposp0,x - jmp DoNotDrawTankNr + ; hide P/M + lda #0 + cpx #$4 ; 5th tank is defferent + bne No5thTankHide + sta hposp0+4 + sta hposp0+5 + beq @+ +No5thTankHide + cpx #$5 ; 6th tank is defferent + bne No6thTankHide + sta hposp0+6 + sta hposp0+7 + beq @+ +No6thTankHide + sta hposp0,x +@ + jmp DoNotDrawTankNr SkipHidingPM @@ -636,20 +649,31 @@ DrawTankNrX ; now P/M graphics on the screen (only for 5 tanks) ; horizontal position + ldx TankNr mwa xdraw xbyte - ldx tanknr - cpx #$5 - bcs NoPlayerMissile rorw xbyte ; divide by 2 (carry does not matter) lda xbyte clc - adc #PMOffset+1 ; P/M to graphics offset + adc #PMOffsetX ; P/M to graphics offset cpx #$4 ; 5th tank are joined missiles and offset is defferent - bne NoMissile + bne No5thTank clc - adc #$0C ; missile offset offset -NoMissile + adc #$04 ; missile offset offset + sta hposp0+4 + sta hposp0+5 + bne NoMissile +No5thTank + cpx #$5 ; 6th tank are joined missiles and offset is defferent + bne Tanks1to4 + clc + adc #$04 ; missile offset offset + sta hposp0+6 + sta hposp0+7 + bne NoMissile +Tanks1to4 sta hposp0,x + +NoMissile ; vertical position lda pmtableL,x sta xbyte @@ -659,29 +683,54 @@ NoMissile ; calculate start position of the tank lda ydraw clc - adc #PMOffset + adc #PMOffsetY sta temp - ; clear sprite and put 3 lines on the tank at the same time ldy #$00 - tya + cpx #$5 + bcs PMForTank6 + ; clear sprite and put 3 lines on the tank at the same time + ldx #3 ; three lines of PM ClearPM cpy temp bne ZeroesToGo - lda #$03 ; (2 bits set) we set on two pixels in three lines +@ lda (xbyte),y + and #%11110000 + ora #%00001111 ; (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 + dex + bne @- ZeroesToGo + lda (xbyte),y + and #%11110000 sta (xbyte),y dey bne ClearPM + beq NoPlayerMissile +PMForTank6 + ; clear sprite and put 3 lines on the tank at the same time + ldx #3 ; three lines of PM +ClearPM6 + cpy temp + bne ZeroesToGo6 +@ lda (xbyte),y + and #%00001111 + ora #%11110000 ; (2 bits set) we set on two pixels in three lines + sta (xbyte),y + dey + dex + bne @- +ZeroesToGo6 + lda (xbyte),y + and #%00001111 + sta (xbyte),y + dey + bne ClearPM6 + NoPlayerMissile ; draw defensive weapons like shield ( tank number in X ) ; in xdraw, ydraw we have coordinates left LOWER corner of Tank char + ldx TankNr lda ActiveDefenceWeapon,x cmp #ind_Shield_________ ; one shot shield beq DrawTankShield @@ -774,7 +823,7 @@ ShieldVisible dec temp bne @- ; draw left oblique line of shield ( / ) - mva #4 temp + mva #3 temp @ jsr plot .nowarn dew ydraw @@ -782,14 +831,14 @@ ShieldVisible dec temp bne @- ; draw top horizontal line of shield ( _ ) - mva #5 temp + mva #7 temp @ jsr plot inw xdraw dec temp bne @- ; draw right oblique line of shield ( \ ) - mva #4 temp + mva #3 temp @ jsr plot inw ydraw @@ -831,7 +880,7 @@ ShieldVisible ; Symbol of ablative shield ? :) ;-------------------------------------------------- sbw xdraw #$04 ; 5 pixels left - sbw ydraw #$0a ; 10 pixels up + sbw ydraw #$0b ; 11 pixels up ; draw additional top horizontal line of shield ( _ ) mva #6 temp @ @@ -841,6 +890,273 @@ ShieldVisible bne @- rts .endp +;-------------------------------------------------- +.proc DrawTankParachute +;Tank number in X +;-------------------------------------------------- + lda #$34 ; parachute symbol + sta CharCode + lda Ytankstable,x + sec + sbc #8 + sta ydraw + lda XtanksTableL,x + sta xdraw + lda XtanksTableH,x + sta xdraw+1 + jsr TypeChar + rts +.endp + +;-------------------------------------------------- +.proc TankFalls; +;-------------------------------------------------- + lda #0 + sta PreviousFall ; bit 7 - left, bit 6 - right + sta EndOfTheFallFlag + sta Parachute + mva #2 FallingSoundBit ; another trick for only one sfx initialization in loop + + ; let's check if the given tank has got the parachute + ldx TankNr + lda ActiveDefenceWeapon,x + cmp #ind_Parachute______ ; parachute + beq ParachuteActive + cmp #ind_StrongParachute ; strong parachute + beq ParachuteActive + cmp #ind_Force_Shield___ ; shield witch energy and parachute + bne TankFallsX +ParachuteActive + inc Parachute +TankFallsX + ; sound only if really falls + lda Parachute + and FallingSoundBit ; bit 1 + beq NoFallingSound + mva #0 FallingSoundBit + mva #sfx_shield_off sfx_effect +NoFallingSound + ; clear previous position + mva #1 Erase + jsr DrawTankNr + ; and the parachute (if present) + lda Parachute + and #01 + beq DoNotClearParachute + ; here we clear the parachute + ldx TankNr + jsr DrawTankParachute +DoNotClearParachute + mva #0 Erase + ldx TankNr + lda EndOfTheFallFlag ; We only get byte below the tank if still falling + bne NoGroundCheck + ; coordinates of the first pixel under the tank + ldx TankNr + 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 + ; +; UnderTank1 ; byte under tank +; UnderTank2 ; byte under tank reversed (for simple check right direction) + lda #08 + sta temp ; Loop Counter +ByteBelowTank + jsr point + beq EmptyPoint2 + sec + ror UnderTank2 + sec + bcs ROLPoint2 +EmptyPoint2 + clc + ror UnderTank2 + clc +ROLPoint2 + rol UnderTank1 + inw xdraw + dec temp + bne ByteBelowTank +NoGroundCheck + ldx TankNr + lda UnderTank1 + bne NoFallingDown + ; Tank falling down ---- + lda Parachute + and #1 + bne ParachutePresent + ; decreasing energy + ldy #2 ; how much energy to substract + jsr DecreaseEnergyX +ParachutePresent + ; check parachute type + lda ActiveDefenceWeapon,x + cmp #ind_StrongParachute ; strong parachute + bne OneTimeParachute + ; decreasing energy of parachute + ldy #2 ; how much energy to substract + jsr DecreaseShieldEnergyX + cpy #0 ; is necessary to reduce tenk energy ? + beq @+ + jsr DecreaseEnergyX +@ + ; check energy of parachute + lda ShieldEnergy,x + bne OneTimeParachute + mva #0 Parachute + mva #0 ActiveDefenceWeapon,x ; deactivate defence +OneTimeParachute + lda Parachute + ora #2 ; we set bit nr 1 (nr 0 means that parachute is present) + sta Parachute + ; tank is falling down - modify coorinates + lda Ytankstable,x + clc + adc #1 + sta Ytankstable,x + jmp EndOfFCycle +NoFallingDown + ; check direction (left or right) + ldy #7 ; SlideLeftTable length -1 (from 0 to 7) +@ lda SlideLeftTable,y + cmp UnderTank1 + beq FallingRight + cmp UnderTank2 + beq FallingLeft + dey + bpl @- + bmi NoLeftOrRight +FallingLeft + ; tank is falling left + bit PreviousFall ; bit 6 - right + bvs EndLeftFall + ; we finish falling left if the tank reached the edge of the screen + lda XtanksTableL,x + bne NotLeftEdge + lda XtanksTableH,x + beq EndLeftFall +NotLeftEdge + ; tank is falling left - modify coorinates + clc + lda XtankstableL,x + adc #1 + sta XtankstableL,x + lda XtankstableH,x + adc #0 + sta XtankstableH,x + mva #%10000000 PreviousFall ; set bit 7 - left + bne EndOfFCycle +FallingRight + ; tank is falling right + bit PreviousFall ; bit 7 - left + bmi EndRightFall + ; we finish falling right if the tank reached the edge of the screen + 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 + beq EndRightFall + ; tank is falling right - modify coorinates + sec + lda XtankstableL,x + sbc #1 + sta XtankstableL,x + lda XtankstableH,x + sbc #0 + sta XtankstableH,x + mva #%01000000 PreviousFall ; set bit 6 - right + bne EndOfFCycle +EndLeftFall +EndRightFall +NoLeftOrRight + inc EndOfTheFallFlag ; after this is shouldn't fall +EndOfFCycle + ; draw tank on new position + jsr DrawTankNr ; ew have TankNr in X (I hope :) ) + ; checking is parachute present and if so, draw it + lda Parachute + cmp #3 ; parachute and falling + bne DoNotDrawParachute + ; here we draw parachute + ldx TankNr + jsr DrawTankParachute + wait ; onli if tank with patachute +RapidFalling +DoNotDrawParachute + lda EndOfTheFallFlag + jeq TankFallsX + ; 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 + beq 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 #%10000000 ; set "virtual ground" for right falling + ldy #%00000001 + bit PreviousFall + bmi ForceFallLeft + tay ; tricky - replaces ldy #%10000000 + lda #%00000001 ; set "virtual ground" for left falling +ForceFallLeft + sta UnderTank1 + sty UnderTank2 + jne TankFallsX +EndOfFall + mva #1 Erase + ldx TankNr + ; if tank was falling down having parachute, + ; we must deduct one parachute + lda Parachute + cmp #$03 ; was falling down and the parachute + bne NoParachuteWeapon + ; first we check type of parachute + lda ActiveDefenceWeapon,x + cmp #ind_Parachute______ ; deactivate weapon only if parachute (54) + bne NoParachuteWeapon + mva #0 ActiveDefenceWeapon,x ; deactivate defence weapon (parachute) +NoParachuteWeapon + ; now we clear parachute on the screen if present + lda Parachute + and #01 + beq ThereWasNoParachute + jsr DrawTankParachute +ThereWasNoParachute + mva #0 Erase + ldx TankNr + jsr DrawTankNr ; redraw tank after erase parachute (exactly for redraw leaky schield :) ) + mva #sfx_silencer sfx_effect + rts + +.endp + +;-------------------------------------------------- +.proc ClearPMmemory +;-------------------------------------------------- + + lda #$00 + tay +@ sta pmgraph+$300,y + sta pmgraph+$400,y + sta pmgraph+$500,y + sta pmgraph+$600,y + sta pmgraph+$700,y + iny + bne @- + rts +.endp ;-------------------------------------------------- .proc drawmountains @@ -1256,8 +1572,8 @@ EndOfUnPlot ; 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. +; +; Optimized by 0xF (Fox) THXXXX!!! ; ----------------------------------------- ; is it not over the screen ??? @@ -1331,9 +1647,7 @@ ClearPlot eor #$ff and bittable,x rts -.endp - -;-------------------------------------------------- +.endp;-------------------------------------------------- .proc DrawLine ;-------------------------------------------------- mva #0 ydraw+1 @@ -1585,12 +1899,12 @@ EndPut4x4 .endp .proc SetMainScreen - mva #0 dmactl +; mva #0 dmactls VDLI DLIinterruptGraph ; jsr SetDLI for graphics (game) screen mwa #dl dlptrs ; issue #72 (glitches when switches) - lda dmactls - and #$fc - ora #$02 ; 2=normal, 3 = wide screen width + lda #%00111110 +; and #$fc +; ora #$02 ; 2=normal, 3 = wide screen width sta dmactls rts .endp diff --git a/lib/atari.hea b/lib/atari.hea index 36e9cfb..aeaf4a3 100755 --- a/lib/atari.hea +++ b/lib/atari.hea @@ -1,33 +1,33 @@ .enum @dmactl - blank = %00 - narrow = %01 - standard= %10 - wide = %11 - missiles= %100 - players = %1000 + blank = %00 + narrow = %01 + standard= %10 + wide = %11 + missiles= %100 + players = %1000 lineX1 = %10000 lineX2 = %00000 - dma = %100000 + dma = %100000 .ende -scr48 = @dmactl(wide|dma|players|missiles|lineX1) ;screen 48b -scr40 = @dmactl(standard|dma|players|missiles|lineX1) ;screen 40b -scr32 = @dmactl(narrow|dma|players|missiles|lineX1) ;screen 32b +scr48 = @dmactl(wide|dma|players|missiles|lineX1) +scr40 = @dmactl(standard|dma|players|missiles|lineX1) +scr32 = @dmactl(narrow|dma|players|missiles|lineX1) .enum @pmcntl - missiles= %1 - players = %10 + missiles= %1 + players = %10 trigs = %100 .ende .enum @gtictl - prior0 = %0 - prior1 = %1 - prior2 = %10 - prior4 = %100 - prior8 = %1000 - ply5 = %10000 ; Fifth Player Enable - mlc = %100000 ; Multiple Color Player Enable + prior0 = %0 + prior1 = %1 + prior2 = %10 + prior4 = %100 + prior8 = %1000 + ply5 = %10000 ; Fifth Player Enable + mlc = %100000 ; Multiple Color Player Enable mode9 = %01000000 mode10 = %10000000 mode11 = %11000000 diff --git a/scorch.asm b/scorch.asm index 2f854c2..de26a6c 100644 --- a/scorch.asm +++ b/scorch.asm @@ -36,7 +36,7 @@ ;we decided it must go in 'English' to let other people work on it .macro build - dta d"147" ; number of this build (3 bytes) + dta d"148" ; number of this build (3 bytes) .endm icl 'definitions.asm' @@ -144,7 +144,7 @@ MainGameLoop jsr CallPurchaseForEveryTank ; issue #72 (glitches when switches) - mva #0 dmactl + mva #0 dmactls jsr GetRandomWind @@ -213,22 +213,22 @@ CalculateGains lda moneyH,x adc gainH,x sta moneyH,x - ; substract loose - ; if loose is greater than money then zero money + ; substract lose + ; if lose is greater than money then zero money lda moneyH,x - cmp looseH,x + cmp loseH,x bcc zeromoney - bne substractloose + bne substractlose lda moneyL,x - cmp looseL,x + cmp loseL,x bcc zeromoney -substractloose +substractlose sec lda moneyL,x - sbc looseL,x + sbc loseL,x sta moneyL,x lda moneyH,x - sbc looseH,x + sbc loseH,x sta moneyH,x jmp skipzeroing zeromoney @@ -244,9 +244,12 @@ skipzeroing jne START inc CurrentRoundNr - mva #0 dmactl ; issue #72 + lda #$0 + sta dmactls ; issue #72 jsr RmtSongSelect mva #sfx_silencer sfx_effect + jsr PMoutofscreen + jmp MainGameLoop @@ -258,12 +261,15 @@ skipzeroing ; the maximum shooting energy to 990 (it is 10*energy) ; the default shooting energy to 350 ; the shooting angle is randomized -; of course gains an looses are zeroed +; of course gains an loses are zeroed lda #song_ingame jsr RmtSongSelect lda #0 + sta sizep0 ; P0-P1 widths + sta sizep0+1 + tax @ sta singleRoundVars,x inx @@ -275,8 +281,8 @@ SettingEnergies lda #$00 sta gainL,x sta gainH,x - sta looseL,x - sta looseH,x + sta loseL,x + sta loseH,x lda #99 sta Energy,x sta eXistenZ,x @@ -306,6 +312,7 @@ SettingEnergies ;generating the new landscape jsr PMoutofScreen ;let P/M disappear jsr clearscreen ;let the screen be clean + jsr ClearPMmemory jsr placetanks ;let the tanks be evenly placed jsr calculatemountains ;let mountains be easy for the eye ;jsr calculatemountains0 ;only for tests - makes mountains flat and 0 height @@ -446,8 +453,8 @@ AfterManualShooting cmp #ind_Nuclear_Winter_ bne StandardShoot ShootAtomicWinter - ; --- nuclear winter --- - jsr NuclearWinter + ; --- atomic winter --- + jsr AtomicWinter jmp NextPlayerShoots ; and we skip shoot ShootWhiteFlag ; --- white flag --- @@ -681,6 +688,20 @@ MetodOfDeath jsr ExplosionDirect mva #sfx_silencer sfx_effect + ; Clear current Shooter settings. After that, Shooter will "search" for the target again + ldx NumberOfPlayers + dex +@ lda skillTable,x + cmp #2 ; clear variables only if Shooter + bne NotShooter + lda #0 + sta PreviousAngle,x + sta PreviousEnergyL,x + sta PreviousEnergyH,x +NotShooter + dex + bpl @- + ; jump to after explosion routines (soil fallout, etc.) ; After going through these routines we are back ; to checking if a tank exploded and maybe we have @@ -695,14 +716,14 @@ MetodOfDeath ;increases gain of tank TankNr ;-------------------------------------------------- sty EnergyDecrease - ; Loose increase - lda looseL,x + ; Lose increase + lda loseL,x clc adc EnergyDecrease - sta looseL,x - lda looseH,x + sta loseL,x + lda loseH,x adc #$00 - sta looseH,x + sta loseH,x ; Energy now, not less than 0 lda Energy,x cmp EnergyDecrease @@ -899,18 +920,19 @@ SetunPlots ;setting up P/M graphics lda #>pmgraph sta pmbase - lda dmactls - ora #$38 ; Players and Missiles single lined - sta dmactls +; lda dmactls +; ora #$38 ; Players and Missiles single lined +; sta dmactls lda #$03 ; P/M on sta pmcntl - lda #$01 - sta sizem ; there will be only M0, double width + lda #$00 sta sizep0 ; P0-P3 widths sta sizep0+1 sta sizep0+2 sta sizep0+3 - lda #$10 ; P/M priorities (bit 4 joins missiles) + lda #%01010101 + sta sizem ; all missiles, double width + lda #%00100000 ; P/M priorities (multicolor players on) sta gtictls jsr PMoutofScreen diff --git a/scorch.xex b/scorch.xex index 9d91cf7..d1439d1 100644 Binary files a/scorch.xex and b/scorch.xex differ diff --git a/textproc.asm b/textproc.asm index 598fe52..06b809b 100644 --- a/textproc.asm +++ b/textproc.asm @@ -17,9 +17,10 @@ ; - and I am sure maxwind, gravity, no_of_rounds in a game, speed of shell flight mwa #OptionsDL dlptrs - lda dmactls - and #$fc - ora #$02 ; normal screen width +; lda dmactls +; and #$fc +; ora #$02 ; normal screen width + lda #%00110010 ; normal screen width, DL on, P/M off sta dmactls VDLI DLIinterruptText.DLIinterruptNone ; jsr SetDLI for text screen without DLIs @@ -241,13 +242,14 @@ AfterManualPurchase ; Rest of the data is taken from appropriate tables ; and during the purchase these tables are modified. - mva #0 dmactl +; mva #0 dmactl VDLI DLIinterruptText ; jsr SetDLI for text (purchase) screen jsr PMoutofScreen mwa #PurchaseDL dlptrs - lda dmactls - and #$fc - ora #$02 ; normal screen width +; lda dmactls +; and #$fc +; ora #$02 ; normal screen width + lda #%00110010 ; normal screen width, DL on, P/M off sta dmactls mwa #ListOfWeapons WeaponsListDL ;switch to the list of offensive weapons @@ -969,9 +971,10 @@ NoArrowDown .proc EnterPlayerNames ;entering names of players mwa #NameDL dlptrs - lda dmactls - and #$fc - ora #$01 ; narrow screen (32 chars) +; lda dmactls +; and #$fc +; ora #$01 ; narrow screen (32 chars) + lda #%00110001 ; narrow screen width, DL on, P/M off sta dmactls VDLI DLIinterruptText ; jsr SetDLI for text (names) screen @@ -2064,6 +2067,10 @@ NextChar02 dex bne @- + lda #$01 + sta sizep0 ; P0-P1 widths + sta sizep0+1 + ; set background lda #$ff ldx #100 ; top of the sprites diff --git a/variables.asm b/variables.asm index cc52773..8e89e01 100644 --- a/variables.asm +++ b/variables.asm @@ -58,16 +58,16 @@ moneyL ;---------------------------------------------------- gainH ;how much money player gets after the round ;it is gathered during the round basing on energy - ;opponents loose after player's shoots + ;opponents lose after player's shoots .DS [MaxPlayers] gainL .DS [MaxPlayers] ;---------------------------------------------------- -looseH ;how much player looses after the round +loseH ;how much player looses after the round ;calculated from REAL energy loss ;(not only to zero energy) .DS [MaxPlayers] -looseL +loseL .DS [MaxPlayers] ;---------------------------------------------------- Energy @@ -197,6 +197,7 @@ vx03 .DS [5] MirvDown .DS [5] ; is given missile down? MirvMissileCounter .DS 1 ; missile Counter (mainly for X) SmokeTracerFlag .DS 1 ; if Smoketracer +LaserFlag .DS 1 ; $ff if Laser XposFlag .DS 1 ; bullet positon X (0 - on screen , %1000000 - off-screen) YposFlag .DS 1 ; bullet positon Y (0 - on screen , %1000000 - over the screen , %0100000 - under the screen) ;---------------------------------------------------- diff --git a/weapons.asm b/weapons.asm index ce999ee..ea44c7b 100644 --- a/weapons.asm +++ b/weapons.asm @@ -655,7 +655,8 @@ DiggerCharacter .endp ; ------------------------ .proc laser -; but where are xdraw and ydraw ???? !!!! +; in xdraw and ydraw we have hit point coordinates +; from Shoot/Flight procedures (invisible flight) ; ------------------------ ldx TankNr lda AngleTable,x @@ -675,33 +676,43 @@ DiggerCharacter sbc #$00 sta ybyte+1 - mva #0 drawFunction - mwa xdraw LaserCoordinate mwa ydraw LaserCoordinate+2 mwa xbyte LaserCoordinate+4 mwa ybyte LaserCoordinate+6 mva #sfx_lightning sfx_effect - mva #51 yc ; laser blink counter + + mva #%10000000 drawFunction + ;the above switches Draw to measuring length + jsr draw + mva #0 drawFunction + lsr LineLength+1 ; LineLength / 8 + ror LineLength + lsr LineLength ; max line lenght is about 380 (9 bits) + lsr LineLength + sec + lda #60 + sbc LineLength + sta yc ; laser blink counter 60-(LineLength/8) @ lda yc - and #$01 + and #$01 + eor #$01 sta color mwa LaserCoordinate xdraw mwa LaserCoordinate+2 ydraw mwa LaserCoordinate+4 xbyte mwa LaserCoordinate+6 ybyte - mva #sfx_lightning sfx_effect + mva #sfx_lightning sfx_effect jsr draw - dec:lda yc - bpl @- + dec yc + bne @- mva #1 color mwa LaserCoordinate xdraw mwa LaserCoordinate+2 ydraw - jsr plot mva #0 HitFlag jsr CheckCollisionWithTank lda HitFlag @@ -901,9 +912,8 @@ UpNotYet beq HowMuchToFallRight2 .nowarn dew xdraw lda xdraw + ora xdraw+1 jne RollinContinues ; like cpw xdraw #0 - lda xdraw+1 - jne RollinContinues beq ExplodeNow HowMuchToFallRight2 inw xdraw @@ -1077,7 +1087,9 @@ UpNotYet2 cmp #1 beq HowMuchToFallRight3 .NOWARN dew xdraw - cpw xdraw #$ffff + lda xdraw + and xdraw+1 + cmp #$ff ; like cpw xdraw #$ffff jne RollinContinuesLiquid beq FillNow HowMuchToFallRight3 @@ -1453,21 +1465,24 @@ RandomizeOffensiveText mva #1 plot4x4color jsr DisplayOffensiveTextNr - - ldx TankNr - lda ActiveWeapon,x - cmp #ind_Laser__________ ; laser - bne NotStrongShoot - mva #0 color - lda #7 - sta Force - sta Force+1 - bne AfterStrongShoot + mva #0 LaserFlag ; $ff - Laser + ldx TankNr + lda ActiveWeapon,x + cmp #ind_Laser__________ ; laser + bne NotStrongShoot + ; Laser: (not)very strong - invisible - shot for laser beam end coordinates + mva #0 color + lda #1 + sta Force + sta Force+1 + mva #$ff LaserFlag ; $ff - Laser + bne AfterStrongShoot NotStrongShoot lda ForceTableL,x sta Force lda ForceTableH,x sta Force+1 + mva #sfx_shoot sfx_effect AfterStrongShoot lda #$0 sta Force+2 @@ -1478,7 +1493,6 @@ AfterStrongShoot sta xtraj sta ytraj - mva #sfx_shoot sfx_effect ; Shoots tank nr X !!! :) ; set the starting coordinates of bullet with correction ; to start where the tank's barrel ends @@ -1516,257 +1530,6 @@ ShotUnderGround rts .endp -;-------------------------------------------------- -.proc TankFalls; -;-------------------------------------------------- - lda #0 - sta PreviousFall ; bit 7 - left, bit 6 - right - sta EndOfTheFallFlag - sta Parachute - mva #2 FallingSoundBit ; another trick for only one sfx initialization in loop - - ; let's check if the given tank has got the parachute - ldx TankNr - lda ActiveDefenceWeapon,x - cmp #ind_Parachute______ ; parachute - beq ParachuteActive - cmp #ind_StrongParachute ; strong parachute - beq ParachuteActive - cmp #ind_Force_Shield___ ; shield witch energy and parachute - bne TankFallsX -ParachuteActive - inc Parachute -TankFallsX - ; sound only if really falls - lda Parachute - and FallingSoundBit ; bit 1 - beq NoFallingSound - mva #0 FallingSoundBit - mva #sfx_shield_off sfx_effect -NoFallingSound - ; clear previous position - mva #1 Erase - jsr DrawTankNr - ; and the parachute (if present) - lda Parachute - and #01 - beq DoNotClearParachute - ; here we clear the parachute - ldx TankNr - jsr DrawTankParachute -DoNotClearParachute - mva #0 Erase - ldx TankNr - lda EndOfTheFallFlag ; We only get byte below the tank if still falling - bne NoGroundCheck - ; coordinates of the first pixel under the tank - ldx TankNr - 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 - ; -; UnderTank1 ; byte under tank -; UnderTank2 ; byte under tank reversed (for simple check right direction) - lda #08 - sta temp ; Loop Counter -ByteBelowTank - jsr point - beq EmptyPoint2 - sec - ror UnderTank2 - sec - bcs ROLPoint2 -EmptyPoint2 - clc - ror UnderTank2 - clc -ROLPoint2 - rol UnderTank1 - inw xdraw - dec temp - bne ByteBelowTank -NoGroundCheck - ldx TankNr - lda UnderTank1 - bne NoFallingDown - ; Tank falling down ---- - lda Parachute - and #1 - bne ParachutePresent - ; decreasing energy - ldy #2 ; how much energy to substract - jsr DecreaseEnergyX -ParachutePresent - ; check parachute type - lda ActiveDefenceWeapon,x - cmp #ind_StrongParachute ; strong parachute - bne OneTimeParachute - ; decreasing energy of parachute - ldy #2 ; how much energy to substract - jsr DecreaseShieldEnergyX - cpy #0 ; is necessary to reduce tenk energy ? - beq @+ - jsr DecreaseEnergyX -@ - ; check energy of parachute - lda ShieldEnergy,x - bne OneTimeParachute - mva #0 Parachute - mva #0 ActiveDefenceWeapon,x ; deactivate defence -OneTimeParachute - lda Parachute - ora #2 ; we set bit nr 1 (nr 0 means that parachute is present) - sta Parachute - ; tank is falling down - modify coorinates - lda Ytankstable,x - clc - adc #1 - sta Ytankstable,x - jmp EndOfFCycle -NoFallingDown - ; check direction (left or right) - ldy #7 ; SlideLeftTable length -1 (from 0 to 7) -@ lda SlideLeftTable,y - cmp UnderTank1 - beq FallingRight - cmp UnderTank2 - beq FallingLeft - dey - bpl @- - bmi NoLeftOrRight -FallingLeft - ; tank is falling left - bit PreviousFall ; bit 6 - right - bvs EndLeftFall - ; we finish falling left if the tank reached the edge of the screen - lda XtanksTableL,x - bne NotLeftEdge - lda XtanksTableH,x - beq EndLeftFall -NotLeftEdge - ; tank is falling left - modify coorinates - clc - lda XtankstableL,x - adc #1 - sta XtankstableL,x - lda XtankstableH,x - adc #0 - sta XtankstableH,x - mva #%10000000 PreviousFall ; set bit 7 - left - bne EndOfFCycle -FallingRight - ; tank is falling right - bit PreviousFall ; bit 7 - left - bmi EndRightFall - ; we finish falling right if the tank reached the edge of the screen - 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 - beq EndRightFall - ; tank is falling right - modify coorinates - sec - lda XtankstableL,x - sbc #1 - sta XtankstableL,x - lda XtankstableH,x - sbc #0 - sta XtankstableH,x - mva #%01000000 PreviousFall ; set bit 6 - right - bne EndOfFCycle -EndLeftFall -EndRightFall -NoLeftOrRight - inc EndOfTheFallFlag ; after this is shouldn't fall -EndOfFCycle - ; draw tank on new position - jsr DrawTankNr ; ew have TankNr in X (I hope :) ) - ; checking is parachute present and if so, draw it - lda Parachute - cmp #3 ; parachute and falling - bne DoNotDrawParachute - ; here we draw parachute - ldx TankNr - jsr DrawTankParachute - wait ; onli if tank with patachute -RapidFalling -DoNotDrawParachute - lda EndOfTheFallFlag - jeq TankFallsX - ; 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 - beq 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 #%10000000 ; set "virtual ground" for right falling - ldy #%00000001 - bit PreviousFall - bmi ForceFallLeft - tay ; tricky - replaces ldy #%10000000 - lda #%00000001 ; set "virtual ground" for left falling -ForceFallLeft - sta UnderTank1 - sty UnderTank2 - jne TankFallsX -EndOfFall - mva #1 Erase - ldx TankNr - ; if tank was falling down having parachute, - ; we must deduct one parachute - lda Parachute - cmp #$03 ; was falling down and the parachute - bne NoParachuteWeapon - ; first we check type of parachute - lda ActiveDefenceWeapon,x - cmp #ind_Parachute______ ; deactivate weapon only if parachute (54) - bne NoParachuteWeapon - mva #0 ActiveDefenceWeapon,x ; deactivate defence weapon (parachute) -NoParachuteWeapon - ; now we clear parachute on the screen if present - lda Parachute - and #01 - beq ThereWasNoParachute - jsr DrawTankParachute -ThereWasNoParachute - mva #0 Erase - ldx TankNr - jsr DrawTankNr ; redraw tank after erase parachute (exactly for redraw leaky schield :) ) - mva #sfx_silencer sfx_effect - rts - -.endp - -;-------------------------------------------------- -.proc DrawTankParachute -;Tank number in X -;-------------------------------------------------- - lda #$34 ; parachute symbol - sta CharCode - lda Ytankstable,x - sec - sbc #8 - sta ydraw - lda XtanksTableL,x - sta xdraw - lda XtanksTableH,x - sta xdraw+1 - jsr TypeChar - rts -.endp ;-------------------------------------------------- .proc Flight ; Force(byte.byte), Wind(0.word) ; Angle(byte) 128=0, 255=maxright, 0=maxleft @@ -1790,7 +1553,7 @@ ThereWasNoParachute ldy #0 ldx TankNr lda ActiveWeapon,x - cmp #11 ; Smoke tracer + cmp #ind_Smoke_Tracer___ ; Smoke tracer bne noSmokeTracer iny noSmokeTracer @@ -1949,6 +1712,8 @@ Loopi sbc vy+3 sta ytraj+2 + bit LaserFlag ; no gravity if Laser + bmi NoGravity ;vy=vy-g (again without least significant byte of vy) sec lda vy+1 @@ -1967,9 +1732,9 @@ Loopi lda ActiveWeapon,x cmp #ind_MIRV___________ ; MIRV jeq MIRVdownLoop +NoGravity StillUp - clc ;xtraj=xtraj+vx (skipping least significant byte of vx) lda xtraj ;here of course Fight to right adc vx+1 @@ -1981,12 +1746,15 @@ StillUp adc vx+3 sta xtraj+2 + bit LaserFlag ; no wind if Laser + bmi NoWind clc .rept 4 lda vx+# adc Wind+# sta vx+# .endr +NoWind mwa xtrajold+1 xdraw mwa ytrajold+1 ydraw mwa xtraj+1 xbyte @@ -2006,6 +1774,22 @@ StillUp nowait lda HitFlag bne Hit + ; --- only for Laser + bit LaserFlag + bpl NoCheckEdgesForLaser + ; If laser fires, edges of the screen finish "flying" and laser hits. + lda ytraj+2 + bmi LaserHitEdge + cpw xtraj+1 #screenwidth+1 + bcc LaserNoHitEdge +LaserHitEdge + mwa xdraw XHit + mwa ydraw YHit + mva #$ff HitFlag ; screen edgs like ground (only for Laser) + jmp EndOfFlight +LaserNoHitEdge + ; ------------------ +NoCheckEdgesForLaser cpw ytraj+1 #screenheight+1 bcc YTrayLowerThanScreenHeight @@ -2095,7 +1879,7 @@ NoDefence rts ; END !!! AutoDefence ; now run defensive-aggressive weapon - Auto Defence! - sbb #255 LeapFrogAngle Angle ; swap angle (LeapFrogAngle - because we have strored angle in this variable) + sbb #180 LeapFrogAngle Angle ; swap angle (LeapFrogAngle - because we have strored angle in this variable) lsrw Force ; Force = Force / 2 - becouse earlier we multiplied by 2 mva #1 Erase ; now erase shield phx @@ -2514,7 +2298,7 @@ MIRValreadyAll .endp ; ------------------------------------------------- -.proc NuclearWinter +.proc AtomicWinter ; ------------------------------------------------- ; This routine is run from inside of the main loop ; and replaces Shoot and Flight routines