diff --git a/README.md b/README.md index c543969..ec58187 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 144 +2022-06-19 +Juneteenth release is coming with the most anticipated new feature: defensive weapons. Thanks to @Pecusx we have 5 completely new weapons and more reasonably working parachute. The stub of instruction manual describing these weapons is available here: https://github.com/pkali/scorch_src/wiki/Instruction-manual. + +The new inventory system has been added. Call it by pressing "I" key or short-pressing fire. Select weapon to use by moving joystick or cursor keys right. Switch between offensive and deffensive weapons by moving joystick left. Fire/escape to quit inventory. + +Other significant playability change is https://github.com/pkali/scorch_src/issues/54 - it is not finished yet, but keeping joystick up or down makes force to increase / decrease faster. +Also - short press of fire calls Inventory, long press fires the shell. The timings are experimental, please let me know it this needs a modification / improvement. + +Tickets closed: +* https://github.com/pkali/scorch_src/issues/92 - less unnecessary cleaning of the offensive texts +* https://github.com/pkali/scorch_src/issues/89 - improved collisions with tank +* https://github.com/pkali/scorch_src/issues/71 - ditto +* https://github.com/pkali/scorch_src/issues/11, https://github.com/pkali/scorch_src/issues/26, https://github.com/pkali/scorch_src/issues/8, https://github.com/pkali/scorch_src/issues/20 - new inventory system + ###### Build 143 2022-06-05 Rewrite build. We redone several important parts of the game to allow for bug fixes and requested features. Generally it was a great success, but some new bugs appeared. This build is nice for the eye, but beware, no mercy for testers again :) diff --git a/artwork/HIMARS14.asm b/artwork/HIMARS14.asm index c658213..1c87947 100644 --- a/artwork/HIMARS14.asm +++ b/artwork/HIMARS14.asm @@ -73,7 +73,7 @@ pmg .ds $0300 eif song_data - ins 'mmm_16.lzs' + ins 'mmm_16.lzs' song_end POKEY = $D200 @@ -456,7 +456,7 @@ quit ini main ; --- - opt l- + ;opt l- .MACRO SPRITES missiles diff --git a/artwork/weapons_AW5.fnt b/artwork/weapons_AW5_mod.fnt similarity index 68% rename from artwork/weapons_AW5.fnt rename to artwork/weapons_AW5_mod.fnt index 6beb32f..8aa58be 100644 Binary files a/artwork/weapons_AW5.fnt and b/artwork/weapons_AW5_mod.fnt differ diff --git a/constants.asm b/constants.asm index 99c6f47..22cab8a 100644 --- a/constants.asm +++ b/constants.asm @@ -14,9 +14,9 @@ dliColorsFore TextBackgroundColor = $02 ; REAL constans - use: LDA #TextBackgroundColor TextForegroundColor = $0c CashOptionL ;(one zero less than on the screen) - .by 0,<200,<500,<800,<1000 + .by 0,<200,<800,<1200,<2000 CashOptionH - .by 0,>200,>500,>800,>1000 + .by 0,>200,>800,>1200,>2000 GravityTable .by 10,20,25,30,40 MaxWindTable .by 5,20,40,70,99 RoundsTable .by 10,20,30,40,50 @@ -514,7 +514,8 @@ EndOfTheBarrelY .by 6,6,6,6,6,6,6,6,6 .by 5,5,5,5,5,5,5,5,5,5 .by 4,4,4,4,4,4,4,4,4,4,4,4,4 - .by 3,3,3,3,3,3,3,3,3,3,3,3,3,3 + .by 4,4,4,4,4,4,4,4,4,4,4,4,4,4 ; one pixel Up for fix problems with colision check +; .by 3,3,3,3,3,3,3,3,3,3,3,3,3,3 .by 0,0,0,0,0,0,0,0,0,0 ; not used .by 0,0,0,0,0,0,0,0,0,0 ; not used @@ -526,7 +527,8 @@ EndOfTheBarrelY .by 0,0,0,0 ; not used ; left angles from 90 (horizontally to the left) to 1 (vertically up) - .by 3,3,3,3,3,3,3,3,3,3,3,3,3,3 +; .by 3,3,3,3,3,3,3,3,3,3,3,3,3,3 + .by 4,4,4,4,4,4,4,4,4,4,4,4,4,4 ; one pixel Up for fix problems with colision check .by 4,4,4,4,4,4,4,4,4,4,4,4,4 .by 5,5,5,5,5,5,5,5,5,5 .by 6,6,6,6,6,6,6,6,6 @@ -593,6 +595,7 @@ WeaponPriceH ; weapons prices (tables with prices of weapons) .by >price______________45 .by >price______________46 .by >price______________47 + .by >price_White_Flag_____ .by >price_Heat_Guidance__ .by >price_Bal_Guidance___ .by >price_Horz_Guidance__ @@ -608,7 +611,6 @@ WeaponPriceH ; weapons prices (tables with prices of weapons) .by >price_Auto_Defense___ .by >price_Fuel_Tank______ .by >price_Contact_Trigger - .by >price_White_Flag_____ WeaponPriceL .by 127. max time measured 2.5 s + + ; ------- RMT ------- lda sfx_effect bmi lab2 asl @ ; * 2 @@ -912,13 +976,14 @@ VBLinterrupt .proc 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 #$ff sta sfx_effect ;reinit value -; lab2 jsr RASTERMUSICTRACKER+3 ;1 play + ; ------- RMT ------- +exitVBL ply plx pla @@ -986,7 +1051,7 @@ UsageLoop rts .endp ;---------------------------------------------- -RandomizeAngle .proc ; +.proc RandomizeAngle ; routine returns in A ; a valid angle for the tank's barrel. ; X is not changed @@ -1009,7 +1074,7 @@ RandomizeAngle .proc ; rts .endp ;---------------------------------------------- -RandomizeForce .proc +.proc RandomizeForce ; routine returns in ForceTable/L/H ; valid force of shooting for TankNr ; in X must be TankNr @@ -1222,7 +1287,7 @@ getkeyend .endp ;-------------------------------------------------- -getkeynowait .proc; +.proc getkeynowait ;-------------------------------------------------- jsr WaitForKeyRelease lda kbcode @@ -1230,7 +1295,7 @@ getkeynowait .proc; rts .endp ;-------------------------------------------------- -WaitForKeyRelease .proc +.proc WaitForKeyRelease ;-------------------------------------------------- lda JSTICK0 and #$0f diff --git a/scorch.xex b/scorch.xex index bfbe522..d759362 100644 Binary files a/scorch.xex and b/scorch.xex differ diff --git a/textproc.asm b/textproc.asm index f48bd10..29881f5 100644 --- a/textproc.asm +++ b/textproc.asm @@ -8,7 +8,7 @@ ;---------------------------------------- ;-------------------------------------------------- -Options .proc +.proc Options ;-------------------------------------------------- ; start-up screen - options, etc. ; this function returns: @@ -201,14 +201,9 @@ OptionsYLoop ;------------------------------------------- ; call of the purchase screens for each tank .proc CallPurchaseForEveryTank - jsr PMoutofScreen - mwa #PurchaseDL dlptrs - lda dmactls - and #$fc - ora #$02 ; normal screen width - sta dmactls mva #0 TankNr + sta isInventory @ ldx TankNr lda SkillTable,x @@ -231,17 +226,29 @@ AfterManualPurchase ;-------------------------------------------------- .proc Purchase ; ;-------------------------------------------------- +; TODO: when round ends with a weapon depleted the pointer points to an empty line + ; In tanknr there is a number of the tank (player) ; that is buying weapons now (from 0). ; Rest of the data is taken from appropriate tables ; and during the purchase these tables are modified. + 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 + sta dmactls + mwa #ListOfWeapons WeaponsListDL ;switch to the list of offensive weapons ldx tankNr lda TankStatusColoursTable,x - sta colpf2s - + sta colpf2s + + ; we are clearing list of the weapons mva #$ff LastWeapon mva #$00 WhichList @@ -265,6 +272,8 @@ NextChar03 ; here we must jump in after each purchase ; to generate again list of available weapons AfterPurchase + + ; current cash display mva #sfx_purchase sfx_effect ldx tanknr lda moneyL,x @@ -277,32 +286,44 @@ AfterPurchase ; in xbyte there is the address of the line that ; is being processed now mwa #ListOfWeapons xbyte - ldx #$00 ; number of the checked weapon + ldx #$00 ; index of the checked weapon stx HowManyOnTheList1 ; amounts of weapons (shells, bullets) in both lists stx HowManyOnTheList2 - stx PositionOnTheList ; Creating full list of the available weapons for displaying -; in X there is a number of the weapon to be checked, +; in X there is an index of the weapon to be checked, ; in 'Xbyte' address of the first char in filled screen line CreateList - ; checking if the weapon of the given number is present + stx temp ; index of a weapon will be necessary later + ; checking if the weapon of the given index is present lda WeaponUnits,x jeq NoWeapon + + ldy tanknr + + bit isInventory + jmi itIsInventory + + ; put "Purchase" on the screen + ldx #[purchaseTextEnd-purchaseText-1] +@ lda purchaseText,x + sta purchaseActivate,x + dex + bpl @- + ; checking if we can afford buying this weapon - ldy tanknr + ldx temp lda moneyH,y cmp WeaponPriceH,x - bne CheckWeapon01 + bne @+ lda moneyL,y cmp WeaponPriceL,x -CheckWeapon01 +@ jcc TooLittleCash - + ; we have enough cash and the weapon can be ; added to the list - stx temp ; number of weapon will be necessary later ; first parentheses and other special chars ; (it's easier this way) @@ -322,58 +343,65 @@ CheckWeapon01 lda #16 ; "0" sta (xbyte),y - ; now symbol of the weapon - lda WeaponSymbols,x - ldy #$4 ; 4 chars from the beginning of the line - sta (xbyte),y - - ;now number of purchased units (shells) - clc - lda xbyte - adc #23 ; 23 chars from the beginning of the line - sta displayposition - lda xbyte+1 - adc #$00 - sta displayposition+1 + ;now number of units (shells) to be purchased + adw xbyte #23 displayposition ; 23 chars from the beginning of the line lda WeaponUnits,x sta decimal jsr displaybyte - ldx temp ;getting back number of the weapon + ldx temp ;getting back index of the weapon ; and now price of the weapon - clc - lda xbyte - adc #27 ; 27 chars from the beginning of the line - sta displayposition - lda xbyte+1 - adc #$00 - sta displayposition+1 + adw xbyte #27 displayposition ; 27 chars from the beginning of the line lda WeaponPriceL,x sta decimal lda WeaponPriceH,x sta decimal+1 jsr displaydec - lda temp ;getting back number of the weapon - pha ;and saving it on the stack + jmp notInventory +itIsInventory + ; put "Activate" on the screen + ldx #[purchaseTextEnd-purchaseText-1] +@ lda activateText,x + sta purchaseActivate,x + dex + bpl @- + + ldx temp + lda TanksWeaponsTableL,y + sta weaponPointer + lda TanksWeaponsTableH,y + sta weaponPointer+1 + ldy temp + lda (weaponPointer),y + jeq noWeapon + + ; clear price area + ldy #22 ; beginning of the price area + lda #0 +@ sta (XBYTE),y + iny + cpy #32+1 ; end of price + bne @- + +notInventory + + ; number of posessed shells + lda temp ; weapon index again jsr HowManyBullets sta decimal - pla - sta temp ; let's store weapon number again - - clc - lda xbyte - adc #1 ; 1 char from the beginning of the screen - sta displayposition - lda xbyte+1 - adc #$00 - sta displayposition+1 + adw xbyte #1 displayposition jsr displaybyte + ldx temp ;weapon index + ; now symbol of the weapon + lda WeaponSymbols,x + ldy #$4 ; 4 chars from the beginning of the line + sta (xbyte),y + ; and now name of the weapon and finisheeeedd !!!! - ldx temp ;weapon number mva #0 temp+1 ; this number is only in X ; times 16 (it's length of the names of weapons) ldy #3 ; Rotate 4 times @@ -383,55 +411,54 @@ CheckWeapon01 dey bpl @- - adw temp #NamesOfWeapons-6 modify + adw temp #NamesOfWeapons-6 weaponPointer - ldy #6 ; from 6th char + ldy #6 ; from 6th char on screen @ - lda (modify),y + lda (weaponPointer),y sta (xbyte),y iny cpy #(16+6) bne @- - ; in X there is what we need + ; in X there is what we need (weapon index) ; If on screen after the purchase there is still ; present the weapon purchased recently, ; the pointer must point to it. - + bit lastWeapon + bpl @+ ; if == $ff => first run, jump to top + mva #0 PositionOnTheList + beq NotTheSameAsLastTime +@ cpx LastWeapon bne NotTheSameAsLastTime lda WhichList - bne ominx06 + bne @+ lda HowManyOnTheList1 sta PositionOnTheList jmp NotTheSameAsLastTime -ominx06 +@ lda HowManyOnTheList2 sta PositionOnTheList NotTheSameAsLastTime ; increase appropriate counter txa cpx #$30 - bcs SecondList + bcs DefenceList ldy HowManyOnTheList1 - sta NubersOfWeaponsL1,y + sta IndexesOfWeaponsL1,y inc HowManyOnTheList1 bne NextLineOfTheList -SecondList +DefenceList ldy HowManyOnTheList2 - sta NubersOfWeaponsL2,y + sta IndexesOfWeaponsL2,y inc HowManyOnTheList2 ; If everything is copied then next line NextLineOfTheList - clc - lda xbyte - adc #40 - sta xbyte - bcc TooLittleCash - inc xbyte+1 + adw xbyte #40 TooLittleCash NoWeapon @@ -550,18 +577,48 @@ DoNotIncHigher2 ; screen clearing at each list refresh ; (it was very ugly - I checked it :) + bit isInventory ; + bpl ChoosingItemForPurchase + + lda whichList + bne PositionDefensive + +; calculate positionOnTheList from the activeWeapon (offensives) + ldx tankNr + lda activeWeapon,x + ldy #0 +@ + cmp IndexesOfWeaponsL1,y + beq ?weaponfound + iny + cpy #48 ; maxOffensiveWeapons + bne @- + ; not found apparently? + ; TODO: check border case (the last weapon) + ldy #0 + beq ?weaponFound ; jmp +PositionDefensive + jsr calcPosDefensive + + +?weaponFound + ; weapon index in Y + sty positionOnTheList ; Here we have all we need ; So choose the weapon for purchase ...... ;-------------------------------------------------- ChoosingItemForPurchase ;-------------------------------------------------- + jsr PutLitteChar ; Places pointer at the right position jsr getkey ldx escFlag - seq:rts + seq:jmp WaitForKeyRelease ; like jsr ... : rts cmp #$2c ; Tab jeq ListChange + cmp #$06 ; cursor left + jeq ListChange cmp #$0c ; Return sne:rts cmp #$e @@ -600,8 +657,7 @@ EndUpX PurchaseKeyDown lda WhichList beq GoDown1 - inc PositionOnTheList - lda PositionOnTheList + inc:lda PositionOnTheList cmp HowManyOnTheList2 bne EndGoDownX ldy HowManyOnTheList2 @@ -609,8 +665,7 @@ PurchaseKeyDown sty PositionOnTheList jmp ChoosingItemForPurchase GoDown1 - inc PositionOnTheList - lda PositionOnTheList + inc:lda PositionOnTheList cmp HowManyOnTheList1 bne MakeOffsetDown ldy HowManyOnTheList1 @@ -632,18 +687,31 @@ EndGoDownX ; swapping the displayed list and setting pointer to position 0 ListChange + mva #0 OffsetDL1 + lda WhichList eor #$01 sta WhichList - bne SecondSelected + bne DeffensiveSelected + mwa #ListOfWeapons WeaponsListDL - jmp @+ -SecondSelected - mwa #ListOfDefensiveWeapons WeaponsListDL + lda isInventory + beq @+ + ; inventory + jsr calcPosOffensive + jmp ChoosingItemForPurchase @ - lda #$00 - sta PositionOnTheList - sta OffsetDL1 + mva #0 PositionOnTheList + jmp ChoosingItemForPurchase + +DeffensiveSelected + mwa #ListOfDefensiveWeapons WeaponsListDL + lda isInventory + beq @+ + jsr calcPosDefensive + jmp ChoosingItemForPurchase +@ + mva #0 positionOnTheList jmp ChoosingItemForPurchase .endp @@ -652,24 +720,23 @@ SecondSelected ;-------------------------------------------------- .proc PurchaseWeaponNow ;-------------------------------------------------- -weaponPtr = temp -isPriceZero = tempXRoller + bit isInventory + bmi inventorySelect lda WhichList bne PurchaseDeffensive ; here we purchase the offensive weapon ldy PositionOnTheList - lda NubersOfWeaponsL1,y + lda IndexesOfWeaponsL1,y jmp PurchaseAll PurchaseDeffensive ldy PositionOnTheList - lda NubersOfWeaponsL2,y + lda IndexesOfWeaponsL2,y PurchaseAll - ; after getting weapon number the routine is common for all + ; after getting weapon index the routine is common for all ldx tanknr - tay ; weapon number is in Y - beq @+ + tay ; weapon index is in Y sec lda moneyL,x ; substracting from posessed money sbc WeaponPriceL,y ; of price of the given weapon @@ -678,61 +745,117 @@ PurchaseAll sbc WeaponPriceH,y sta moneyH,x - ; save info about price == 0 - lda WeaponPriceL,y - ora WeaponPriceH,y - sta isPriceZero - - +positiveMoney ; now we have to get address of ; the table of the weapon of the tank ; and add appropriate number of shells lda TanksWeaponsTableL,x - sta weaponPtr + sta weaponPointer lda TanksWeaponsTableH,x - sta weaponPtr+1 + sta weaponPointer+1 clc - lda (weaponPtr),y ; and we have number of posessed bullets of the weapon + lda (weaponPointer),y ; and we have number of posessed bullets of the weapon adc WeaponUnits,y - sta (weaponPtr),y ; and we added appropriate number of bullets + sta (weaponPointer),y ; and we added appropriate number of bullets cmp #100 ; but there should be no more than 99 bullets bcc LessThan100 lda #99 - sta (weaponPtr),y + sta (weaponPointer),y LessThan100 sty LastWeapon ; store last purchased weapon ; because we must put screen pointer next to it - ; additional check for unfinished game - ; if weapon was free (price == $0) - ; then have nothing... - lda isPriceZero - bne @+ - lda #0 - sta (weaponPtr),y -@ + mva #0 PositionOnTheList ; to move the pointer to the top when no more monies jmp Purchase.AfterPurchase + +inventorySelect + lda whichList + bne invSelectDef + + ldy PositionOnTheList + lda IndexesOfWeaponsL1,y + ldx tankNr + sta activeWeapon,x + jmp WaitForKeyRelease ; rts + +invSelectDef + ldy PositionOnTheList + lda IndexesOfWeaponsL2,y + tay + ldx tankNr + sta ActiveDefenceWeapon,x + ; decrease number of defensives + lda TanksWeaponsTableL,x + sta weaponPointer + lda TanksWeaponsTableH,x + sta weaponPointer+1 + lda (weaponPointer),y + sec + sbc #1 + sta (weaponPointer),y + + lda DefensiveEnergy,y + sta ShieldEnergy,x + jmp WaitForKeyRelease ; rts + +.endp +; ----------------------------------------------------- +.proc calcPosDefensive +; calculate positionOnTheList from the activeWeapon (defensives) + ldx tankNr + lda ActiveDefenceWeapon,x + beq ?noWeaponActive + ldy #0 ; min defensive weapon +@ + cmp IndexesOfWeaponsL2,y + beq ?weaponfound + iny + cpy #8*2 ; maxDefensiveWeapon + bne @- + ; not found apparently? + ; TODO: check border case (the last weapon) +?noWeaponActive + ldy #0 +?weaponFound + sty positionOnTheList + rts .endp +.proc calcPosOffensive +; calculate positionOnTheList from the activeWeapon (defensives) + ldx tankNr + lda ActiveWeapon,x + beq ?noWeaponActive + ldy #0 ; min defensive weapon +@ + cmp IndexesOfWeaponsL1,y + beq ?weaponfound + iny + cpy #8*5 ; maxOffensiveWeapon + bne @- + ; not found apparently? + ; TODO: check border case (the last weapon) +?noWeaponActive + ldy #0 +?weaponFound + sty positionOnTheList + rts +.endp +; ----------------------------------------------------- .proc PutLitteChar - ; first let's cleat both lists from little chars + ; first let's clear both lists from little chars mwa #ListOfWeapons xbyte ldx #52 ; there are 52 lines total ldy #$00 EraseLoop - lda #$00 + tya ; lda #$00 sta (xbyte),y - clc - lda xbyte - adc #40 - sta xbyte - bcc ominx02 - inc xbyte+1 -ominx02 + adw xbyte #40 dex bpl EraseLoop + ; now let's check which list is active now lda WhichList beq CharToList1 @@ -742,13 +865,7 @@ ominx02 ldx PositionOnTheList beq SelectList2 ; if there is 0 we add nothing AddLoop2 - clc - lda xbyte - adc #40 - sta xbyte - bcc ominx03 - inc xbyte+1 -ominx03 + adw xbyte #40 dex bne AddLoop2 SelectList2 @@ -770,13 +887,7 @@ CharToList1 ldx PositionOnTheList beq SelectList1 ; if there is 0 we add nothing AddLoop1 - clc - lda xbyte - adc #40 - sta xbyte - bcc ominx04 - inc xbyte+1 -ominx04 + adw xbyte #40 dex bne AddLoop1 SelectList1 @@ -787,13 +898,7 @@ SelectList1 ldx OffsetDL1 beq SetWindowList1 ; if zero then add nothing LoopWindow1 - clc - lda xbyte - adc #40 - sta xbyte - bcc ominx05 - inc xbyte+1 -ominx05 + adw xbyte #40 dex bne LoopWindow1 SetWindowList1 @@ -805,8 +910,8 @@ SetWindowList1 ldy #>EmptyLine lda OffsetDL1 beq NoArrowUp - ldx #MoreUp + ldx #MoreUp NoArrowUp stx MoreUpdl sty MoreUpdl+1 @@ -819,8 +924,8 @@ NoArrowUp bmi NoArrowDown cmp OffsetDL1 bcc NoArrowDown - ldx #MoreDown + ldx #MoreDown NoArrowDown stx MoreDowndl sty MoreDowndl+1 @@ -1200,6 +1305,8 @@ space dta d" " ;that's easy because we have number of tank ;and xtankstableL and H keep X position of a given tank + ;save vars (messed when printing...) + lda xtankstableL,y sta temp lda xtankstableH,y @@ -1320,12 +1427,12 @@ DOTNcharloop asl clc adc TextPositionX - sta Xdraw + sta dx lda #0 adc TextPositionX+1 - sta Xdraw+1 + sta dx+1 lda TextPositionY - sta ydraw + sta dy jsr PutChar4x4 inc TextCounter @@ -1343,6 +1450,7 @@ DOTNcharloop ;address in LineAddress4x4 ;starting from LineXdraw, LineYdraw + ldy #0 sty LineCharNr @@ -1355,8 +1463,8 @@ TypeLine4x4Loop beq EndOfTypeLine4x4 sta CharCode4x4 - mwa LineXdraw Xdraw - mva LineYdraw Ydraw + mwa LineXdraw dx + mva LineYdraw dy mva #1 plot4x4color jsr PutChar4x4 ;type empty pixels as well! adw LineXdraw #4 @@ -1372,10 +1480,6 @@ EndOfTypeLine4x4 .proc AreYouSure ;using 4x4 font - ;save vars (messed in TypeLine4x4) - mwa Xdraw xk - mva Ydraw yc - mva #4 ResultY ; where seppuku text starts Y-wise on the screen ;top frame @@ -1405,7 +1509,7 @@ EndOfTypeLine4x4 skip01 ;clean - mva #3 dx + mva #3 di mva #4 ResultY @ mva #1 plot4x4color @@ -1415,23 +1519,16 @@ skip01 jsr TypeLine4x4 adb ResultY #4 ;next line - dec dx + dec di bne @- - quit_areyousure - ;restore vars - mva yc Ydraw - mwa xk Xdraw rts .endp ;-------------------------------- .proc DisplaySeppuku ;using 4x4 font - ;save vars (messed in TypeLine4x4) - mwa Xdraw xk - mva Ydraw yc mva #20 fs ; temp, how many times blink the billboard seppuku_loop @@ -1459,7 +1556,7 @@ seppuku_loop ;clean seppuku - mva #3 dx + mva #3 di mva #4 ResultY @ mwa #lineClear LineAddress4x4 @@ -1468,16 +1565,13 @@ seppuku_loop jsr TypeLine4x4 adb ResultY #4 ;next line - dec dx + dec di bne @- dec fs jne seppuku_loop quit_seppuku - ;restore vars - mva yc Ydraw - mwa xk Xdraw rts .endp ;-------------------------------- @@ -1690,8 +1784,6 @@ FinishResultDisplay bpl @- adw temp #NamesOfWeapons - ldy #6 ; from 6th character - ldy #15 @ lda (temp),y @@ -1699,6 +1791,39 @@ FinishResultDisplay dey bpl @- + ;--------------------- + ;displaying name of the defence weapon (if active) + ;--------------------- + lda #$08 ; ( + sta textbuffer+80+22 + lda #$09 ; ) + sta textbuffer+80+39 + lda ActiveDefenceWeapon,x + bne ActiveDefence + ; clear brackets + lda #$00 ; space + sta textbuffer+80+22 + sta textbuffer+80+39 + lda #47 ; no weapon name +ActiveDefence + sta temp ;get back number of the weapon + mva #0 temp+1 + ; times 16 (because this is length of weapon name) + ldy #3 ; shift left 4 times +@ + aslw temp + dey + bpl @- + + adw temp #NamesOfWeapons + + ldy #15 +@ + lda (temp),y + sta textbuffer+40+40+23,y + dey + bpl @- + ;--------------------- ;displaying the energy of a tank ;--------------------- @@ -1709,6 +1834,31 @@ FinishResultDisplay mwa #textbuffer+48 displayposition jsr displaybyte + ;--------------------- + ;displaying the energy of a tank shield (if exist) + ;--------------------- + ; clear (if no shield) + lda #$00 ; space + sta textbuffer+40+10 + sta textbuffer+40+11 + sta textbuffer+40+12 + sta textbuffer+40+13 + ; check shield energy and display it + ldx TankNr + lda ActiveDefenceWeapon,x + beq NoDefenceWeapon + lda ShieldEnergy,x + beq NoShieldEnergy + sta decimal ; displayed value + lda #$08 ; ( + sta textbuffer+40+10 + mwa #textbuffer+40+11 displayposition + jsr displaybyte + lda #$09 ; ) + sta textbuffer+40+13 +NoDefenceWeapon +NoShieldEnergy + ;========================= ;display Force ;========================= @@ -1717,7 +1867,7 @@ FinishResultDisplay sta decimal lda ForceTableH,x sta decimal+1 - mwa #textbuffer+40+34 displayposition + mwa #textbuffer+40+36 displayposition jsr displaydec ;========================= @@ -1729,9 +1879,9 @@ FinishResultDisplay lda AngleTable,x bmi AngleToLeft lda #$7f ; (tab) character - sta textbuffer+40+23 + sta textbuffer+40+25 lda #0 ;space - sta textbuffer+40+20 + sta textbuffer+40+22 lda #90 sec sbc AngleTable,x @@ -1748,12 +1898,12 @@ AngleToLeft lda BarrelTableL,y sta CharCode lda #$7e ;(del) char - sta textbuffer+40+20 + sta textbuffer+40+22 lda #0 ;space - sta textbuffer+40+23 + sta textbuffer+40+25 AngleDisplay - mwa #textbuffer+40+21 displayposition + mwa #textbuffer+40+23 displayposition jsr displaybyte ;========================= @@ -1763,9 +1913,9 @@ AngleDisplay lda Wind+3 ; highest byte of 4 byte wind bmi DisplayLeftWind lda #$7f ; (tab) char - sta textbuffer+80+28 + sta textbuffer+80+20 lda #0 ;space - sta textbuffer+80+25 + sta textbuffer+80+17 beq DisplayWindValue DisplayLeftWind sec ; Wind = -Wind @@ -1776,14 +1926,14 @@ DisplayLeftWind sbc temp+1 sta temp+1 lda #$7e ;(del) char - sta textbuffer+80+25 + sta textbuffer+80+17 lda #0 ;space - sta textbuffer+80+28 + sta textbuffer+80+20 DisplayWindValue :4 lsrw temp ;divide by 16 to have a nice value on a screen lda temp sta decimal - mwa #textbuffer+80+26 displayposition + mwa #textbuffer+80+18 displayposition jsr displaybyte ;========================= @@ -1791,7 +1941,7 @@ DisplayWindValue ;========================= lda CurrentRoundNr sta decimal - mwa #textbuffer+80+14 displayposition + mwa #textbuffer+80+7 displayposition jsr displaybyte ;decimal (byte), displayposition (word) rts diff --git a/variables.asm b/variables.asm index 47c1ce9..b24c535 100644 --- a/variables.asm +++ b/variables.asm @@ -30,6 +30,8 @@ RoundNrDisplay ;===================================================== variablesStart ; zeroing starts here ;===================================================== +isInventory .ds 1 ; 0 - purchase, $ff - inventory +;-------------- drawFunction .ds 1 ; 0 - plot, %10000000 - LineLength (N), %01000000 - DrawCheck (V) ;-------------- sfx_effect .ds 1 @@ -47,7 +49,7 @@ moneyH ;we place zero at the end of prices and money ;and have range from 0 to 99990 (not too much) ;money players have (maybe one more byte is needed?) .DS [MaxPlayers] -moneyL +moneyL .DS [MaxPlayers] ;---------------------------------------------------- gainH ;how much money player gets after the round @@ -66,6 +68,8 @@ looseL ;---------------------------------------------------- Energy .DS [MaxPlayers] +ShieldEnergy + .DS [MaxPlayers] EnergyDecrease .DS 1 eXistenZ .DS [MaxPlayers] @@ -95,6 +99,8 @@ NewAngle .DS 1 ActiveWeapon ;number of the selected weapon .DS [MaxPlayers] +ActiveDefenceWeapon ;number of the activated defence weapon - 0 + .DS [MaxPlayers] WeaponDepleted .DS 1 ; if 0 deactivate the weapon and switch to Baby Missile ;---------------------------------------------------- @@ -114,7 +120,7 @@ MaxWind .ds 1 ; WindOrientation .DS 1 ;(0-right,1-left) ;---------------------------------------------------- Counter .DS 1 ;temporary Counter for outside loops -HitFlag .DS 1 ;1 when missile hit anything +HitFlag .DS 1 ;$ff when missile hit ground, $00 when no hit, $01-$06 tank index+1 when hit tank ;---------------------------------------------------- xtankstableL ;X positions of tanks (lower left point) .DS [MaxPlayers] @@ -239,14 +245,12 @@ temptankNr .DS 1 ;---------------------------------------------------- ;Variables from textproc.s65 - ; tables with numbers of weapons on the right lists - ; to be honest - I do not know at the moment what the above - ; comment was supposed to mean... + ; tables with indexes of weapons on the right lists ; OK (2022) so, L1 is list of offensive weapons, L2 - defensive -NubersOfWeaponsL1 - .ds 8*5 ; :(8*5) .by $ff -NubersOfWeaponsL2 - .ds 8*2 ; :(8*2) .by $ff +IndexesOfWeaponsL1 + .ds 8*5 ; max 40 offensive weapons. this is wrong, should be 48, still only 32 defined. +IndexesOfWeaponsL2 + .ds 8*2 ; max 16 defensive weapons. ;---------------------------------------------------- ; variables storing amount of weapons on the first and second diff --git a/weapons.asm b/weapons.asm index ba6da9e..e6b36f0 100644 --- a/weapons.asm +++ b/weapons.asm @@ -102,14 +102,7 @@ VOID jsr xmissile ; soil must fall down now! there is no other way... - - ;first clean the offensive text... - ldy TankNr - mva #0 plot4x4color - jsr DisplayOffensiveTextNr - ; hide tanks or they fall down with soil - lda TankNr pha mva #1 Erase @@ -130,6 +123,7 @@ VOID mva LeapFrogAngle Angle mva #sfx_funky_hit sfx_effect + sbw ytraj+1 #$05 ; next missiles start point goes 5 pixel UP to prevent multiple explosion at one point if tank is hit (4 pixels tank height + 1) jsr Flight lda HitFlag beq EndOfLeapping @@ -159,6 +153,7 @@ VOID ror Force mva LeapFrogAngle Angle mva #sfx_funky_hit sfx_effect + sbw ytraj+1 #$05 ; next missiles start point goes 5 pixel UP to prevent multiple explosion at one point if tank is hit (4 pixels tank height + 1) jsr Flight lda HitFlag beq EndOfLeapping @@ -178,16 +173,12 @@ EndOfLeapping .proc funkybomb ; mva #sfx_baby_missile sfx_effect mwa xtraj+1 xtrajfb - mwa ytraj+1 ytrajfb + sbw ytraj+1 #$05 ytrajfb ; funky missiles start point goes 5 pixel UP to prevent multiple explosion at one point if tank is hit (4 pixels tank height + 1) inc FallDown2 ;central Explosion mva #21 ExplosionRadius jsr CalculateExplosionRange0 jsr xmissile - - ldy TankNr - mva #0 plot4x4color - jsr DisplayOffensiveTextNr lda TankNr pha @@ -663,12 +654,39 @@ DistanceCheckLoop adc #1 :3 asl tay + ; check shields + lda ActiveDefenceWeapon,x + cmp #57 ; one hit shield + beq UseShield + cmp #58 ; shield with energy and parachute + beq UseShieldWithEnergy + cmp #59 ; 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) + beq UseShieldWithEnergy + cmp #56 ; Mag deflector (it works only if hit ground next to tank. Tank hit is handled in Flight proc) + beq UseShieldWithEnergy jsr DecreaseEnergyX - + jmp EndOfDistanceCheckLoop +UseShieldWithEnergy + jsr DecreaseShieldEnergyX + cpy #0 ; is necessary to reduce tenk energy ? + beq ShieldCoveredTank + jsr DecreaseEnergyX +ShieldCoveredTank + lda ShieldEnergy,x + jne EndOfDistanceCheckLoop +ShieldEnergy0 ; deactivate if no energy. it's like use one hit shield :) +UseShield + mva #1 Erase + phx + jsr DrawTankShield + plx + mva #0 ActiveDefenceWeapon,x ; deactivate defense weapons TankIsNotWithinTheRange EndOfDistanceCheckLoop txa - bne DistanceCheckLoop + jne DistanceCheckLoop mva #sfx_silencer sfx_effect rts .endp @@ -740,7 +758,7 @@ UpNotYet sbc #1 sta ydraw ;check tank collision prior to PLOT - sty HitFlag + sty HitFlag ; set to 0 jsr CheckCollisionWithTank @@ -1007,13 +1025,11 @@ ContinueToCheckMaxForce2 ; $f3 - shift+key notpressed - lda TRIG0S - beq notpressed lda SKSTAT cmp #$ff - beq checkJoy + jeq checkJoy cmp #$f7 ; SHIFT - beq checkJoy + jeq checkJoy lda kbcode and #%10111111 ; SHIFT elimination @@ -1026,6 +1042,18 @@ notpressed ;---esc pressed-quit game--- rts +@ + cmp #$0d ; I + bne @+ +callInventory + mva #$ff isInventory + jsr Purchase + mva #0 escFlag + jsr DisplayStatus + jsr SetMainScreen + jsr DrawTanks + jsr WaitForKeyRelease + jmp BeforeFire @ cmp #$8e jeq CTRLPressedUp @@ -1064,10 +1092,17 @@ notpressedJoy ;fire lda TRIG0S jeq pressedSpace + mva #$ff pressTimer ; stop counting frames jmp notpressed ; pressedUp + lda pressTimer + spl:mva #0 pressTimer ; if >128 then reset to 0 + cmp #25 ; 1/2s + bcs CTRLPressedUp + + ;force increaseeee! ldx TankNr inc ForceTableL,x @@ -1104,6 +1139,11 @@ CTRLPressedUp pressedDown + lda pressTimer + spl:mva #0 pressTimer ; if >128 then reset to 0 + cmp #25 ; 1/2s + bcs CTRLPressedDown + mva #sfx_set_power_1 sfx_effect ldx TankNr @@ -1197,6 +1237,13 @@ CTRLpressedTAB pressedSpace ;================================= ;we shoot here!!! + mva #0 pressTimer ; reset + jsr WaitForKeyRelease + lda pressTimer + cmp #25 ; 1/2s + bcs fire + jmp callInventory +fire RTS .endp @@ -1269,9 +1316,20 @@ AfterStrongShoot sbc #$00 sta ytraj+2 + ; checking if the shot is underground (no Flight but Hit :) ) + ldy #0 + adw xtraj+1 #mountaintable temp + lda ytraj+1 + cmp (temp),y ; check collision witch mountains + bcs ShotUnderGround jsr Flight mva #1 color rts +ShotUnderGround + mwa xtraj+1 xdraw ; but why not XHit and YHit !!!??? + mwa ytraj+1 ydraw + mva #$ff HitFlag + rts .endp @@ -1285,9 +1343,13 @@ AfterStrongShoot sta Parachute ; let's check if the given tank has got the parachute - lda #$35 ; parachute - jsr HowManyBullets - beq TankFallsX + ldx TankNr + lda ActiveDefenceWeapon,x + cmp #54 ; parachute + beq ParachuteActive + cmp #58 ; scheld witch energy and parachute + bne TankFallsX +ParachuteActive inc Parachute TankFallsX ; coordinates of the first pixel under the tank @@ -1489,6 +1551,11 @@ EndOfFall ; first we clear parachute on the screen mva #1 Erase ldx TankNr + lda ActiveDefenceWeapon,x + cmp #54 ; deactivate weapon only if parachute (53) + bne NoParachuteWeapon + mva #0 ActiveDefenceWeapon,x ; deactivate defence weapon (parachute) +NoParachuteWeapon lda #$34 sta CharCode lda Ytankstable,x @@ -1501,10 +1568,8 @@ EndOfFall sta xdraw+1 jsr TypeChar mva #0 Erase - ; now we can deduct one parachute from the list of weapons - - lda #$35 ; parachute - jsr DecreaseWeapon + ldx TankNr + jsr DrawTankNr ; redraw tank after erase parachute (exactly for redraw leaky schield :) ) ThereWasNoParachute mva #sfx_silencer sfx_effect rts @@ -1536,7 +1601,8 @@ ThereWasNoParachute noSmokeTracer sty SmokeTracerFlag -RepeatIfSmokeTracer +RepeatIfSmokeTracer +RepeatFlight mwa ytraj+1 Ytrajold+1 mwa xtraj+1 Xtrajold+1 mva #%01000000 drawFunction @@ -1775,8 +1841,6 @@ EndOfFlight jsr unPlot mwa xcircle xdraw mwa ycircle ydraw -; mwa XHit xdraw -; mva YHit ydraw ldy SmokeTracerFlag beq EndOfFlight2 @@ -1785,7 +1849,71 @@ EndOfFlight jmp SecondFlight EndOfFlight2 mva #0 tracerflag ; don't know why - rts + + ; and now check for defensive-aggressive weapon + lda HitFlag + jeq NoHitAtEndOfFight ; RTS only !!! + jmi NoTankHitAtEndOfFight + ; tank hit - check defensive weapon of this tank + tax + dex ; index of tank in X + lda ActiveDefenceWeapon,x + cmp #61 ; Auto Defence + beq AutoDefence + cmp #56 ; Mag Deflector + bne NoDefence +MagDeflector + ; now run defensive-aggressive weapon - Mag Deflector! + ; get tank position + clc + lda xtankstableL,x + adc #$04 ; almost in tak center :) + sta XHit + lda xtankstableH,x + adc #$00 + sta XHit+1 + lda #$ff ; change to ground hit (we hope) + sta HitFlag + bit random ; left or right deflection ? + bpl RightDeflection +LeftDeflection + sbw XHit #18 ; 18 pixels to right and explode... + bit XHit+1 ; if off-screen ... + bpl EndOfMagDeflector ; hit of course but we need RTS + adw XHit #36 ; change to right :) + jmp EndOfMagDeflector +RightDeflection + adw XHit #18 ; 18 pixels to right and explode... + cpw XHit screenwidth ; if off-screen ... + bcs EndOfMagDeflector ; hit of course but we need RTS + sbw XHit #36 ; change to left +EndOfMagDeflector + mwa XHit xdraw ; why? !!! +NoTankHitAtEndOfFight +NoHitAtEndOfFight +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) + lsrw Force ; Force = Force / 2 - becouse earlier we multiplied by 2 + mva #1 Erase ; now erase shield + phx + jsr DrawTankShield + jsr DrawTankShieldHorns + plx + lda #$00 + sta Erase + sta ActiveDefenceWeapon,x ; deactivate used Auto Defence + sta ShieldEnergy,x + sta xtraj ; prepare coordinates + sta ytraj + sta xtraj+2 + sta ytraj+2 + mwa XHit xtraj+1 + sbw YHit #5 ytraj+1 + mva #1 color + jmp RepeatFlight ; and repeat Fight .endp .proc SecondFlight @@ -2157,7 +2285,7 @@ MIRValreadyAll mva tempor2 TankNr mva #0 Erase jsr SoilDown2 - mva #1 HitFlag + mva #$ff HitFlag ; but why ?? ;jsr drawtanks rts .endp @@ -2168,7 +2296,7 @@ MIRValreadyAll ; Check collision with Tank :) ; xdraw , ydraw - coordinates of the checked point ; results: -; HitFlag - 1 - hit, 0 - no hit +; HitFlag - $ff - hit ground, 0 - no hit, 1-6 - hit tank (index+1) ; XHit , YHit - coordinates of hit ; X - index of the hit tank @@ -2176,31 +2304,40 @@ MIRValreadyAll CheckCollisionWithTankLoop lda eXistenZ,x beq DeadTank + ; first we test top and bottom (same with and without shield!) + lda ytankstable,x + cmp ydraw ; check range + bcc BelowTheTank ;(ytankstable,ytankstable+3) + sbc #4 ; we must rewrite EndOfTheBarrelY table or remove Y correction completely to "bold" tank !!! + cmp ydraw + bcs OverTheTank + ; with or without shield ? + lda ShieldEnergy,x + bne CheckCollisionWithShieldedTank ; tank with shield is bigger :) + lda xtankstableH,x cmp xdraw+1 - bne Condition01 + bne @+ lda xtankstableL,x cmp xdraw -Condition01 +@ bcs LeftFromTheTank ;add 8 double byte + ; now we use Y as low byte and A as high byte of checked position (right edge of tank) + ; it is tricky but fast and much shorter clc adc #8 tay lda xtankstableH,x adc #0 cmp xdraw+1 - bne Condition02 + bne @+ cpy xdraw -Condition02 +@ bcc RightFromTheTank - - lda ytankstable,x - cmp ydraw ; check range - bcc BelowTheTank ;(ytankstable,ytankstable+3) - sbc #4 - cmp ydraw - bcs OverTheTank - mva #1 HitFlag +TankHit + inx + stx HitFlag ; index of hit tank+1 + dex mwa xdraw XHit mwa ydraw YHit rts ; in X there is an index of the hit tank @@ -2213,6 +2350,33 @@ DeadTank cpx NumberOfPlayers bne CheckCollisionWithTankLoop rts +CheckCollisionWithShieldedTank + ; now we use Y as low byte and A as high byte of checked position (left right edgs of shield) + ; it is tricky but fast and much shorter + lda xtankstableL,x + sec + sbc #4 ; 5 pixels more on left side + tay + lda xtankstableH,x + sbc #0 + ; bmi ShieldOverLeftEdge ; I do not know whether to check it. Probably not :) !!! + cmp xdraw+1 + bne @+ + cpy xdraw +@ + bcs LeftFromTheTank + tya ;add 16 double byte + clc + adc #16 + tay + lda xtankstableH,x + adc #0 + cmp xdraw+1 + bne @+ + cpy xdraw +@ + bcc RightFromTheTank + bcs TankHit .endp ;-------------------------------------------------- CalculateExplosionRange0