diff --git a/README.md b/README.md index 0b803af..05586f0 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,21 @@ With the advent of fujinet (https://fujinet.online/) we are thinking about makin ## Changes: +###### Build 145 +2022-06-26 +Possibly last round of weapon additions! +@Pecusx added +- working White Flag -- it is a way to give up while not making opponents richer! +- Battery - a must for every tank with low energy. +- Strong Parachute - like a normal parachute, but stronger (it has energy and can work more than once) +- Nuclear Winter - a quick and efficient solution to global worming, err, warning, WARMING! +@mikerro added new SFX and in-game-tunes. +- Pressing [S] turns on/off SFX (when aiming). Pressing [M] turns on/off in-game tunes. +Tickets closed: +- https://github.com/pkali/scorch_src/issues/54 - holding joystick up or down longer speeds up force change. It makes playing with joystick much nicer. +- https://github.com/pkali/scorch_src/issues/76 - a beginning of visual tweaks by Adam +- infinite defensive weapons purchase bug fixed, to chagrin of some... + ###### Build 144 2022-06-19 Father's day release comes with the most anticipated new feature: defensive weapons. Thanks to @Pecus we have 5 completely new weapons and a more reasonably working parachute. The stub of the instruction manual describing these weapons is available here: https://github.com/pkali/scorch_src/wiki/Instruction-manual. diff --git a/artwork/sfx/scorch_trial0e_stripped.rmt b/artwork/sfx/scorch_trial0f_stripped.rmt similarity index 50% rename from artwork/sfx/scorch_trial0e_stripped.rmt rename to artwork/sfx/scorch_trial0f_stripped.rmt index b2d6ae3..0343be7 100644 Binary files a/artwork/sfx/scorch_trial0e_stripped.rmt and b/artwork/sfx/scorch_trial0f_stripped.rmt differ diff --git a/artwork/tanks.fnt b/artwork/tanks.fnt index e7d11ef..8c0e93d 100644 Binary files a/artwork/tanks.fnt and b/artwork/tanks.fnt differ diff --git a/constants.asm b/constants.asm index 22cab8a..88d91f0 100644 --- a/constants.asm +++ b/constants.asm @@ -596,13 +596,13 @@ WeaponPriceH ; weapons prices (tables with prices of weapons) .by >price______________46 .by >price______________47 .by >price_White_Flag_____ - .by >price_Heat_Guidance__ + .by >price_Battery________ .by >price_Bal_Guidance___ .by >price_Horz_Guidance__ .by >price_Vert_Guidance__ .by >price_Lazy_Boy_______ .by >price_Parachute______ - .by >price_Battery________ + .by >price_StrongParachute .by >price_Mag_Deflector__ .by >price_Shield_________ .by >price_Force_Shield___ @@ -610,7 +610,7 @@ WeaponPriceH ; weapons prices (tables with prices of weapons) .by >price_Super_Mag______ .by >price_Auto_Defense___ .by >price_Fuel_Tank______ - .by >price_Contact_Trigger + .by >price_Nuclear_Winter_ WeaponPriceL .by MODUL ;hi byte of RMT module to Y reg - lda #0 ;starting song line 0-255 to A reg - jsr RASTERMUSICTRACKER ;Init + lda #0 + jsr RmtSongSelect ; VMAIN VBLinterrupt,6 ;jsr SetVBL rts .endp - +;-------------------------------------------------- .proc DLIinterruptGraph ;sta dliA ;sty dliY @@ -935,7 +944,7 @@ ClearResults pla rti .endp - +;-------------------------------------------------- .proc DLIinterruptText ;sta dliA pha @@ -947,7 +956,7 @@ ClearResults DLIinterruptNone rti .endp - +;-------------------------------------------------- .proc VBLinterrupt pha phx @@ -968,14 +977,16 @@ itsPAL ; pressTimer is trigger tick counter. always 50 ticks / s bit:smi:inc pressTimer ; timer halted if >127. max time measured 2.5 s + ; ------- RMT ------- lda sfx_effect bmi lab2 asl @ ; * 2 tay ;Y = 2,4,..,16 instrument number * 2 (0,2,4,..,126) ldx #0 ;X = 0 channel (0..3 or 0..7 for stereo module) - lda #0 ;A = 12 note (0..60) - jsr RASTERMUSICTRACKER+15 ;RMT_SFX start tone (It works only if FEAT_SFX is enabled !!!) + lda #0 ;A = 0 note (0..60) + bit noSfx + smi:jsr RASTERMUSICTRACKER+15 ;RMT_SFX start tone (It works only if FEAT_SFX is enabled !!!) lda #$ff sta sfx_effect ;reinit value @@ -999,9 +1010,7 @@ exitVBL bne @- rts .endp - - - +;-------------------------------------------------- .proc RandomizeSequence ; in: NumberOfPlayers ; out: TankSequence @@ -1119,7 +1128,6 @@ LimitForce rts .endp - ;---------------------------------------------- .proc MoveBarrelToNewPosition jsr DrawTankNr @@ -1153,7 +1161,7 @@ rotateLeft BarrelPositionIsFine rts - .endp +.endp ;---------------------------------------------- .proc SortSequence ; @@ -1283,9 +1291,8 @@ notpressedJoyGetKey getkeyend mvx #sfx_keyclick sfx_effect rts - - .endp + ;-------------------------------------------------- .proc getkeynowait ;-------------------------------------------------- @@ -1294,6 +1301,7 @@ getkeyend and #$3f ;CTRL and SHIFT ellimination rts .endp + ;-------------------------------------------------- .proc WaitForKeyRelease ;-------------------------------------------------- @@ -1309,7 +1317,16 @@ getkeyend rts .endp - +;-------------------------------------------------- +.proc RmtSongSelect +;-------------------------------------------------- +; starting song line 0-255 to A reg + bit noMusic + spl:lda #song_silencio + ldx #MODUL ;hi byte of RMT module to Y reg + jmp RASTERMUSICTRACKER ;Init, :RTS +.endp ;---------------------------------------------- icl 'weapons.asm' ;---------------------------------------------- @@ -1331,6 +1348,7 @@ TankFont ;---------------------------------------------- icl 'variables.asm' ;---------------------------------------------- + ; reserved space for RMT player .ds $0320 .align $100 @@ -1339,7 +1357,7 @@ TankFont MODUL equ $b000 ;address of RMT module opt h- ;RMT module is standard Atari binary file already - ins "artwork/sfx/scorch_trial0e_stripped.rmt" ;include music RMT module + ins "artwork/sfx/scorch_trial0f_stripped.rmt" ;include music RMT module opt h+ ; ; diff --git a/scorch.xex b/scorch.xex index 1e58424..f02f07a 100644 Binary files a/scorch.xex and b/scorch.xex differ diff --git a/textproc.asm b/textproc.asm index 29881f5..8b79b17 100644 --- a/textproc.asm +++ b/textproc.asm @@ -287,8 +287,8 @@ AfterPurchase ; is being processed now mwa #ListOfWeapons xbyte ldx #$00 ; index of the checked weapon - stx HowManyOnTheList1 ; amounts of weapons (shells, bullets) in both lists - stx HowManyOnTheList2 + stx HowManyOnTheListOff ; amounts of weapons (shells, bullets) in both lists + stx HowManyOnTheListDef ; Creating full list of the available weapons for displaying ; in X there is an index of the weapon to be checked, @@ -437,25 +437,25 @@ notInventory bne NotTheSameAsLastTime lda WhichList bne @+ - lda HowManyOnTheList1 + lda HowManyOnTheListOff sta PositionOnTheList jmp NotTheSameAsLastTime @ - lda HowManyOnTheList2 + lda HowManyOnTheListDef sta PositionOnTheList NotTheSameAsLastTime ; increase appropriate counter txa cpx #$30 bcs DefenceList - ldy HowManyOnTheList1 + ldy HowManyOnTheListOff sta IndexesOfWeaponsL1,y - inc HowManyOnTheList1 + inc HowManyOnTheListOff bne NextLineOfTheList DefenceList - ldy HowManyOnTheList2 + ldy HowManyOnTheListDef sta IndexesOfWeaponsL2,y - inc HowManyOnTheList2 + inc HowManyOnTheListDef ; If everything is copied then next line NextLineOfTheList adw xbyte #40 @@ -491,7 +491,7 @@ WeHaveOffset ; of the first erased char. ; (multiplying taken from book of Ruszczyc 'Assembler 6502' - lda HowManyOnTheList1 + lda HowManyOnTheListOff sta xbyte+1 ; multiplier (temporarily here, it will be erased anyway) lda #$00 ; higher byte of the Result sta xbyte ; lower byte of the Result @@ -534,7 +534,7 @@ DoNotIncHigher1 ; Multiply number on list 1 by 40 and set address ; of the first erased char. - lda HowManyOnTheList2 + lda HowManyOnTheListDef sta xbyte+1 ; multiplier lda #$00 ; higher byte of the Result sta xbyte ; lower byte of the Result @@ -658,17 +658,17 @@ PurchaseKeyDown lda WhichList beq GoDown1 inc:lda PositionOnTheList - cmp HowManyOnTheList2 + cmp HowManyOnTheListDef bne EndGoDownX - ldy HowManyOnTheList2 + ldy HowManyOnTheListDef dey sty PositionOnTheList jmp ChoosingItemForPurchase GoDown1 inc:lda PositionOnTheList - cmp HowManyOnTheList1 + cmp HowManyOnTheListOff bne MakeOffsetDown - ldy HowManyOnTheList1 + ldy HowManyOnTheListOff dey sty PositionOnTheList MakeOffsetDown @@ -785,7 +785,26 @@ invSelectDef lda IndexesOfWeaponsL2,y tay ldx tankNr + cmp #ind_Battery________ + bne NotBattery + ; if activate battery, we do it differently + mva #sfx_battery sfx_effect + mva #99 Energy,x + bne DecreaseDefensive ; bypass activation +NotBattery + cmp #ind_White_Flag_____ + bne NotWhiteFlag + cmp ActiveDefenceWeapon,x + bne NoDeactivateWhiteFlag + mva #sfx_white_flag sfx_effect + lda #$00 ; if try to activate activated White Flag then deactivate Defence sta ActiveDefenceWeapon,x + sta ShieldEnergy,x + beq DefActivationEnd +NotWhiteFlag +NoDeactivateWhiteFlag + sta ActiveDefenceWeapon,x +DecreaseDefensive ; decrease number of defensives lda TanksWeaponsTableL,x sta weaponPointer @@ -798,6 +817,7 @@ invSelectDef lda DefensiveEnergy,y sta ShieldEnergy,x +DefActivationEnd jmp WaitForKeyRelease ; rts .endp @@ -819,6 +839,8 @@ invSelectDef ?noWeaponActive ldy #0 ?weaponFound + cpy howManyOnTheListDef + bcs ?noWeaponActive sty positionOnTheList rts .endp @@ -840,6 +862,8 @@ invSelectDef ?noWeaponActive ldy #0 ?weaponFound + cpy howManyOnTheListOff + bcs ?noWeaponActive sty positionOnTheList rts .endp @@ -916,7 +940,7 @@ NoArrowUp stx MoreUpdl sty MoreUpdl+1 ; the same, bu scrolling down - lda HowManyOnTheList1 + lda HowManyOnTheListOff ldx #EmptyLine sec @@ -1578,8 +1602,9 @@ quit_seppuku .proc DisplayResults ; ;displays results of the round ;using 4x4 font + jsr RoundOverSprites + - mva #sfx_smoke_cloud sfx_effect mva #1 plot4x4color ;centering the result screen @@ -1609,6 +1634,8 @@ quit_seppuku beq @+ ;unconditional jump, because TypeLine4x4 ends with beq GameOver4x4 + lda #song_game_over + jsr RmtSongSelect mwa #LineGameOver LineAddress4x4 mwa #((ScreenWidth/2)-(8*4)) LineXdraw mva ResultY LineYdraw @@ -1965,5 +1992,38 @@ NextChar02 rts .endp ;------------------------------------------------- +.proc RoundOverSprites + ; fill sprites with bytes + ldy numberOfPlayers + dey + lda gameOverSpritesTop,y + sta temp + + ; clean the whole sprite + lda #0 + tax +@ sta PMGraph+$400,x + sta PMGraph+$500,x + dex + bne @- + + ; set background + lda #$ff + ldx #100 ; top of the sprites +@ sta PMGraph+$400,x + sta PMGraph+$500,x + inx + cpx temp + bne @- + GOSbeg = 112 + mva #GOSbeg hposp0 + mva #GOSbeg+12 hposp0+1 + + mva #15 COLPM0S + sta COLPM1S + + rts +.endp +;------------------------------------------------- .endif \ No newline at end of file diff --git a/variables.asm b/variables.asm index b24c535..93ed69f 100644 --- a/variables.asm +++ b/variables.asm @@ -19,6 +19,8 @@ seppukuVal .by 75 skilltable ; computer controlled players' skills (1-8), 0 - human (no cleaning, ticket #30) .DS [MaxPlayers] ;---------------------------------------------------- +noMusic .by 0 ; 0 - play music, $ff - do not play music +noSfx .by 0 ; 0 - play SFX, $ff - do not play SFX ; 4x4 text buffer ResultLineBuffer dta d" ", $ff @@ -256,9 +258,9 @@ IndexesOfWeaponsL2 ; variables storing amount of weapons on the first and second ; list and pointer position -HowManyOnTheList1 +HowManyOnTheListOff .DS 1 -HowManyOnTheList2 +HowManyOnTheListDef .DS 1 PositionOnTheList ; pointer position on the list being displayed .DS 1 diff --git a/weapons.asm b/weapons.asm index e6b36f0..963ae92 100644 --- a/weapons.asm +++ b/weapons.asm @@ -33,7 +33,7 @@ ExplosionRoutines .word VOID-1 ;napalm .word VOID-1 ;hotnapalm .word tracer-1 - .word VOID-1 ;smoketracer + .word tracer-1 ;smoketracer .word babyroller-1 .word roller-1 .word heavyroller-1 @@ -57,6 +57,7 @@ ExplosionRoutines .word laser-1 VOID +tracer rts .endp ; ------------------------ @@ -264,10 +265,6 @@ NoLowerCircle rts .endp ; ------------------------ -.proc tracer - rts -.endp -; ------------------------ .proc babyroller inc FallDown2 mva #11 ExplosionRadius @@ -656,15 +653,15 @@ DistanceCheckLoop tay ; check shields lda ActiveDefenceWeapon,x - cmp #57 ; one hit shield + cmp #ind_Shield_________ ; one hit shield beq UseShield - cmp #58 ; shield with energy and parachute + cmp #ind_Force_Shield___ ; shield with energy and parachute beq UseShieldWithEnergy - cmp #59 ; shield with energy + cmp #ind_Heavy_Shield___ ; shield with energy beq UseShieldWithEnergy - cmp #61 ; Auto Defence (it works only if hit ground next to tank. Tank hit is handled in Flight proc) + cmp #ind_Auto_Defense___ ; Auto Defence (it works only if hit ground next to tank. Tank hit is handled in Flight proc) beq UseShieldWithEnergy - cmp #56 ; Mag deflector (it works only if hit ground next to tank. Tank hit is handled in Flight proc) + cmp #ind_Mag_Deflector__ ; Mag deflector (it works only if hit ground next to tank. Tank hit is handled in Flight proc) beq UseShieldWithEnergy jsr DecreaseEnergyX jmp EndOfDistanceCheckLoop @@ -1046,6 +1043,11 @@ notpressed cmp #$0d ; I bne @+ callInventory + ; Hide all tanks - after inventory they may have other shapes + mva #1 Erase + jsr DrawTanks + mva #0 Erase + ; mva #$ff isInventory jsr Purchase mva #0 escFlag @@ -1076,6 +1078,10 @@ jumpFromStick jeq pressedSpace cmp #$2c jeq pressedTAB + cmp #$25 ; M + jeq pressedM + cmp #$3e ; S + jeq pressedS jmp notpressed checkJoy ;------------JOY------------- @@ -1233,6 +1239,22 @@ CTRLpressedTAB jsr WaitForKeyRelease jmp BeforeFire +pressedM + ; have you tried turning the music off and on again? + lda #$ff + eor:sta noMusic + lda #song_ingame + jsr RmtSongSelect + jsr WaitForKeyRelease + jmp BeforeFire + +pressedS + ; have you tried turning sfx off and on again? + lda #$ff + eor:sta noSfx + jsr WaitForKeyRelease + jmp BeforeFire + pressedSpace ;================================= @@ -1241,7 +1263,7 @@ pressedSpace jsr WaitForKeyRelease lda pressTimer cmp #25 ; 1/2s - bcs fire + bcc fire jmp callInventory fire RTS @@ -1272,7 +1294,7 @@ RandomizeOffensiveText ldx TankNr lda ActiveWeapon,x - cmp #$20 ; laser + cmp #ind_Laser__________ ; laser bne NotStrongShoot mva #0 color lda #7 @@ -1345,9 +1367,11 @@ ShotUnderGround ; let's check if the given tank has got the parachute ldx TankNr lda ActiveDefenceWeapon,x - cmp #54 ; parachute + cmp #ind_Parachute______ ; parachute beq ParachuteActive - cmp #58 ; scheld witch energy and parachute + cmp #ind_StrongParachute ; strong parachute + beq ParachuteActive + cmp #ind_Force_Shield___ ; shield witch energy and parachute bne TankFallsX ParachuteActive inc Parachute @@ -1417,6 +1441,44 @@ ItStillFalls FallDiagonally NoFallingDown ParachutePresent + ; check parachute type + lda ActiveDefenceWeapon,x + cmp #ind_StrongParachute ; strong parachute + bne OneTimeParachute + ; decreasing energy of parachute - if the vertical fall, substract 2 + ; and if at an angle then substract 1 + ldy #1 ; how much energy to substract + lda IfFallDown + and #1 + beq NoFallingDown2 + ldx TankNr + jsr DecreaseShieldEnergyX + cpy #0 ; is necessary to reduce tenk energy ? + beq @+ + jsr DecreaseEnergyX +@ + ldy #1 + lda IfFallDown + and #6 + bne FallDiagonally2 + ldx TankNr + 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 weapon (parachute) + ; and now we must clear parachute symbol + mva #1 Erase + jsr DrawTankParachute +FallDiagonally2 +NoFallingDown2 +OneTimeParachute ; we must set flag meaning that the tank was falling down ; because later maybe the number of parachutes will decrease ; (if there were parachutes and they were ON) @@ -1424,7 +1486,7 @@ ParachutePresent lda Parachute ora #2 ; we set bit nr 1 (nr 0 means that parachute is present) sta Parachute - +testowanie ; storing last direction of falling ; (it is not necessarily the direction from the previous ; iteraction, so we must check directional bits before storing) @@ -1472,17 +1534,7 @@ NotRightEdge beq DoNotClearParachute ; here we clear the parachute ldx TankNr - lda #$34 - sta CharCode - lda Ytankstable,x - sec - sbc #8 - sta ydraw - lda XtanksTableL,x - sta xdraw - lda XtanksTableH,x - sta xdraw+1 - jsr TypeChar + jsr DrawTankParachute DoNotClearParachute mva #0 Erase ldx TankNr @@ -1525,17 +1577,7 @@ DoesNotFallRight ; here we draw parachute ldx TankNr - lda #$34 - sta CharCode - lda Ytankstable,x - sec - sbc #8 - sta ydraw - lda XtanksTableL,x - sta xdraw - lda XtanksTableH,x - sta xdraw+1 - jsr TypeChar + jsr DrawTankParachute DoNotDrawParachute lda EndOfTheFallFlag jeq TankFallsX @@ -1552,11 +1594,24 @@ EndOfFall mva #1 Erase ldx TankNr lda ActiveDefenceWeapon,x - cmp #54 ; deactivate weapon only if parachute (53) + cmp #ind_Parachute______ ; deactivate weapon only if parachute (54) bne NoParachuteWeapon mva #0 ActiveDefenceWeapon,x ; deactivate defence weapon (parachute) NoParachuteWeapon - lda #$34 + jsr DrawTankParachute + mva #0 Erase + ldx TankNr + jsr DrawTankNr ; redraw tank after erase parachute (exactly for redraw leaky schield :) ) +ThereWasNoParachute + mva #sfx_silencer sfx_effect + rts +.endp + +;-------------------------------------------------- +.proc DrawTankParachute +;Tank number in X +;-------------------------------------------------- + lda #$34 ; parachute symbol sta CharCode lda Ytankstable,x sec @@ -1567,14 +1622,8 @@ NoParachuteWeapon lda XtanksTableH,x sta xdraw+1 jsr TypeChar - mva #0 Erase - ldx TankNr - jsr DrawTankNr ; redraw tank after erase parachute (exactly for redraw leaky schield :) ) -ThereWasNoParachute - mva #sfx_silencer sfx_effect - rts + rts .endp - ;-------------------------------------------------- .proc Flight ; Force(byte.byte), Wind(0.word) ; Angle(byte) 128=0, 255=maxright, 0=maxleft @@ -1858,9 +1907,9 @@ EndOfFlight2 tax dex ; index of tank in X lda ActiveDefenceWeapon,x - cmp #61 ; Auto Defence + cmp #ind_Auto_Defense___ ; Auto Defence beq AutoDefence - cmp #56 ; Mag Deflector + cmp #ind_Mag_Deflector__ ; Mag Deflector bne NoDefence MagDeflector ; now run defensive-aggressive weapon - Mag Deflector! @@ -2290,6 +2339,96 @@ MIRValreadyAll rts .endp +; ------------------------------------------------- +.proc WhiteFlag +; ------------------------------------------------- +; This routine is run from inside of the main loop +; and replaces Shoot and Flight routines +; X and TankNr - index of shooting tank +; ------------------------------------------------- + mva #sfx_death_begin sfx_effect + jsr FlashTank ; first we flash tank + mva #1 Erase + jsr DrawTankNr ; and erase tank + mva #0 Erase + ldx TankNr + sta Energy,x ; clear tank energy + sta eXistenZ,x ; erase from existence + sta LASTeXistenZ,x ; to prevent explosion + sta ActiveDefenceWeapon,x ; deactivate White Flag + jsr PMoutofScreen + jsr drawtanks ; for restore PM + mva #sfx_silencer sfx_effect + rts +.endp + +; ------------------------------------------------- +.proc NuclearWinter +; ------------------------------------------------- +; This routine is run from inside of the main loop +; and replaces Shoot and Flight routines +; X and TankNr - index of shooting tank +; ------------------------------------------------- + mva #sfx_sandhog sfx_effect + ldy #0 ; byte counter (from 0 to 39) +NextColumn + ; big loop - we repat internal loops for each column of bytes + sty magic + ldx #120 ; line counter (from 0 to 60 ) + ; first loop - inverse column of bytes for a while + ldy magic +NextLine1 + jsr InverseScreenByte + dex + dex + bpl NextLine1 + ; + wait ; wait uses A and Y + ; second loop - inverse again and put random "snow" to column of bytes + ldx #120 + ldy magic + mva #$55 magic+1 +NextLine2 + jsr InverseScreenByte + lda random + ora magic+1 + and (temp),y + sta (temp),y + lda magic+1 + eor #$ff + sta magic+1 + dex + dex + bpl NextLine2 + ; and go to next column + iny + cpy #40 + bne NextColumn + ; and we have "snow" :) + lda #0 + ldx TankNr + sta ActiveDefenceWeapon,x ; deactivate Nuclear Winter + + sta RangeLeft ; whole screen in range of soil down + sta RangeLeft+1 + mwa #screenwidth RangeRight + jsr SoilDown2 + jsr drawtanks ; for restore PM + rts + + ; in order to optimize the fragment repeated in both internal loops + ; we save 15 bytes :) +InverseScreenByte + lda LineTableL,x + sta temp + lda LineTableH,x + sta temp+1 + lda (temp),y + eor #$ff + sta (temp),y + rts +.endp + ; ------------------------------------------------- .proc CheckCollisionWithTank ; -------------------------------------------------