diff --git a/Atari/display_static.asm b/Atari/display_static.asm index 135d2fb..5862ef4 100644 --- a/Atari/display_static.asm +++ b/Atari/display_static.asm @@ -9,7 +9,7 @@ OptionsScreen dta d"Welcome to Scorch v. " build ; 4 bytes from scorch.asm (fancy method) :) - dta d" (un)2000-2023" + dta d" (un)2000-2024" .IF TARGET = 800 dta d" Please select option with " diff --git a/Atari/gr_basics.asm b/Atari/gr_basics.asm index 6c8691f..c385235 100644 --- a/Atari/gr_basics.asm +++ b/Atari/gr_basics.asm @@ -109,6 +109,8 @@ EndOfUnPlot .proc plot ;plot (xdraw, ydraw, color) ; color == 1 --> put pixel ; color == 0 --> erase pixel +; xdraw (word) - X coordinate +; ydraw (word) - Y coordinate ; this is one of the most important routines in the whole ; game. If you are going to speed up the game, start with ; plot - it is used by every single effect starting from explosions @@ -165,9 +167,11 @@ ClearPlot .proc ExPlot ;ExPlot (EplotX, EplotY) ; EOR plot: ; Inverts color of a pixel +; EplotX (word) - X coordinate +; EplotY (byte) - Y coordinate ; Note: No coordinate control!!! ; With off-screen coordinates, it can damage main program. -; only for ingame meteors +; only for ingame meteors - for Atari only ; ----------------------------------------- ; let's calculate coordinates from xdraw and ydraw ;xbyte = xbyte/8 @@ -195,8 +199,10 @@ ClearPlot ; ----------------------------------------- .proc point_plot ; ----------------------------------------- - ; checks state of the pixel (coordinates in xdraw and ydraw) - ; result is in A (zero or appropriate bit is set) +; checks state of the pixel (coordinates in xdraw and ydraw) +; xdraw (word) - X coordinate +; ydraw (word) - Y coordinate +; result is in A (0 - point is set; appropriate bit is set - point is clear) INVERTED! ; let's calculate coordinates from xdraw and ydraw @@ -220,13 +226,15 @@ ClearPlot ldx xdraw ; optimization (256 bytes long bittable) lda (xbyte),y - eor #$ff and bittable1_long,x rts .endp ;-------------------------------------------------- .proc drawmountains ;-------------------------------------------------- +; draw mountains from mountaintable +; ClearSky - $ff Crear sky during drawmountains, 0 - no clear sky + mwa #0 xdraw mwa #mountaintable modify ; mountaintable pointer mva #1 color @@ -424,7 +432,7 @@ NothingToFall ;-------------------------------------------------- .proc SoilDownTurbo ;-------------------------------------------------- -; fast SoilDown froc - test +; fast SoilDown proc jsr ClearTanks NoClearTanks jsr CalcAndDrawMountains @@ -463,20 +471,21 @@ Fast ; Put char without coordinates check! ; and 8 bytes to the table ldy #7 + ldx #$ff ; otimization - thanks @Irgendwer CopyChar + txa ; $ff + sta char2,y lda (fontind),y eor #$ff sta char1,y - lda #$ff - sta char2,y dey bpl CopyChar ; and 8 subsequent bytes as a mask adw fontind #8 ldy #7 CopyMask - lda (fontind),y - eor #$ff + txa ; $ff + eor (fontind),y sta mask1,y lda #$00 sta mask2,y diff --git a/Atari/inputs.asm b/Atari/inputs.asm new file mode 100644 index 0000000..84037f6 --- /dev/null +++ b/Atari/inputs.asm @@ -0,0 +1,216 @@ +;-------------------------------------------------- +.proc GetKey +; waits for pressing a key and returns pressed value in A +; when [ESC] is pressed, escFlag is set +; result: A=keycode +;-------------------------------------------------- + jsr WaitForKeyRelease +getKeyAfterWait + jsr GetKeyFast + cmp #@kbcode._none + beq getKeyAfterWait + ldy #0 + sty ATRACT ; reset atract mode + mvy #sfx_keyclick sfx_effect + rts +.endp + +;-------------------------------------------------- +.proc GetKeyFast +; returns pressed value in A - no waits for press +; when [ESC] is pressed, escFlag is set +; result: A=keycode ($ff - no key pressed) +;-------------------------------------------------- + .IF TARGET = 800 + lda SKSTAT + cmp #$ff + beq checkJoyGetKey ; key not pressed, check Joy + cmp #$f7 ; SHIFT + beq checkJoyGetKey + .ELIF TARGET = 5200 + lda SkStatSimulator + and #%11111110 + bne checkJoyGetKey ; key not pressed, check Joy + .ENDIF + lda kbcode + cmp #@kbcode._none + beq checkJoyGetKey + pha + and #$3f ; CTRL and SHIFT ellimination + cmp #@kbcode._esc ; 28 ; ESC + beq EscPressed + pla + jmp getkeyend +EscPressed + pla + mvy #$80 escFlag + bne getkeyend + +checkJoyGetKey + ;------------JOY------------- + ;happy happy joy joy + ;check for joystick now + lda STICK0 + and #$0f + cmp #$0f + beq notpressedJoyGetKey + tay + lda joyToKeyTable,y + bne getkeyend + +notpressedJoyGetKey + ;fire + lda STRIG0 + beq JoyButton + .IF TARGET = 800 ; Second joy button , Select and Option key only on A800 + jsr Check2button + bcc SecondButton + bne checkSelectKey +checkSelectKey + lda CONSOL + and #%00000010 ; Select + beq SelectPressed + lda CONSOL + and #%00000100 ; Option + beq OptionPressed + .ENDIF + lda #@kbcode._none + bne getkeyend +OptionPressed + lda #@kbcode._atari ; Option key + bne getkeyend +SecondButton +SelectPressed + lda #@kbcode._tab ; Select key + bne getkeyend +JoyButton + lda #@kbcode._ret ; Return key +getkeyend + rts +; ---- + .IF TARGET = 800 ; Second joy button only on A800 +Check2button + lda PADDL0 + and #$c0 + eor #$C0 + cmp PaddleState + sta PaddleState + rts + .ENDIF +.endp + +;-------------------------------------------------- +.proc getkeynowait +;-------------------------------------------------- + jsr WaitForKeyRelease + lda kbcode + and #$3f ; CTRL and SHIFT ellimination + rts +.endp + +;-------------------------------------------------- +.proc WaitForLongPress +;-------------------------------------------------- + lda #0 + sta pressTimer ; reset + jsr WaitForKeyRelease.StillWait + lda pressTimer + cmp #25 ; 1/2s + rts ; if CARRY is set then long press +.endp + +;-------------------------------------------------- +.proc WaitForKeyRelease +;-------------------------------------------------- + lda #128-KeyRepeatSpeed ; tricky + sec + sbc FirstKeypressDelay ; tricky 2 :) + sta pressTimer +StillWait + bit pressTimer + bmi KeyAutoReleased + lda STICK0 + and #$0f + cmp #$0f + bne StillWait + lda STRIG0 + beq StillWait + .IF TARGET = 800 + lda SKSTAT + cmp #$ff + bne StillWait + lda CONSOL + and #%00000110 ; Select and Option only + cmp #%00000110 + bne StillWait + .ELIF TARGET = 5200 + lda SkStatSimulator + and #%11111110 + beq StillWait + .ENDIF +KeyReleased + mva #FirstKeySpeed FirstKeypressDelay + rts +KeyAutoReleased ; autorepeat + mva #0 FirstKeypressDelay + rts +.endp +/* ;-------------------------------------------------- +.proc IsKeyPressed +; result: A=0 - yes , A>0 - no +;-------------------------------------------------- + lda SKSTAT + and #%00000100 + beq @+ + lda STRIG0 +@ rts +.endp */ +;-------------------------------------------------- +.proc CheckStartKey +;-------------------------------------------------- + lda CONSOL ; turbo mode + and #%00000001 ; START KEY + rts +.endp +;-------------------------------------------------- +.proc CheckExitKeys +;-------------------------------------------------- +; Checks keyboard and sets appropriate flags for exit procedures +; If START+OPTION is pressed - exit to GameOver screen +; If 'O' key is pressed - displays "Are you sure?" and - exit to GameOver screen +; If 'Esc' key is pressed - displays "Are you sure?" and - exit to Menu screen +; Just setting the right flags!!! + + ; Select and Option + lda CONSOL + and #%00000101 ; Start + Option + beq QuitToGameover + lda SKSTAT + cmp #$ff + jeq nokeys + cmp #$f7 ; SHIFT + jeq nokeys + + lda kbcode + and #%10111111 ; SHIFT elimination + + cmp #@kbcode._O ; $08 ; O + bne CheckEsc + jsr AreYouSure + bit escFlag + bpl nokeys + ;---O pressed-quit game to game over screen--- +QuitToGameover + mva #$C0 escFlag ; bits 7 and 6 set + rts +CheckEsc + cmp #@kbcode._esc ; 28 ; ESC + bne nokeys +DisplayAreYouSure + jsr AreYouSure + ;---esc pressed-quit game--- +nokeys + bit escFlag + rts +; +.endp diff --git a/Atari/lib/5200MACRO.ASM b/Atari/lib/5200MACRO.ASM index 506a5cd..7747352 100644 --- a/Atari/lib/5200MACRO.ASM +++ b/Atari/lib/5200MACRO.ASM @@ -139,6 +139,16 @@ pla tay .endm +;------------------------------------- + .macro txy + txa + tay + .endm +;------------------------------------- + .macro tyx + tya + tax + .endm ;------------------------------------- .macro pause ;waits :1 number (byte) of frames diff --git a/Atari/lib/ATARISYS.ASM b/Atari/lib/ATARISYS.ASM index 7c031de..3fa62a6 100644 --- a/Atari/lib/ATARISYS.ASM +++ b/Atari/lib/ATARISYS.ASM @@ -67,12 +67,12 @@ PHINIV EQU $E48C ;UPLOADED HANDLER INIT ; ; COMMAND CODES FOR IOCBS ; -OPEN EQU $03 ;OPEN FOR I/O +_OPEN EQU $03 ;OPEN FOR I/O GETREC EQU $05 ;GET RECORD (TEXT) GETCHR EQU $07 ;GET CHARACTER(S) PUTREC EQU $09 ;PUT RECORD (TEXT) PUTCHR EQU $0B ;PUT CHARACTER(S) -CLOSE EQU $0C ;CLOSE DEVICE +_CLOSE EQU $0C ;CLOSE DEVICE STATIS EQU $0D ;STATUS REQUEST SPECIL EQU $0E ;SPECIAL ENTRY COMMAND ; @@ -135,6 +135,7 @@ DERRER EQU $90 ;PERIPHRAL DEVICE ERR BADMOD EQU $91 ;BAD SCREEN MODE # FNCNOT EQU $92 ;NONEXISTANT FUNCTION SCRMEM EQU $93 ;SCREEN MEM TOO SMALL +FILENF EQU $AA ;FILE NOT FOUND ; ; PAGE ZERO RAM ASSIGNMENTS ; @@ -376,7 +377,7 @@ CBAUDL EQU $02EE ;CASSETTE BAUD RATE CBAUDH EQU $02EF CRSINH EQU $02F0 ;CURSOR INHIBIT 0=ON KEYDEL EQU $02F1 ;KEY DELAY -CH1 EQU $02F2 ;PRIOR KB CHAR CODE +CH1 EQU $02F2 ;PRIOR KB CHAR CODE CHACT EQU $02F3 ;CHACTL REGISTER RAM CHBAS EQU $02F4 ;CHBAS REGISTER RAM NEWROW EQU $02F5 ;POINT DRAW GOES TO @@ -593,11 +594,11 @@ PBCTL EQU PIA+3 ; --------------------------------------------------------------------------- ; JUMP EQU $01 ; display list jump instruction (3 byte) -JVB EQU $41 ; display list jump and wait for vblank instruction (3) +JVB EQU $41 ; display list jump and wait for vblank instruction (3) ; -SCH EQU $10 ; display list horizontal scrolling -SCV EQU $20 ; display list vertical scrolling -LMS EQU $40 ; display list load memory scan instruction (3 byte) +SCH EQU $10 ; display list horizontal scrolling +SCV EQU $20 ; display list vertical scrolling +LMS EQU $40 ; display list load memory scan instruction (3 byte) DLII EQU $80 ; display list interrupt instruction ; SKIP1 EQU $00 ; display list skip 1 scan line instruction @@ -656,67 +657,68 @@ scr32 = @dmactl(narrow|dma|players|missiles|lineX1) ; KBCODEs ; --------------------------------------------------------------------------- .enum @kbcode - _none = 255 - _esc = 28 - _1 = 31 - _2 = 30 - _3 = 26 - _4 = 24 - _5 = 29 - _6 = 27 - _7 = 51 - _8 = 53 - _9 = 48 - _0 = 50 - _lt = 54 - _gt = 55 - _del = 52 - _tab = 44 - _Q = 47 - _W = 46 - _E = 42 - _R = 40 - _T = 45 - _Y = 43 - _U = 11 - _I = 13 - _O = 8 - _P = 10 - _min = 14 - _up = 14 ; cursor function - _eq = 15 - _down = 15 ; cursor function - _ret = 12 - _A = 63 - _S = 62 - _D = 58 - _F = 56 - _G = 61 - _H = 57 - _J = 1 - _K = 5 - _L = 0 + _none = 255 + _esc = 28 + _1 = 31 + _2 = 30 + _3 = 26 + _4 = 24 + _5 = 29 + _6 = 27 + _7 = 51 + _8 = 53 + _9 = 48 + _0 = 50 + _lt = 54 + _gt = 55 + _del = 52 + _tab = 44 + _Q = 47 + _W = 46 + _E = 42 + _R = 40 + _T = 45 + _Y = 43 + _U = 11 + _I = 13 + _O = 8 + _P = 10 + _min = 14 + _up = 14 ; cursor function + _eq = 15 + _down = 15 ; cursor function + _ret = 12 + _A = 63 + _S = 62 + _D = 58 + _F = 56 + _G = 61 + _H = 57 + _J = 1 + _K = 5 + _L = 0 _semicolon = 2 - _plus = 6 - _left = 6 ; cursor function + _plus = 6 + _left = 6 ; cursor function _asterisk = 7 _right = 7 ; cursor function - _caps = 60 - _Z = 23 - _X = 22 - _C = 18 - _V = 16 - _B = 21 - _N = 36 - _M = 37 + _caps = 60 + _Z = 23 + _X = 22 + _C = 18 + _V = 16 + _B = 21 + _N = 36 + _M = 37 _comma = 32 - _dot = 34 + _dot = 34 _slash = 38 _atari = 39 - _help = 17 - _F1 = 3 - _F2 = 4 - _F3 = 19 - _F4 = 20 + _help = 17 + _F1 = 3 + _F2 = 4 + _F3 = 19 + _F4 = 20 _space = 33 -.ende \ No newline at end of file +.ende +EOL = $9b \ No newline at end of file diff --git a/Atari/lib/MACRO.ASM b/Atari/lib/MACRO.ASM index 6ded402..1ce890a 100644 --- a/Atari/lib/MACRO.ASM +++ b/Atari/lib/MACRO.ASM @@ -160,6 +160,16 @@ pla tay .endm +;------------------------------------- + .macro txy + txa + tay + .endm +;------------------------------------- + .macro tyx + tya + tax + .endm ;------------------------------------- .macro pause ;waits :1 number (byte) of frames diff --git a/Atari/lib/cartloader_vectors.inc b/Atari/lib/cartloader_vectors.inc index 889405b..662ca71 100644 --- a/Atari/lib/cartloader_vectors.inc +++ b/Atari/lib/cartloader_vectors.inc @@ -1,6 +1,6 @@ X_LOADER_START = $0700; X_BANK = $074E; -X_SRC = $07CA; +X_SRC = $07D0; X_CLRSTART = $071D; X_CLREND = $0728; X_PORTB = $0707; diff --git a/Atari/textproc.asm b/Atari/textproc.asm index 6b79b24..7feb777 100644 --- a/Atari/textproc.asm +++ b/Atari/textproc.asm @@ -78,7 +78,7 @@ OptionsMainLoop jsr OptionsInversion - jsr getkey + jsr GetKey bit escFlag spl:rts @@ -124,11 +124,16 @@ OptionsNoLeft OptionsNoRight cmp #@kbcode._ret ; $c ;Return key bne OptionsNoReturn + ; wait for long press + jsr WaitForLongPress + bcs TabPressed ; if long press (fire or Return) +EndOfOptions rts ; options selected OptionsNoReturn cmp #@kbcode._tab ; Tab key bne OptionsNoTab +TabPressed jsr SelectNextGradient OptionsNoTab jmp OptionsMainLoop @@ -409,7 +414,13 @@ ChoosingItemForPurchase cmp #@kbcode._left ; $06 ; cursor left jeq ListChange cmp #@kbcode._ret ; $0c ; Return - sne:rts + bne NoReturn + jsr WaitForLongPress + bcc exitthismenu ; short press + jmp PurchaseWeaponNow ; long press +exitthismenu + rts +NoReturn cmp #@kbcode._up ; $e beq PurchaseKeyUp cmp #@kbcode._down ; $f @@ -872,13 +883,14 @@ NotBarrel 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 +NoDeactivateWhiteFlag + ; Activate White Flag (or deactivate if A=0) sta ActiveDefenceWeapon,x sta ShieldEnergy,x - beq DefActivationEnd + mva #sfx_white_flag sfx_effect + bne DefActivationEnd NotWhiteFlag -NoDeactivateWhiteFlag ; activate new defensive sta ActiveDefenceWeapon,x ; set defensive energy @@ -1727,8 +1739,9 @@ FastTank ; ldx TankNr dex bpl AllTanksFloatingDown - jsr IsKeyPressed - bne MainTanksFloatingLoop ; neverending loop + jsr GetKeyFast + cmp #@kbcode._none + beq MainTanksFloatingLoop ; neverending loop mva #$00 ScrollFlag ; credits scroll off jmp MakeDarkScreen ; jsr GameOverResultsClear diff --git a/C64/gr_basics.asm b/C64/gr_basics.asm index 860ae9d..d497343 100644 --- a/C64/gr_basics.asm +++ b/C64/gr_basics.asm @@ -101,6 +101,8 @@ EndOfUnPlot .proc plot ;plot (xdraw, ydraw, color) ; color == 1 --> put pixel ; color == 0 --> erase pixel +; xdraw (word) - X coordinate +; ydraw (word) - Y coordinate ; this is one of the most important routines in the whole ; game. If you are going to speed up the game, start with ; plot - it is used by every single effect starting from explosions @@ -154,8 +156,10 @@ ClearPlot ; ----------------------------------------- .proc point_plot ; ----------------------------------------- - ; checks state of the pixel (coordinates in xdraw and ydraw) - ; result is in A (zero or appropriate bit is set) +; checks state of the pixel (coordinates in xdraw and ydraw) +; xdraw (word) - X coordinate +; ydraw (word) - Y coordinate +; result is in A (0 - point is set; appropriate bit is set - point is clear) INVERTED! ; let's calculate coordinates from xdraw and ydraw @@ -178,13 +182,14 @@ ClearPlot ldy #0 lda (xbyte),y - eor #$ff and bittable1_long,x rts .endp ;-------------------------------------------------- .proc drawmountains ;-------------------------------------------------- +; draw mountains from mountaintable +; ClearSky - $ff Crear sky during drawmountains, 0 - no clear sky mwa #0 xdraw mwa #mountaintable modify mva #1 color @@ -212,6 +217,29 @@ NotLower bpl @- sta temp2 inc temp2 ; this is our minimum + bit ClearSky + bpl NoClearSky + ; Clear Sky + mwa #0 ydraw + jsr plot.MakePlot ; after plot we have: (xbyte),y - addres of screen byte +@ lda #$ff + sta (xbyte),y + adw xbyte #screenBytes ; next line + inc ydraw + lda xdraw + ldy ydraw + clc + adc linetableL,y + sta xbyte + lda linetableH,y + adc xdraw+1 + sta xbyte+1 + tya + cmp #screenheight + beq NoClearSky + cmp temp2 ; our minimum height od sky + bne @- +NoClearSky MinCalculated ldy #0 lda (modify),y @@ -284,6 +312,22 @@ MinCalculated bne @- NotFillBytes .ELSE + bit ClearSky + bpl NoClearSky + ; Clear Sky + ldy #0 + lda (modify),y + sta ydraw + sty ydraw+1 + sty color +clearline + jsr plot.MakePlot + dec ydraw + lda ydraw + cmp #$ff + bne clearline + mva #1 color +NoClearSky ldy #0 lda (modify),y cmp #screenheight @@ -305,10 +349,10 @@ NoMountain ;-------------------------------------------------- .proc SoilDownTurbo ;-------------------------------------------------- -; fast SoilDown froc - test +; fast SoilDown proc jsr ClearTanks NoClearTanks -; jsr CalcAndDrawMountains +; jsr CalcAndDrawMountains - to do (now Atari only) jmp DrawTanks ;rts .endp @@ -344,20 +388,21 @@ Fast ; Put char without coordinates check! ; and 8 bytes to the table ldy #7 + ldx #$ff ; otimization - thanks @Irgendwer CopyChar + txa ; $ff + sta char2,y lda (fontind),y eor #$ff sta char1,y - lda #$ff - sta char2,y dey bpl CopyChar ; and 8 subsequent bytes as a mask adw fontind #8 ldy #7 CopyMask - lda (fontind),y - eor #$ff + txa ; $ff + eor (fontind),y sta mask1,y lda #$00 sta mask2,y diff --git a/C64/inputs.asm b/C64/inputs.asm new file mode 100644 index 0000000..24b225e --- /dev/null +++ b/C64/inputs.asm @@ -0,0 +1,74 @@ +;-------------------------------------------------- +.proc GetKey +; waits for pressing a key and returns pressed value in A +; when [ESC] is pressed, escFlag is set +; result: A=keycode +;-------------------------------------------------- + jsr WaitForKeyRelease + jsr GetKeyFast + ldy #0 + sty escFlag + rts +.endp + +;-------------------------------------------------- +.proc GetKeyFast +; returns pressed value in A - no wait for press +; when [ESC] is pressed, escFlag is set +; result: A=keycode +;-------------------------------------------------- + lda #$ff + rts +.endp + +;-------------------------------------------------- +.proc getkeynowait +;-------------------------------------------------- + jsr WaitForKeyRelease + lda kbcode + and #$3f ;CTRL and SHIFT ellimination + rts +.endp + +;-------------------------------------------------- +.proc WaitForLongPress +;-------------------------------------------------- + lda #0 + sta pressTimer ; reset + jsr WaitForKeyRelease.StillWait + lda pressTimer + cmp #25 ; 1/2s + rts ; if CARRY is set then long press +.endp + +;-------------------------------------------------- +.proc WaitForKeyRelease +;-------------------------------------------------- +StillWait + rts +.endp +;-------------------------------------------------- +.proc IsKeyPressed +; result: A=0 - yes , A>0 - no +;-------------------------------------------------- + lda #1 + rts +.endp +;-------------------------------------------------- +.proc CheckStartKey +;-------------------------------------------------- + lda #%00000001 ; START KEY not pressed + rts +.endp +;-------------------------------------------------- +.proc CheckExitKeys +;-------------------------------------------------- +; Checks keyboard and sets appropriate flags for exit procedures +; If START+OPTION is pressed - exit to GameOver screen +; If 'O' key is pressed - displays "Are you sure?" and - exit to GameOver screen +; If 'Esc' key is pressed - displays "Are you sure?" and - exit to Menu screen +; Just setting the right flags!!! + mva #$00 escFlag ; flag cleared + rts +; +.endp diff --git a/C64/lib/MACRO.ASM b/C64/lib/MACRO.ASM index c61d971..393e517 100644 --- a/C64/lib/MACRO.ASM +++ b/C64/lib/MACRO.ASM @@ -278,6 +278,16 @@ upstartEnd pla tay .endm +;------------------------------------- + .macro txy + txa + tay + .endm +;------------------------------------- + .macro tyx + tya + tax + .endm ;------------------------------------- .MACRO WAIT ; WAIT diff --git a/Manuals/MANUAL_EN.bin b/Manuals/MANUAL_EN.bin index f6c189d..b75a473 100644 Binary files a/Manuals/MANUAL_EN.bin and b/Manuals/MANUAL_EN.bin differ diff --git a/Manuals/MANUAL_EN.md b/Manuals/MANUAL_EN.md index c20db50..ca930bf 100644 --- a/Manuals/MANUAL_EN.md +++ b/Manuals/MANUAL_EN.md @@ -39,7 +39,7 @@ On the first screen, you can configure gameplay options: Select options with cursor keys or a joystick. -The **TAB**, **SELECT**, or second joystick button (supported Joy 2B+ standard or compatible), and on the Atari 5200 console, the **5** controller key changes the color of the mountains (3 versions to choose from). +The **TAB**, **SELECT**, long press of first joystick button or second joystick button (supported Joy 2B+ standard or compatible), and on the Atari 5200 console, the **5** controller key changes the color of the mountains (3 versions to choose from). If the cursor indicates the wind strength selection option **Wind**, pressing **TAB** changes the way the wind strength is drawn from "every round" to "every turn" and vice versa. Drawing every turn is indicated by the **?** sign next to the word **Wind**. @@ -71,7 +71,7 @@ If a name is not entered, it will be supplemented with the default one. ## 3. Shopping screen (before each round) ![Shopping offensives screen.](images/PurOffensive.png) ![Shopping defensives screen.](images/PurDefensive.png) -On this screen, you can make purchases of offensive and defensive weapons. Only those weapons that the player can afford are visible, along with information about the price and the number of units of a given weapon that will be obtained for that price. You move through the lists with the cursor keys (up and down) or with the joystick, the **TAB** key or the left arrow, the left joystick tilt or second joystick button changes the screen to defensive or offensive weapons, the **SPACE** key or the right arrow and also the joystick to the right does the purchase of the indicated weapon. +On this screen, you can make purchases of offensive and defensive weapons. Only those weapons that the player can afford are visible, along with information about the price and the number of units of a given weapon that will be obtained for that price. You move through the lists with the cursor keys (up and down) or with the joystick, the **TAB** key or the left arrow, the left joystick tilt or second joystick button changes the screen to defensive or offensive weapons, the **SPACE** key, the right arrow, long press of first joystick button and also the joystick to the right does the purchase of the indicated weapon. The **RETURN** key or the joystick button press switches to the defensive weapon activation screen. Here you can activate previously bought defensive (or offensive after switching with **TAB**, etc) weapons. @@ -231,7 +231,6 @@ And here are the values of maximum energy loss for individual weapons. If a weap | Riot Blast | 0 (↓) | | Riot Bomb | 0 (↓) | | Heavy Riot Bomb | 0 (↓) | -| Baby Digger | 0 (↓) | | Digger | 0 (↓) | | Heavy Digger | 0 (↓) | | Sandhog | 0 (↓) | @@ -241,6 +240,7 @@ And here are the values of maximum energy loss for individual weapons. If a weap | Ton of Dirt | 0 (↓) | | Liquid Dirt | 0 (↓) | | Dirt Charge | 0 (↓) | +| Propaganda | 0 (↓) | | Stomp | 0 (↓) | | Laser | 100 (↓) | @@ -257,11 +257,9 @@ Remarks: * **Heavy Riot Bomb** as in **Riot Bomb**, but the explosion radius is 29 pixels from the point of impact - as in the case of **Nuke** -* **Baby Digger** - no energy is subtracted, but a portion of the soil is dug in a radius of 60 pixels from the point of impact. +* **Digger** - no energy is subtracted, but a portion of the soil is dug in a radius of 60 pixels from the point of impact. -* **Digger** - as above - more digging. - -* **Heavy Digger** - as above - even more digging. +* **Heavy Digger** - as above - more digging. * **Sandhog** - as above - another way of digging @@ -275,6 +273,8 @@ Remarks: * **Liquid Dirt** - (floods the ground at the point of hit with liquid soil, filling in the depressions. +* **Propaganda** - no energy is subtracted, but the point of the hit is covered with propaganda texts. + * **Stomp** - no energy is subtracted, but all tanks within a radius depending on the force of the shot are pushed back, and after being pushed back they may fall or be buried. With a maximum force of 990 units, the radius of action is about 60 pixels. * **Laser** - 100 energy units deducted, but only in the case of a direct hit - that is, the hit tank always dies. @@ -302,7 +302,7 @@ Remarks: * **Nuclear Winter** - adds nothing, takes nothing away :) - in fact, it is not so much a defensive weapon as a double-edged one. It floods the area with "radioactive" fallout, which is ordinary soil. If you do not have at hand any weapon that digs up the terrain, and for that a shield (preferably disposable), then after such "fallout" you will have to shoot yourself - because being underground is otherwise impossible. Alternatively, **White Flag** always remains. -* **Long Schlong** - a special weapon :) - Costs a lot, doesn't help with anything (except possibly digging yourself out but only when slightly buried but it has a cool name and looks cool :) - It can be activated independently of other defensive weapons and remains active until the end of the round (it cannot be deactivated). +* **Long Schlong** - a special weapon :) - Costs a lot, doesn't help with anything (except possibly digging yourself out but only when slightly buried but it has a cool name and looks cool :) - It can be activated independently of other defensive weapons and remains active until the end of the round (it cannot be deactivated). This weapon has a depressing effect on computer-controlled opponents at **Poolshark** level and above. * **Lazy Boy** - it is not a defensive weapon. It is an aiming aid. When it is activated, the tank tries to aim at the nearest enemy and automatically adjusts the power of the shot and angle. If it has too little energy, it can sometimes aim wrong (it uses a method like **Cyborg** to aim). Like **Battery**, it does not deactivate other defensive weapons when used. Note: There is no point in activating this weapon before the round, targeting will not take place because there is nothing to target yet. @@ -397,9 +397,9 @@ In a hopeless situation, self-destruction might be a better option than waving t **Long Schlong** has got serious intimidating power. Become the alpha tank and fear not. -As a last resort, you can always become a Terminator (the standard model, not T-1000 :) ). - Robo-tanks do not possess **Autodefense**, so their defenses activate only directly before their shot. A concentrated attack by several players on one robo tank guarantees success. +As a last resort, you can always become a Terminator (the standard model, not T-1000 :) ). + Break a barrel or two. diff --git a/Manuals/MANUAL_PL_A800.bin b/Manuals/MANUAL_PL_A800.bin index 55cf06b..13c30f8 100644 Binary files a/Manuals/MANUAL_PL_A800.bin and b/Manuals/MANUAL_PL_A800.bin differ diff --git a/Manuals/MANUAL_PL_A800.md b/Manuals/MANUAL_PL_A800.md index ce05d95..89aaeef 100644 --- a/Manuals/MANUAL_PL_A800.md +++ b/Manuals/MANUAL_PL_A800.md @@ -39,7 +39,7 @@ Na pierwszym ekranie możemy skonfigurować opcje rozgrywki: Wybór opcji klawiszami kursora lub joystickiem. -Klawisz **TAB**, **SELECT** lub drugi przycisk joysticka (wspierany standard Joy 2B+ lub zgodny) zmieniają kolor gór (3 wersje do wyboru). +Klawisz **TAB**, **SELECT**, dłuższe przytrzymanie pierwszego przycisku joysticka lub drugi przycisk joysticka (wspierany standard Joy 2B+ lub zgodny) zmieniają kolor gór (3 wersje do wyboru). Jeśli kursor wskazuje opcję wyboru siły wiatru **Wind**, wciśnięcie **TAB** zmienia sposób losowania siły wiatru z "co rundę" na "co turę" i odwrotnie. Losowanie co turę jest sygnalizowane znakiem "?" przy słowie **Wind**. @@ -72,7 +72,7 @@ Jeśli nazwa nie zostanie wpisana, to zostanie uzupełniona nazwą domyślną. ## 3. Ekran zakupów (przed każdą rundą). ![Ekran zakupów broni ofensywnych.](images/PurOffensive.png) ![Ekran zakupów broni defensywnych.](images/PurDefensive.png) -Na tym ekranie można dokonywać zakupów broni ofensywnych i defensywnych. Widoczne są tylko te bronie, na które gracza stać wraz z informacją o cenie i ilości jednostek danej broni, którą za tę cenę otrzymamy. Informacje na ekranie nie wymagają chyba więcej opisu. Po listach poruszamy się klawiszami kursora (góra i dół) lub joystickiem, klawisz **TAB** lub strzałka w lewo, czy też ruch joystickiem w lewo lub drugi przycisk joysticka zmieniają ekran na bronie defensywne lub ofensywne, klawisz **SPACJA** lub strzałka w prawo, a także joystick w prawo realizują zakup wskazanej broni. +Na tym ekranie można dokonywać zakupów broni ofensywnych i defensywnych. Widoczne są tylko te bronie, na które gracza stać wraz z informacją o cenie i ilości jednostek danej broni, którą za tę cenę otrzymamy. Informacje na ekranie nie wymagają chyba więcej opisu. Po listach poruszamy się klawiszami kursora (góra i dół) lub joystickiem, klawisz **TAB** lub strzałka w lewo, czy też ruch joystickiem w lewo lub drugi przycisk joysticka zmieniają ekran na bronie defensywne lub ofensywne, klawisz **SPACJA** , strzałka w prawo, dłuższe przytrzymanie przycisku joysticka, a także joystick w prawo realizują zakup wskazanej broni. Klawisz **RETURN** lub przycisk joysticka przechodzi do ekranu aktywacji broni defensywnych. @@ -229,7 +229,6 @@ A oto wartości maksymalnego ubytku energii dla poszczególnych broni. Jeśli br | Riot Blast | 0 (↓)| | Riot Bomb | 0 (↓)| | Heavy Riot Bomb | 0 (↓)| -| Baby Digger | 0 (↓)| | Digger | 0 (↓)| | Heavy Digger | 0 (↓)| | Sandhog | 0 (↓)| @@ -239,6 +238,7 @@ A oto wartości maksymalnego ubytku energii dla poszczególnych broni. Jeśli br | Ton of Dirt | 0 (↓)| | Liquid Dirt | 0 (↓)| | Dirt Charge | 0 (↓)| +| Propaganda | 0 (↓)| | Stomp | 0 (↓)| | Laser | 100 (↓)| @@ -255,11 +255,9 @@ Uwagi: * **Heavy Riot Bomb** - jak w Riot Bomb, ale promień eksplozji to 29 pikseli od punktu trafienia - tak jak w wypadku **Nuke**. -* **Baby Digger** - nie jest odejmowana energia, ale podkopywana jest część gruntu promieniu 60 pikseli od punktu trafienia. +* **Digger** - nie jest odejmowana energia, ale podkopywana jest część gruntu promieniu 60 pikseli od punktu trafienia. -* **Digger** - jak wyżej - większy podkop. - -* **Heavy Digger** - jak wyżej - największy podkop. +* **Heavy Digger** - jak wyżej - większy podkop. * **Sandhog** - jak wyżej - inny sposób podkopywania. @@ -275,6 +273,8 @@ Uwagi: * **Dirt Charge** - nie jest odejmowana energia, ale usypywany jest dodatkowy grunt w górę od punktu trafienia w promieniu 61 pikseli. Broń przydatna do zakopywania przeciwnika. +* **Propaganda** - nie jest odejmowana energia, miejsce trafienia zostaje zasypane propagandowymi tekstami. + * **Stomp** - nie jest odejmowana energia, ale wszystkie czołgi w promieniu zależnym od siły strzału zostają odepchnięte, a po odepchnięciu mogą spaść lub zostać zasypane. Przy maksymalnej sile 990 jednostek promień działania to około 60 pikseli. * **Laser** - tu także jest inaczej - równo 100 tylko w przypadku bezpośredniego trafienia po prostu odejmujemy 100 jednostek energii - czyli czołg zawsze ginie. @@ -304,7 +304,7 @@ Uwagi: * **Nuclear Winter** - nic nie dodaje, nic nie zabiera :) - w zasadzie to broń nie tyle defensywna, co obosieczna. Zasypuje teren opadem "radioaktywnym", który jest zwyczajną glebą. Jeśli nie mamy pod ręką żadnej broni odkopującej teren i do tego osłony (najlepiej jednorazowej), to po takim "opadzie" będzie trzeba strzelić do siebie - bo będąc pod ziemią inaczej się nie da. Ewentualnie pozostaje zawsze White Flag. -* **Long Schlong** - broń specjalna :) - kosztuje dużo, nie bardzo w czymkolwiek pomaga (poza ewentualnym odkopaniem się - tylko przy niewielkim przysypaniu - ale fajnie się nazywa i wygląda :) - Można ją aktywować niezależnie od innych broni defensywnych i pozostaje aktywna do końca rundy (nie da się jej dezaktywować). +* **Long Schlong** - broń specjalna :) - kosztuje dużo, nie bardzo w czymkolwiek pomaga (poza ewentualnym odkopaniem się - tylko przy niewielkim przysypaniu - ale fajnie się nazywa i wygląda :) - Można ją aktywować niezależnie od innych broni defensywnych i pozostaje aktywna do końca rundy (nie da się jej dezaktywować). Broń ta działa deprymująco na przeciwników sterowanych przez komputer na poziomie **Poolshark** i wyższych. * **Lazy Boy** - nie jest to właściwie broń defensywna. Jest to wspomaganie celowania. Po jej aktywacji czołg stara się wycelować w najbliższego przeciwnika i automatycznie ustawia siłę strzału oraz kąt. W przypadku posiadania zbyt małej ilości energii może czasem wycelować źle (do celowania stosuje metodę taką jak **Cyborg**). Tak jak **Battery** nie dezaktywuje innych broni defensywnych w przypadku jej użycia. Uwaga! Nie ma sensu aktywacja tej broni przed rundą, celowanie nie odbędzie się, bo nie ma jeszcze do czego celować. @@ -400,8 +400,8 @@ W sytuacji beznadziejnej smobójstwo może być lepsze od **White Flag**. Jeśli **Long Schlong** potrafi znacząco onieśmielić przeciwników. Bądź alfa-czołgiem i porzuć wszelkie lęki. -W ostateczności możesz zostać Terminatorem (model standardowy, nie T-1000 :) ) - Roboczołgi nie mają **Autodefense**, więc defensywy aktywują tylko bezpośrednio przed swoim strzałem. Zmasowany atak kilku graczy na jednego roboczołga gwarantuje sukces. +W ostateczności możesz zostać Terminatorem (model standardowy, nie T-1000 :) ) + Połamania luf życzą autorzy. diff --git a/Manuals/man_cart_txt_EN.asm b/Manuals/man_cart_txt_EN.asm deleted file mode 100644 index 59b3975..0000000 --- a/Manuals/man_cart_txt_EN.asm +++ /dev/null @@ -1,1912 +0,0 @@ - .align 40 - dta " Basic instruction manual:" - .align 40 - dta "---------------------------" - .align 40 - .align 40 - dta "You can play using the keyboard (all" - .align 40 - dta "functionality) or controllers in all of" - .align 40 - dta "the ports (all functionality necessary" - .align 40 - dta "for gameplay)." - .align 40 - .align 40 - dta " 1. Game Option Selection." - .align 40 - dta "---------------------------" - .align 40 - .align 40 - .align 40 - dta "On the first screen, you can configure" - .align 40 - dta "gameplay options:" - .align 40 - dta $5a, d" number of players (2 - 6) includes" - .align 40 - dta "both human and computer-controlled" - .align 40 - dta "players" - .align 40 - dta $5a, d" the initial amount of cash of each" - .align 40 - dta "player (2K is the optimal value we" - .align 40 - dta "chose, but for short games, it is worth" - .align 40 - dta "choosing a higher value)" - .align 40 - dta $5a, d" gravity" - .align 40 - dta $5a, d" maximum wind strength (wind is drawn" - .align 40 - dta "at the beginning of each round or during" - .align 40 - dta "the round between turns, here we can" - .align 40 - dta "choose how strong it can be):" - .align 40 - dta d" ", $5a, d" 1B - maximum wind strength: 5" - .align 40 - dta d" ", $5a, d" 3B - maximum wind strength: 20" - .align 40 - dta d" ", $5a, d" 5B - maximum wind strength: 40" - .align 40 - dta d" ", $5a, d" 7B - maximum wind strength: 70" - .align 40 - dta d" ", $5a, d" 9B - maximum wind strength: 99" - .align 40 - dta $5a, d" number of rounds in a game" - .align 40 - dta $5a, d" missile speed (does not affect the" - .align 40 - dta "flight path - only changes the apparent" - .align 40 - dta "missile speed - does not change anything" - .align 40 - dta "in the gameplay itself)" - .align 40 - dta $5a, d" frequency of suicides :) - if for a" - .align 40 - dta "number of turns the game has not" - .align 40 - dta "recorded hits (tanks are constantly" - .align 40 - dta "shooting inaccurately), after one of" - .align 40 - dta "such misses a tank commits suicide -" - .align 40 - dta "here you determine how long they can" - .align 40 - dta """shooting for the stars"" :) - if only" - .align 40 - dta "people play the optimal setting is" - .align 40 - dta """norm"", in the case of" - .align 40 - dta "computer-controlled players ... you" - .align 40 - dta "choose." - .align 40 - dta $5a, d" The height (and undulation) of the" - .align 40 - dta "mountains from almost flat (NL - Kingdom" - .align 40 - dta "of the Netherlands), to soaring and high" - .align 40 - dta "(NP - Federal Democratic Republic of" - .align 40 - dta "Nepal)" - .align 40 - dta $5a, d" the way the walls (edges of the" - .align 40 - dta "screen) work:" - .align 40 - dta $5a, d" none - projectiles that flew off the" - .align 40 - dta "screen do not return (black color of the" - .align 40 - dta "screen frame)" - .align 40 - dta $5a, d" wrap - the screen ""wraps"" and" - .align 40 - dta "projectiles that flew to the right" - .align 40 - dta "appear on the left side and vice versa" - .align 40 - dta "(purple color of the screen frame)" - .align 40 - dta $5a, d" bump - the right and left walls" - .align 40 - dta "deflect projectiles that want to fly" - .align 40 - dta "through them (dark blue color of the" - .align 40 - dta "screen frame)" - .align 40 - dta $5a, d" boxy - just like bump, except that the" - .align 40 - dta """ceiling"" also reflects projectiles" - .align 40 - dta "(green color of the screen frame)" - .align 40 - dta $5a, d" rand - at the beginning of each round," - .align 40 - dta "one of the above 4 ways the walls work" - .align 40 - dta "is drawn." - .align 40 - .align 40 - dta "During gameplay, the current mode of the" - .align 40 - dta "walls is represented by the color of the" - .align 40 - dta "screen frame:" - .align 40 - dta $5a, d" none - black," - .align 40 - dta $5a, d" wrap - purple," - .align 40 - dta $5a, d" bump - dark blue," - .align 40 - dta $5a, d" boxy - green." - .align 40 - .align 40 - dta "Select options with cursor keys or a" - .align 40 - dta "controller." - .align 40 - .align 40 - dta "The [TAB], [SELECT] or second controller" - .align 40 - dta "button (supported Joy 2B+ standard or" - .align 40 - dta "compatible) key change the color of the" - .align 40 - dta "mountains (3 versions to choose from)." - .align 40 - dta "If the cursor indicates the wind" - .align 40 - dta "strength selection option ""Wind"" change" - .align 40 - dta "the way the wind strength is drawn from" - .align 40 - dta """every round"" to ""every turn"" and vice" - .align 40 - dta "versa. Drawing every turn is indicated" - .align 40 - dta "by the ""?"" sign next to the word ""Wind""." - .align 40 - dta "If the cursor indicates the gravity" - .align 40 - dta "selection option ""Gravity"" changes the" - .align 40 - dta "procedure of falling the ground to a" - .align 40 - dta "less impressive but faster one, and vice" - .align 40 - dta "versa. The selection of fast ground fall" - .align 40 - dta "is indicated by the letter ""f"" next to" - .align 40 - dta "the word ""Gravity""." - .align 40 - .align 40 - dta "The [RETURN] key or a controller button" - .align 40 - dta "moves to the next screen." - .align 40 - .align 40 - dta " 2. Names of players and AI opponents" - .align 40 - dta "--------------------------------------" - .align 40 - .align 40 - .align 40 - dta "The second screen is shown for each" - .align 40 - dta "player. Here you can use the cursor keys" - .align 40 - dta "or controller to select whether the tank" - .align 40 - dta "will be driven by a human (HUMAN option)" - .align 40 - dta "or a computer (other options)." - .align 40 - dta "The [TAB], [SELECT] or second controller" - .align 40 - dta "button allows to choose which controller" - .align 40 - dta "port the player will use." - .align 40 - dta "The [INVERSE] or [OPTION] key allows you" - .align 40 - dta "to select one of the 3 available tank" - .align 40 - dta "shapes." - .align 40 - dta "At the same time, you can enter the name" - .align 40 - dta "of the selected player from the" - .align 40 - dta "keyboard." - .align 40 - dta "When the [RETURN] key is pressed or the" - .align 40 - dta "controller button is pressed briefly," - .align 40 - dta "the screen switches to the next player" - .align 40 - dta "until the difficulty levels for each" - .align 40 - dta "player are selected." - .align 40 - dta "The player's name can also be entered" - .align 40 - dta "with the controller. After pressing and" - .align 40 - dta "holding the button for more than 1s, you" - .align 40 - dta "can use up/down movements to change the" - .align 40 - dta "letter being entered, and left/right" - .align 40 - dta "movements to change its position in the" - .align 40 - dta "name. Releasing the button ends the name" - .align 40 - dta "entry and returns to the level" - .align 40 - dta "selection." - .align 40 - .align 40 - dta "If the name is not entered, it will be" - .align 40 - dta "supplemented with the default name." - .align 40 - .align 40 - dta " 3. Shopping screen (before each round)" - .align 40 - dta "----------------------------------------" - .align 40 - .align 40 - .align 40 - .align 40 - dta "On this screen, you can make purchases" - .align 40 - dta "of offensive and defensive weapons. Only" - .align 40 - dta "those weapons that the player can afford" - .align 40 - dta "are visible, along with information" - .align 40 - dta "about the price and the number of units" - .align 40 - dta "of a given weapon that will be obtained" - .align 40 - dta "for that price. The information on the" - .align 40 - dta "screen probably needs no more" - .align 40 - dta "description. You move through the lists" - .align 40 - dta "with the cursor keys (up and down) or" - .align 40 - dta "with the controller, the [TAB] key or" - .align 40 - dta "the left arrow, the left controller tilt" - .align 40 - dta "or second controller button change the" - .align 40 - dta "screen to defensive or offensive" - .align 40 - dta "weapons, the [SPACE] key or the right" - .align 40 - dta "arrow and also the controller to the" - .align 40 - dta "right does the purchase of the indicated" - .align 40 - dta "weapon." - .align 40 - .align 40 - dta "The [RETURN] key or the controller" - .align 40 - dta "button press switches to the defensive" - .align 40 - dta "weapon activation screen. Here you can" - .align 40 - dta "activate previously bought defensive (or" - .align 40 - dta "offensive after switching with [TAB]," - .align 40 - dta "etc) weapons." - .align 40 - .align 40 - .align 40 - .align 40 - dta "This makes it possible to activate" - .align 40 - dta "shields and others before the round" - .align 40 - dta "starts." - .align 40 - .align 40 - dta "Another [RETURN] key or controller" - .align 40 - dta "button press switches to the next" - .align 40 - dta "player's shopping screen." - .align 40 - dta "(For computer players this screen is not" - .align 40 - dta "shown.)" - .align 40 - .align 40 - dta " 4. The main screen of the game" - .align 40 - dta "--------------------------------" - .align 40 - .align 40 - .align 40 - dta "The status line shows which player is" - .align 40 - dta "currently allowed to take a shot and a" - .align 40 - dta "set of other information:" - .align 40 - dta $5a, d" player's tank name," - .align 40 - dta $5a, d" active controller number or difficulty" - .align 40 - dta "level of computer-controlled player" - dta d"(1-" - dta d"Moron"* - dta d" - 8-" - dta d"Unknown"* - dta d")," - dta d" " - .align 40 - .align 40 - dta $5a, d" currently selected offensive weapon" - .align 40 - dta "(symbol quantity and name)," - .align 40 - dta $5a, d" the player's remaining energy points" - .align 40 - dta "and if he has an active defensive weapon" - .align 40 - dta "that has its energy - in parentheses the" - .align 40 - dta "energy level," - .align 40 - dta $5a, d" the angle and the direction of the" - .align 40 - dta "barrel set by the player," - .align 40 - dta $5a, d" the shot strength set by the player" - .align 40 - dta "(the maximum shot strength is limited by" - .align 40 - dta "the player's energy - it can not exceed" - .align 40 - dta d"the energy ", $5a, d" 10 . This means that you" - .align 40 - dta "can fire weaker shots only when having a" - .align 40 - dta "small amount of energy," - .align 40 - dta $5a, d" the current round number," - .align 40 - dta $5a, d" wind speed and direction," - dta d"* ""computer"" symbol if " - dta d"Auto Defense"* - dta d" " - .align 40 - .align 40 - dta "is active," - .align 40 - dta $5a, d" in parentheses is the name of the" - .align 40 - dta "active defensive weapon - if there is" - .align 40 - dta "any activated by the player." - .align 40 - .align 40 - dta "The basic controls are simple enough -" - .align 40 - dta "cursor keys or controller: left/right -" - .align 40 - dta "change the angle of the barrel, up/down" - .align 40 - dta "- change the the force of the shot." - .align 40 - dta "Other functions:" - .align 40 - .align 40 - dta $5a, d" [SPACE] or controller button pressed" - .align 40 - dta "briefly - firing a shot." - .align 40 - dta $5a, d" [TAB] or [SELECT] or second controller" - .align 40 - dta "button - selection of offensive weapons" - .align 40 - dta "(this option is not available directly" - .align 40 - dta "with one button controller - you need to" - .align 40 - dta "select Inventory). |" - .align 40 - dta $5a, d" [I] or longer holding the controller" - .align 40 - dta "button - go to Inventory. It is a screen" - .align 40 - dta "(actually two) with the same layout as" - .align 40 - dta "the shopping menu, it also works" - .align 40 - dta "similarly except that here you don't buy" - .align 40 - dta "weapons, but choose one of the offensive" - .align 40 - dta "ones to shoot or activate a defensive" - .align 40 - dta "weapon. |" - .align 40 - dta $5a, d" [A] or [OPTION] - go directly to the" - .align 40 - dta "defensive weapons activation." - .align 40 - dta $5a, d" [M] - disable/enable background music." - .align 40 - dta "|" - .align 40 - dta $5a, d" [S] - disable/enable effect sounds. |" - .align 40 - dta $5a, d" [START] - speed up some game" - .align 40 - dta "animations. |" - .align 40 - dta $5a, d" [O] - end the current game and jump to" - .align 40 - dta "the Game Over screen with a summary. The" - .align 40 - dta "summary of the results does not take" - .align 40 - dta "into account the current round of the" - .align 40 - dta "game, but only the rounds completed" - .align 40 - dta "earlier. This corresponds to pressing" - .align 40 - dta "the [ESC] key with the difference that" - .align 40 - dta "the summary and credits are displayed. |" - .align 40 - dta $5a, d" [START] + [OPTION] - immediately force" - .align 40 - dta "the end of the game (Game Over), just" - .align 40 - dta "like [O] but without confirmation." - .align 40 - dta $5a, d" [G] - changes the mountain shading |" - .align 40 - dta $5a, d" [ESC] - during the entire game at any" - .align 40 - dta "time (unless the computer is playing," - .align 40 - dta "then sometimes you have to wait a while)" - .align 40 - dta "you can press the [ESC] key, which" - .align 40 - dta "allows you to abort the game and return" - .align 40 - dta "to the beginning (of course, there is" - .align 40 - dta "protection against accidental pressing)." - .align 40 - dta "|" - .align 40 - dta $5a, d" [Y] - when asked to abort or terminate" - .align 40 - dta "the game - confirmation |" - .align 40 - dta $5a, d" [CTRL] + [HELP] - Toggle ""visual" - .align 40 - dta "debug"" mode. It displays distances" - .align 40 - dta "measured, laser aiming, and aiming" - .align 40 - dta "technique. It leaves a mess on the" - .align 40 - dta "screen, but it does not impair the game," - .align 40 - dta "just makes it a bit harder. |" - .align 40 - .align 40 - dta " 5. Game mechanics - offensive weapons" - .align 40 - dta "---------------------------------------" - .align 40 - .align 40 - dta " Energy of tanks." - .align 40 - dta "------------------" - .align 40 - dta "At the beginning of each round, each" - .align 40 - dta "tank has 99 ash units of energy." - .align 40 - dta "Tanks' energy is depleted in 3 ways:" - .align 40 - dta $5a, d" one unit after each shot" - .align 40 - dta $5a, d" while falling (one pixel down -2" - .align 40 - dta "units)." - .align 40 - dta $5a, d" when a projectile hits the tank or" - .align 40 - dta "next to it - and here the amount of" - .align 40 - dta "energy subtracted depends on the" - .align 40 - dta "distance from the center of the" - .align 40 - dta "explosion and the type/power of the" - .align 40 - dta "projectile." - .align 40 - .align 40 - dta " How energy and money works:" - .align 40 - dta "-----------------------------" - .align 40 - dta "After each round the amount of money" - .align 40 - dta "gained/lost is calculated, this is done" - .align 40 - dta "on the basis of two variables" - .align 40 - dta "accumulated by each tank during the" - .align 40 - dta "round. These variables are:" - .align 40 - .align 40 - dta "gain - energy ""captured"" from tanks hit" - .align 40 - dta "(also if you hit yourself :) and here's" - .align 40 - dta "the catch, if you have very little" - .align 40 - dta "energy left it can be profitable to hit" - .align 40 - dta "yourself with a powerful weapon" - .align 40 - .align 40 - dta "lose - energy lost due to explosion/fall" - .align 40 - dta "(and here it is important - to count the" - .align 40 - dta "total loss of energy even if the tank" - .align 40 - dta "has less at the moment of hit)." - .align 40 - .align 40 - dta "In addition, the tank that won the round" - .align 40 - dta "has a parameter gain (captured from hit" - .align 40 - dta "tanks energy) increased by the remaining" - .align 40 - dta "energy at the end of the round (because" - .align 40 - dta "it did not die and should have it -" - .align 40 - dta "although it also happens otherwise :) )" - .align 40 - .align 40 - dta "Specifically:" - .align 40 - .align 40 - dta " After each round:" - .align 40 - dta "-------------------" - .align 40 - dta d"money = money + (20 ", $5a, d" (gain+energy))." - .align 40 - .align 40 - dta d"money = money - (10 ", $5a, d" lose)." - .align 40 - .align 40 - dta "if money <0 then money=0." - .align 40 - .align 40 - dta "(at the start of each round gain and" - .align 40 - dta "lose have a value of 0)." - .align 40 - .align 40 - dta "During a round, if another tank is hit" - .align 40 - dta "as a result of a shot fired by a tank," - .align 40 - dta "the tank firing the shot ""gets the" - .align 40 - dta "energy"" taken away from the hit tank." - .align 40 - dta " tank taking a shot:" - .align 40 - dta "---------------------" - .align 40 - dta "gain = gain + EnergyDecrease." - .align 40 - dta " tank hit:" - .align 40 - dta "-----------" - .align 40 - dta "lose = lose + EnergyDecrease." - .align 40 - .align 40 - dta "Where EnergyDecrease is the loss of" - .align 40 - dta "energy due to the hit." - .align 40 - .align 40 - dta "Of course, at the same time the hit tank" - .align 40 - dta "loses the amount of energy stored in" - .align 40 - dta "EnergyDecrease, except that here the" - .align 40 - dta "loss cannot exceed the energy you have." - .align 40 - .align 40 - dta " How a hit works." - .align 40 - dta "------------------" - .align 40 - dta "Each weapon that results in an explosion" - .align 40 - dta "has its own blast radius." - .align 40 - .align 40 - dta "After the explosion, every tank in its" - .align 40 - dta "range loses energy." - .align 40 - .align 40 - dta "It works in such a way that if the hit" - .align 40 - dta "is exactly on the center point of the" - .align 40 - dta "tank EnergyDecrease receives the maximum" - .align 40 - dta "value for the weapon, and for each pixel" - .align 40 - dta "of distance from the center of the tank" - .align 40 - dta "this value is reduced by 8." - .align 40 - .align 40 - dta "For example, if a hit with the Baby" - .align 40 - dta "Missile weapon hits the center of the" - .align 40 - dta "tank perfectly, it will lose exactly 88" - .align 40 - dta "units of energy (plus what it loses" - .align 40 - dta "falling after the explosion)." - .align 40 - dta "If you hit with the same weapon at a" - .align 40 - dta "distance of 10 pixels from the center of" - .align 40 - dta "the tank, the loss will be only 8 units." - .align 40 - .align 40 - dta "And here are the values of maximum" - .align 40 - dta "energy loss for individual weapons. If a" - .align 40 - dta "weapon explodes several times, each" - .align 40 - dta "explosion is calculated independently" - .align 40 - dta "(additional values in the table):" - .align 40 - .align 40 - dta "Offensive weapons and maximum energy" - .align 40 - dta "loss:" - .align 40 - dta $5a, d" Baby Missile: 88" - .align 40 - dta $5a, d" Missile: 136" - .align 40 - dta $5a, d" Baby Nuke: 200" - .align 40 - dta $5a, d" Nuke: 240" - .align 40 - dta $5a, d" LeapFrog: 136 112 112" - .align 40 - dta $5a, d" Funky Bomb: 168 88 (* 5)" - .align 40 - dta $5a, d" MIRV: 136 (* 5)" - .align 40 - dta $5a, d" Death's Head: 240 (* 5)" - .align 40 - dta $5a, d" Napalm: 40 (this weapon is different" - .align 40 - dta "and the distance from the center is not" - .align 40 - dta "determined, simply any tank in range of" - .align 40 - dta "the flames loses 40 units of energy)" - .align 40 - dta $5a, d" Hot Napalm: 80 (the rule is the same" - .align 40 - dta "as in Napalm)" - .align 40 - dta $5a, d" Baby Roller: 88" - .align 40 - dta $5a, d" Roller: 168" - .align 40 - dta $5a, d" Heavy Roller: 240" - .align 40 - dta $5a, d" Riot Charge: 0 (no energy is" - .align 40 - dta "subtracted, but a portion of the ground" - .align 40 - dta "upward from the hit point in a 31-pixel" - .align 40 - dta "radius is removed)" - .align 40 - dta $5a, d" Riot Blast: 0 (as in Riot Charge, but" - .align 40 - dta "in a radius of 61 pixels)" - .align 40 - dta $5a, d" Riot Bomb: 0 (no energy is subtracted," - .align 40 - dta "but the ground in a radius of 17 pixels" - .align 40 - dta "from the hit point is destroyed - as in" - .align 40 - dta "the case of Missile. The weapon is" - .align 40 - dta "useful for digging out after being" - .align 40 - dta "buried, or for undermining an opponent)" - .align 40 - dta $5a, d" Heavy Riot Bomb: 0 (as in Riot Bomb," - .align 40 - dta "but the explosion radius is 29 pixels" - .align 40 - dta "from the point of impact - as in the" - .align 40 - dta "case of Nuke)" - .align 40 - dta $5a, d" Baby Digger: 0 (no energy is" - .align 40 - dta "subtracted, but a portion of the ground" - .align 40 - dta "is undermined in a radius of 60 pixels" - .align 40 - dta "from the point of impact)" - .align 40 - dta $5a, d" Digger: 0 (as above - greater" - .align 40 - dta "undermining)" - .align 40 - dta $5a, d" Heavy Digger: 0 (as above - greatest" - .align 40 - dta "undermining)" - .align 40 - dta $5a, d" Sandhog: 0 (as above - another way of" - .align 40 - dta "undermining)" - .align 40 - dta $5a, d" Heavy Sandhog: 0 (as above - largest" - .align 40 - dta "dig)" - .align 40 - dta $5a, d" Dirt Clod: 0 (no energy is subtracted," - .align 40 - dta "but a ground ball with a radius of 12" - .align 40 - dta "pixels from the hit point is created." - .align 40 - dta "The weapon is useful for burying the" - .align 40 - dta "opponent)" - .align 40 - dta $5a, d" Dirt Ball: 0 (as above, but the radius" - .align 40 - dta "of the ball is 22 pixels)" - .align 40 - dta $5a, d" Ton of Dirt: 0 (as above, but the" - .align 40 - dta "radius of the ball is 31 pixels)" - .align 40 - dta $5a, d" Liquid Dirt: 0 (floods the ground at" - .align 40 - dta "the point of hit with liquid soil," - .align 40 - dta "filling in the depressions)" - .align 40 - dta $5a, d" Stomp: 0 (no energy is subtracted, but" - .align 40 - dta "all tanks within a radius depending on" - .align 40 - dta "the force of the shot are pushed back," - .align 40 - dta "and after being pushed back they may" - .align 40 - dta "fall or be buried. With a maximum force" - .align 40 - dta "of 990 units, the radius of action is" - .align 40 - dta "about 60 pixels)" - .align 40 - dta $5a, d" Laser: 100 (but here it is also" - .align 40 - dta "different - only in a case of a direct" - .align 40 - dta "hit simply subtract 100 units of energy" - .align 40 - dta "- that is, the tank always dies)" - .align 40 - .align 40 - dta "Large points received by the player is" - .align 40 - dta "the number of tanks that died earlier" - .align 40 - dta "than him. If any of the other tanks" - dta d"capitulated earlier (" - dta d"White Flag"* - dta d") is" - dta d" " - .align 40 - .align 40 - dta "not added to those that died and does" - .align 40 - dta "not give points." - .align 40 - dta "Only these points determine the order in" - .align 40 - dta "the summary." - .align 40 - .align 40 - dta " 6. And now for defensive weapons:" - .align 40 - dta "-----------------------------------" - dta d"* " - dta d"White Flag"* - dta d" - causes the surrender" - dta d" " - .align 40 - .align 40 - dta "of the player (can sometimes be useful" - .align 40 - dta "in a hopeless situation). The advantage" - .align 40 - dta "is that by surrendering you don't give a" - .align 40 - dta "big point to your opponents and don't" - .align 40 - dta "cause one of them to gain by killing us," - .align 40 - dta "you also limit the loss of your energy" - .align 40 - dta "and also cash. An important note - this" - .align 40 - dta "is the only defensive weapon that can be" - .align 40 - dta "deactivated. All you have to do is" - .align 40 - dta "re-enter inventory and once again select" - .align 40 - dta "its activation." - .align 40 - dta d"* " - dta d"Battery"* - dta d" - when activated, it" - dta d" " - .align 40 - .align 40 - dta "recharges the tank's energy to full (99" - .align 40 - dta "units). It is one of three defensive" - .align 40 - dta "weapons that does not deactivate other" - .align 40 - dta "defensive weapons when used." - .align 40 - dta d"* " - dta d"Hovercraft"* - dta d" - a weapon that allows" - dta d" " - .align 40 - .align 40 - dta "the tank to move. It has its own fuel" - .align 40 - dta "supply in form of electric eels and in" - .align 40 - dta "addition, it can be activated multiple" - .align 40 - dta "times during the same turn, and after" - .align 40 - dta "using it, you can activate another" - .align 40 - dta "defensive weapon and fire a shot in the" - .align 40 - dta "same turn. After using it, the tank" - .align 40 - dta "rises above the mountains and using the" - .align 40 - dta "cursor keys or a controller you can move" - .align 40 - dta "the tank to a new position. [SPACE] or" - .align 40 - dta "the controller button cause the tank to" - .align 40 - dta "land in a new place. You can fly until" - .align 40 - dta "the tank runs out of eels (presented on" - .align 40 - dta "the status bar like the energy of a" - .align 40 - dta "defensive weapon), if the eel fuel runs" - .align 40 - dta "out the tank will fall down on its own." - .align 40 - dta "It is not possible to land on other" - .align 40 - dta "tanks." - .align 40 - dta d"* " - dta d"Parachute"* - dta d" - does not protect" - dta d" " - .align 40 - .align 40 - dta "against loss of energy due to a" - .align 40 - dta "neighboring explosion, makes you not" - .align 40 - dta "lose energy during ONE fall. After such" - .align 40 - dta "a fall, it deactivates and a new" - .align 40 - dta "parachute must be activated." - .align 40 - dta d"* " - dta d"Shield"* - dta d" - the simplest shield works" - dta d" " - .align 40 - dta d"exactly the opposite of " - dta d"Parachute"* - dta d"," - dta d" " - .align 40 - .align 40 - dta "it does not protect against energy loss" - .align 40 - dta "while falling, instead it protects" - .align 40 - dta "against energy loss caused by ONE" - .align 40 - dta "adjacent explosion. It protects once, no" - .align 40 - dta "matter how strong the explosion is" - .align 40 - dta "(whether tis but a scratch or a direct" - .align 40 - dta "hit with a nuke), and deactivates" - .align 40 - dta "immediately afterward." - .align 40 - dta d"* " - dta d"Heavy Shield"* - dta d" - a shield with its" - dta d" " - .align 40 - .align 40 - dta "own energy (at the start of 99 units)," - dta d"it works the same as " - dta d"Shield"* - dta d" (does" - dta d" " - .align 40 - .align 40 - dta "not protect against falling) with the" - .align 40 - dta "exception that it has its own energy" - .align 40 - dta "resource. When exploding, the energy of" - .align 40 - dta "this shield is reduced first, and if it" - .align 40 - dta "reaches 0, the shield deactivates and" - .align 40 - dta "further reduces the tank's energy. Due" - .align 40 - dta "to this action, a tank with this type of" - .align 40 - dta "shield can be ""killed"" by undermining" - .align 40 - dta "it, because falling reduces the energy" - .align 40 - dta "of the tank and not the shield." - .align 40 - dta d"* " - dta d"Force Shield"* - dta d" - the strongest" - dta d" " - .align 40 - .align 40 - dta "shield - works just like Heavy Shield" - .align 40 - dta "only that it is combined with" - dta d"Parachute"* - dta d". What is important in this" - dta d" " - .align 40 - .align 40 - dta "case, falling does not take energy away" - .align 40 - dta "from the shield or the tank. It is only" - .align 40 - dta "taken away by hits." - .align 40 - dta d"* " - dta d"Bouncy Castle"* - dta d" - a" - dta d" " - .align 40 - .align 40 - dta "passive-aggressive weapon :). It works" - .align 40 - dta "as follows - in a case of a direct tank" - .align 40 - dta "hit (and shield), it causes the" - .align 40 - dta "projectile to ""bounce"" in the opposite" - .align 40 - dta "direction with the same force with which" - .align 40 - dta "it was fired. In the absence of wind and" - .align 40 - dta "a difference in level, the weapon then" - .align 40 - dta "hits the tank that fired it. After such" - .align 40 - dta "a bounce, it deactivates. As the weapon" - .align 40 - dta "reacts in this way only to precise hits," - dta d"it is also works like " - dta d"Heavy Shield"* - dta d" " - .align 40 - .align 40 - dta "and has 99 units at the start (we will" - .align 40 - dta "probably have to rethink this value and" - .align 40 - dta "give a smaller one here)." - .align 40 - dta d"* " - dta d"Mag Deflector"* - dta d" - the second" - dta d" " - .align 40 - .align 40 - dta "passive-aggressive weapon :) . In case" - .align 40 - dta "of a direct hit on a tank (and shield)," - .align 40 - dta "it causes the hit point to move randomly" - .align 40 - dta "to the left or right side of the" - .align 40 - dta "protected tank, but not very far, so you" - .align 40 - dta "can get ""shrapnel"" with stronger" - dta d"weapons. As in the case of " - dta d"Bouncy"* - dta d" " - .align 40 - dta d"Castle" - dta d", it is also a shield that"* - dta d" " - .align 40 - dta d"corresponds to the action of " - dta d"Heavy"* - dta d" " - .align 40 - dta d"Shield" - dta d" and has 99 units at the start"* - dta d" " - .align 40 - .align 40 - dta "(probably here we will have also to" - .align 40 - dta "rethink this value and give a smaller" - .align 40 - dta "one)." - .align 40 - dta d"* " - dta d"Nuclear Winter"* - dta d" - adds nothing," - dta d" " - .align 40 - .align 40 - dta "takes nothing away :) - in fact, it is" - .align 40 - dta "not so much a defensive weapon as a" - .align 40 - dta "double-edged one. It floods the area" - .align 40 - dta "with ""radioactive"" fallout, which is" - .align 40 - dta "ordinary soil. If you do not have at" - .align 40 - dta "hand any weapon that digs up the" - .align 40 - dta "terrain, and for that a shield" - .align 40 - dta "(preferably disposable), then after such" - .align 40 - dta """fallout"" you will have to shoot" - .align 40 - dta "yourself - because being underground is" - .align 40 - dta "otherwise impossible. Alternatively," - dta d"White Flag"* - dta d" always remains." - dta d" " - .align 40 - .align 40 - dta d"* " - dta d"Long Schlong"* - dta d" - a special weapon :)" - dta d" " - .align 40 - .align 40 - dta "- Costs a lot, doesn't really help with" - .align 40 - dta "anything (except possibly digging" - .align 40 - dta "yourself out but only when slightly" - .align 40 - dta "buried but it has a cool name and looks" - .align 40 - dta "cool :) - It can be activated" - .align 40 - dta "independently of other defensive weapons" - .align 40 - dta "and remains active until the end of the" - .align 40 - dta "round (it cannot be deactivated)." - .align 40 - dta d"* " - dta d"Lazy Boy"* - dta d" - it is not actually a" - dta d" " - .align 40 - .align 40 - dta "defensive weapon. It is an aiming aid." - .align 40 - dta "When it is activated, the tank tries to" - .align 40 - dta "aim at the nearest enemy and" - .align 40 - dta "automatically adjusts the power of the" - .align 40 - dta "shot and angle. If it has too little" - .align 40 - dta "energy, it can sometimes aim wrong (it" - dta d"uses a method like " - dta d"Cyborg"* - dta d" to aim)." - dta d" " - .align 40 - dta d"Like " - dta d"Battery"* - dta d", it does not deactivate" - dta d" " - .align 40 - .align 40 - dta "other defensive weapons when used. Note:" - .align 40 - dta "There is no point in activating this" - .align 40 - dta "weapon before the round, targeting will" - .align 40 - dta "not take place because there is nothing" - .align 40 - dta "to target yet." - .align 40 - dta d"* " - dta d"Lazy Darwin"* - dta d" - works just like" - dta d" " - .align 40 - dta d"Lazy Boy"* - dta d" but targets the weakest" - dta d" " - .align 40 - .align 40 - dta "opponent. In this weapon, after" - .align 40 - dta "automatic targeting, ""visual targeting""" - .align 40 - dta "remains active, so you can easily change" - .align 40 - dta "the target and independently select" - .align 40 - dta "another opponent by seeing if you hit" - .align 40 - dta "him." - .align 40 - dta d"* " - dta d"Auto Defense"* - dta d" - activates the mode" - dta d" " - .align 40 - .align 40 - dta "of automatic activation of defensive" - .align 40 - dta "weapons. After its activation, the tank" - .align 40 - dta "automatically activates the strongest" - .align 40 - dta "shield it has (consuming it, of course)" - .align 40 - dta "at any time when there is no shield" - .align 40 - dta "(also between shots of other players)." - .align 40 - dta "At the same time, if the tank's energy" - .align 40 - dta "level drops below 30 units, it" - dta d"automatically activates " - dta d"Battery"* - dta d" if" - dta d" " - .align 40 - .align 40 - dta "it has it. This weapon remains active" - .align 40 - dta "until the end of the round and is" - .align 40 - dta "indicated by the ""computer"" symbol" - .align 40 - dta "before the name of the active defensive" - .align 40 - dta "weapon in the status line. It is the" - .align 40 - dta "second defensive weapon that does not" - .align 40 - dta "deactivate other defensive weapons when" - .align 40 - dta "used." - .align 40 - dta d"* " - dta d"Spy Hard"* - dta d" - Help for the forgetful" - dta d" " - .align 40 - .align 40 - dta ":) . When activated, it shows a preview" - .align 40 - dta "of information about the next opponents" - .align 40 - dta "one by one. Left/Right - changes the" - .align 40 - dta """spied"" tank. Fire/Space/Return/Esc -" - .align 40 - dta "ends the ""spying"". This is the last" - .align 40 - dta "defensive weapon, which does not" - .align 40 - dta "deactivate other defensive weapons when" - .align 40 - dta "used." - .align 40 - .align 40 - dta "Due to the different warhead tracking" - dta d"system of " - dta d"MIRV"* - dta d" weapons, the " - dta d"Bouncy"* - dta d" " - .align 40 - dta d"Castle" - dta d" and "* - dta d"Mag Deflector" - dta d" defensive"* - dta d" " - .align 40 - .align 40 - dta "weapons only use the shielding function" - .align 40 - dta "when hit by these weapons. In addition," - dta d"MIRV"* - dta d" warheads do not bounce or fly" - dta d" " - .align 40 - .align 40 - dta "through sidewalls when falling" - .align 40 - .align 40 - dta "None of the shields protect against" - dta d"Napalm"* - dta d". " - dta d"Bouncy Castle"* - dta d" or " - dta d"Mag"* - dta d" " - .align 40 - dta d"Deflector" - dta d" on a direct hit will deflect"* - dta d" " - .align 40 - .align 40 - dta "it or carry it past, but just hit very" - .align 40 - dta "close to a tank and its shield will not" - .align 40 - dta "save it." - .align 40 - dta d"White Flag"* - dta d", " - dta d"Hovercraft"* - dta d" and" - dta d" " - .align 40 - dta d"Nuclear Winter"* - dta d" weapons, when" - dta d" " - .align 40 - .align 40 - dta "selected, require activation, this is" - .align 40 - dta "accomplished by ""firing a shot"" after" - .align 40 - dta "the selection of that weapon. Of course," - .align 40 - dta "the shot of the offensive weapon is then" - .align 40 - dta "not fired, but only the selected" - .align 40 - dta "defensive weapon is activated." - .align 40 - .align 40 - dta "You can only have one defensive weapon" - dta d"active at a time (except " - dta d"Long"* - dta d" " - .align 40 - dta d"Schlong" - dta d" of course :) ). You can always"* - dta d" " - .align 40 - .align 40 - dta "change the decision and activate another" - dta d"defensive weapon or deactivate " - dta d"White"* - dta d" " - .align 40 - dta d"Flag" - dta d" before firing."* - dta d" " - .align 40 - .align 40 - .align 40 - dta "And of course, activating a weapon when" - .align 40 - dta "you already have some other weapon" - .align 40 - dta "activated causes the loss of the" - .align 40 - dta "previous one (no returns :) )." - .align 40 - .align 40 - dta " 7. ""Other"" weapons:" - .align 40 - dta "---------------------" - .align 40 - dta d"* " - dta d"Best F...g Gifts"* - dta d" - this is a 'loot" - dta d" " - .align 40 - .align 40 - dta "box', not a weapon per se. Buying it" - .align 40 - dta "draws one of the offensive or (rarely)" - .align 40 - dta "defensive weapons and adds it to the" - .align 40 - dta "player's arsenal. It is a lottery in" - .align 40 - dta "which you can lose (if you draw a weapon" - dta d"cheaper than the " - dta d"Best F...g Gifts"* - dta d" " - .align 40 - .align 40 - dta "price) but also gain. You can get a" - .align 40 - dta "weapon otherwise not affordable at all" - .align 40 - .align 40 - dta " 8. AI opponents:" - .align 40 - dta "------------------" - .align 40 - .align 40 - dta "The game has 8 difficulty levels of" - .align 40 - dta "computer-controlled opponents. Or" - .align 40 - dta "actually 7 different ones and one" - .align 40 - dta """surprise"". Each has its own way of" - .align 40 - dta "buying defensive and offensive weapons" - .align 40 - dta "and a different method of target" - .align 40 - dta "selection and targeting itself, as well" - .align 40 - dta "as weapon selection. They are arranged" - .align 40 - dta "in the list according to increasing" - .align 40 - dta """skills"":" - .align 40 - dta d"* " - dta d"Moron"* - dta d" - the dumbest of opponents" - dta d" " - .align 40 - .align 40 - dta "(which does not mean the safest). Shoots" - .align 40 - dta "completely at random using only one" - dta d"weapon - " - dta d"Baby Missile"* - dta d". He doesn't" - dta d" " - .align 40 - .align 40 - dta "buy anything and doesn't know how to use" - .align 40 - dta "defensive weapons." - .align 40 - dta d"* " - dta d"Shooter"* - dta d" - This opponent does not" - dta d" " - .align 40 - .align 40 - dta "shoot blindly. He chooses one direction" - .align 40 - dta "for himself. Based on his own position -" - .align 40 - dta "he shoots in the direction from which" - .align 40 - dta "there is more space assuming that this" - .align 40 - dta "is where the other tanks are. He starts" - .align 40 - dta "firing from a high angle and shot after" - .align 40 - dta "shot changes this angle to a lower and" - .align 40 - dta "lower angle trying to fire the entire" - .align 40 - dta "area on the chosen side. He always fires" - .align 40 - dta "with the best weapon he has (the highest" - .align 40 - dta "on the list of weapons he has - that is," - .align 40 - dta "not necessarily the best). He does not" - .align 40 - dta "use defensive weapons even though he" - .align 40 - dta "buys them" - .align 40 - dta d"* " - dta d"Poolshark"* - dta d" - When attacking, he" - dta d" " - .align 40 - .align 40 - dta "sets the nearest tank as his target," - .align 40 - dta "then selects the angle of the shot, and" - .align 40 - dta "tries to select its strength by drawing" - .align 40 - dta "it from the selected range. He always" - .align 40 - dta "shoots with the best weapon he has. He" - .align 40 - dta "uses defensive weapons. With a" - .align 40 - dta "probability of 1:3, he activates the" - .align 40 - dta "best defensive weapon he owns (the" - .align 40 - dta "highest on the list of weapons he owns -" - .align 40 - dta "that is, not necessarily the best)" - .align 40 - dta "before firing. If his energy level drops" - dta d"below 30 units - he uses " - dta d"Battery"* - dta d" (of" - dta d" " - .align 40 - .align 40 - dta "course, if he bought it before), if the" - .align 40 - dta "energy drops below 5 and he has no" - dta d"Battery"* - dta d" he surrenders - " - dta d"White"* - dta d" " - .align 40 - dta d"Flag" - dta d". At the beginning of the round he"* - dta d" " - .align 40 - .align 40 - dta "makes 1 attemp to buy defensive weapons" - .align 40 - dta "and 6 offensive weapons." - .align 40 - dta d"* " - dta d"Tosser"* - dta d" - When attacking, he acts" - dta d" " - .align 40 - dta d"exactly like " - dta d"Poolshark"* - dta d" however, he" - dta d" " - .align 40 - .align 40 - dta "may have a ""better"" weapon inventory due" - .align 40 - dta "to a different purchase tactic. He" - .align 40 - dta "always activates the best defensive" - .align 40 - dta "weapon he has before shooting. And just" - dta d"like " - dta d"Poolshark"* - dta d" he uses " - dta d"Battery"* - dta d" " - .align 40 - dta d"and " - dta d"White Flag"* - dta d". At the beginning of" - dta d" " - .align 40 - .align 40 - dta "the round, he assesses how much money he" - .align 40 - dta "has and depending on that, he makes" - .align 40 - dta "(money/5100) attempts to buy defensive" - .align 40 - dta "weapons and then checks again how much" - .align 40 - dta "money he has left and makes (money/1250)" - .align 40 - dta "attempts to buy offensive weapons." - .align 40 - dta d"* " - dta d"Chooser"* - dta d" - Takes as a target the" - dta d" " - .align 40 - .align 40 - dta "weakest opponent (with the least amount" - .align 40 - dta "of energy) and aims very precisely, but" - .align 40 - dta "before the shot the energy of the shot" - .align 40 - dta "is modified by the parameter of luck :)" - .align 40 - dta ", that is, despite the precise aiming it" - .align 40 - dta "does not always hit. He shoots with the" - .align 40 - dta "best weapon he has unless the target is" - .align 40 - dta "close. Then he changes his weapon to" - dta d"Baby Missile"* - dta d" to avoid hitting" - dta d" " - .align 40 - .align 40 - dta "himself. He always activates the best" - .align 40 - dta "defensive weapon he has before shooting" - dta d"and, like " - dta d"Poolshark"* - dta d", uses" - dta d" " - .align 40 - dta d"Battery"* - dta d" and " - dta d"White Flag"* - dta d". He" - dta d" " - .align 40 - dta d"purchases just like " - dta d"Tosser"* - dta d"." - dta d" " - .align 40 - .align 40 - dta d"* " - dta d"Spoiler"* - dta d" - He shoots exactly like" - dta d" " - .align 40 - dta d"Chooser"* - dta d" except that he has more luck" - dta d" " - .align 40 - .align 40 - dta ":) , which means that even if he doesn't" - .align 40 - dta "hit the target of his choice, it can be" - dta d"a more precise shot than " - dta d"Chooser"* - dta d". If" - dta d" " - .align 40 - .align 40 - dta "he is unable to hit his chosen target," - .align 40 - dta "he tries to choose another target that" - .align 40 - dta "he can accurately hit. He uses defensive" - dta d"weapons exactly like " - dta d"Chooser"* - dta d". At the" - dta d" " - .align 40 - .align 40 - dta "beginning of the round, he assesses how" - .align 40 - dta "much money he has and depending on that," - .align 40 - dta "he makes (money/5100) attempts to buy" - .align 40 - dta "defensive weapons and then checks again" - .align 40 - dta "how much money he has left and makes" - .align 40 - dta "(money/320) attempts to buy offensive" - .align 40 - dta "weapons. When buying defensive weapons," - .align 40 - dta "he buys only strong and precise weapons" - .align 40 - dta "- that is, weapons that won't" - .align 40 - dta "accidentally hurt him." - .align 40 - dta d"* " - dta d"Cyborg"* - dta d" - Takes aim at the weakest" - dta d" " - .align 40 - .align 40 - dta "opponent (with the least amount of" - .align 40 - dta "energy) but prefers human-controlled" - .align 40 - dta "opponents. If he is unable to hit his" - .align 40 - dta "chosen target, he tries to choose" - .align 40 - dta "another target that he can accurately" - .align 40 - dta "hit. Aims very accurately and in the" - .align 40 - dta "vast majority of cases hits on the first" - .align 40 - dta "shot. He fires the shot with the best" - .align 40 - dta "weapon he has unless the target is" - .align 40 - dta "close. Then he changes his weapon to" - dta d"Baby Missile"* - dta d" to avoid hitting" - dta d" " - .align 40 - .align 40 - dta "himself. He uses defensive weapons" - dta d"exactly like " - dta d"Chooser"* - dta d" but if he has" - dta d" " - .align 40 - dta d"more than 2 pieces of " - dta d"Battery"* - dta d" he" - dta d" " - .align 40 - .align 40 - dta "uses them if the energy decreases below" - .align 40 - dta "60 units.. He shops exactly like" - dta d"Spoiler"* - dta d"." - dta d" " - .align 40 - .align 40 - dta d"* " - dta d"Unknown"* - dta d" - Before firing each shot," - dta d" " - .align 40 - .align 40 - dta "he randomly chooses a course of action" - dta d"from " - dta d"Poolshark"* - dta d" to " - dta d"Cyborg"* - dta d" and" - dta d" " - .align 40 - .align 40 - dta "applies his tactics. However, the" - .align 40 - dta "tactics of weapon purchases are always" - dta d"identical to " - dta d"Tosser"* - dta d"." - dta d" " - .align 40 - .align 40 - .align 40 - dta "Trying to buy a weapon (offensive or" - .align 40 - dta "defensive) is as follows:" - .align 40 - dta "First, one of the weapons is drawn" - .align 40 - dta "(among all possible offensive or" - .align 40 - dta "defensive weapons). Then a check is" - .align 40 - dta "performed to see if the drawn weapon is" - .align 40 - dta "in the list of weapons possible for" - .align 40 - dta "purchase by the tank. If not, no weapon" - .align 40 - dta "is bought in this trial, and if so, its" - .align 40 - dta "price is checked. If the tank has that" - .align 40 - dta "much money, the weapon is bought," - .align 40 - dta "otherwise the trial ends without making" - .align 40 - dta "a purchase." - .align 40 - dta d"Weapons purchased by: " - dta d"Shooter"* - dta d"," - dta d" " - .align 40 - dta d"Poolshark"* - dta d", " - dta d"Tosser"* - dta d" and" - dta d" " - .align 40 - dta d"Chooser"* - dta d":" - dta d" " - .align 40 - .align 40 - dta "Offensive weapons:" - .align 40 - dta $5a, d" Missile" - .align 40 - dta $5a, d" Baby Nuke" - .align 40 - dta $5a, d" Nuke" - .align 40 - dta $5a, d" LeapFrog" - .align 40 - dta $5a, d" Funky Bomb" - .align 40 - dta $5a, d" MIRV" - .align 40 - dta $5a, d" Death's Head" - .align 40 - dta $5a, d" Napalm" - .align 40 - dta $5a, d" Hot Napalm" - .align 40 - dta $5a, d" Baby Roller" - .align 40 - dta $5a, d" Roller" - .align 40 - dta $5a, d" Heavy Roller" - .align 40 - .align 40 - dta "Defensive weapons:" - .align 40 - dta $5a, d" Battery" - .align 40 - dta $5a, d" Parachute" - .align 40 - dta $5a, d" Strong Parachute" - .align 40 - dta $5a, d" Mag Deflector" - .align 40 - dta $5a, d" Shield" - .align 40 - dta $5a, d" Heavy Shield" - .align 40 - dta $5a, d" Force Shield" - .align 40 - dta $5a, d" Bouncy Castle" - .align 40 - dta " " - dta d"Weapons purchased by: " - dta d"Spoiler"* - dta d" and" - dta d" " - .align 40 - dta d"Cyborg"* - dta d":" - dta d" " - .align 40 - .align 40 - dta "Offensive weapons:" - .align 40 - dta $5a, d" Missile" - .align 40 - dta $5a, d" Baby Nuke" - .align 40 - dta $5a, d" Nuke" - .align 40 - dta $5a, d" Hot Napalm" - .align 40 - .align 40 - dta "Defensive weapons:" - .align 40 - dta $5a, d" Battery" - .align 40 - dta $5a, d" Strong Parachute" - .align 40 - dta $5a, d" Mag Deflector" - .align 40 - dta $5a, d" Heavy Shield" - .align 40 - dta $5a, d" Force Shield" - .align 40 - dta $5a, d" Bouncy Castle" - .align 40 - .align 40 diff --git a/Manuals/manual.asm b/Manuals/manual.asm index ffcd500..456e85a 100644 --- a/Manuals/manual.asm +++ b/Manuals/manual.asm @@ -8,7 +8,7 @@ screen_height = 26 screen_width = 40 -screen = $1000 ; start - 40*screen_height +screen = $0900 ; start - 40*screen_height KeyRepeatSpeed = 15 ; (max 127 !!!) @@ -414,9 +414,6 @@ NTSC rts .endp - icl "music/rmtplayr.a65" - - dl :2 .byte SKIP8 .byte LMS+MODE2 @@ -451,6 +448,8 @@ ticksPerSecond .byte 0 fake_pokey :9 .byte 0 pressTimer .byte 0 + icl "music/rmtplayr.a65" + man_text .if LANG = "PL" @@ -460,6 +459,7 @@ man_text .endif man_text_end .by $ff, $ff + .ECHO * opt h- ;RMT module is standard Atari binary file already ins "music/czytaczu1_stripped.rmt" ;include music RMT module diff --git a/Manuals/manual_en.xex b/Manuals/manual_en.xex index fc9cac6..29d7210 100644 Binary files a/Manuals/manual_en.xex and b/Manuals/manual_en.xex differ diff --git a/Manuals/manual_pl.xex b/Manuals/manual_pl.xex index a52a06d..6428ffa 100644 Binary files a/Manuals/manual_pl.xex and b/Manuals/manual_pl.xex differ diff --git a/Manuals/music/rmtplayr.a65 b/Manuals/music/rmtplayr.a65 index 7c2e1d2..aaa11cd 100755 --- a/Manuals/music/rmtplayr.a65 +++ b/Manuals/music/rmtplayr.a65 @@ -27,7 +27,7 @@ TRACKS equ 8 TRACKS equ 4 EIF ;* -PLAYER equ $3400 +PLAYER equ $2400 ;* ;* RMT FEATures definitions file ;* For optimizations of RMT player routine to concrete RMT modul only! diff --git a/README.md b/README.md index b67631c..16dc296 100644 --- a/README.md +++ b/README.md @@ -38,16 +38,24 @@ Compilation: (requires mads newer than 2023-09-13) Game source code is split into several parts: - `scorch.asm` is the main game startup code +- `scorchC64.asm` is the main game startup code for Commodore 64 - `game.asm` - it all happens here - `grafproc.asm` - graphics routines like line or circle - `textproc.asm` - text routines like list of weapons and shop - `variables.asm` - all non-zero page variables -- `constants.asm` - various tables of constants -- `display_*.asm` - display lists and text screen definitions +- `constants.asm` and `constants_top.asm` - various tables of constants - `ai.asm` - artificial stupidity of computer opponents - `weapons.asm` - general arsenal of tankies - `definitions.asm` - label definitions, moved to make it work better with Altirra debug (it doesn't). +Hardware dependent code (In the corresponding folders - 'Atari', 'C64', ...): +- `display_*.asm` - display lists and text screen definitions +- `gr_basic.asm` - graphics primitives (plot, point, soildown, drawmountains, etc.) for faster drawing +- `inputs.asm` - keyboard and joystick routines +- `interrupts.asm` - interrupts routines (DLI on Atari, music and SFX, timers) +- `textproc.asm` - text routines for menus and shop + + We were trying to use macros, pseudo-ops, and simple graphics primitives as much as possible. This way, it should be relatively easy to port this code to, for example, the C64. After working on this piece of code for N years, we are sure it would be much wiser to write it in C, Action!, or MadPascal. On the other hand, it is so much fun to type 150 characters when all you want to have is y = a * x + b. :) @@ -62,7 +70,7 @@ With the advent of [fujinet](https://fujinet.online/) we are thinking about maki 2023-12-07 Physical release version. -We are extremely pleased to inform you that our humble game was released on a physical media by [Mq](mailto:mq666xx@gmail.com) (Atari 8-bit version) and 5200 [atariage.com](https://atariage.com). +We are extremely pleased to inform you that our humble game was released on a physical media by [Mq](mailto:mq666xx@gmail.com) (Atari 8-bit version) and 5200 [atariage.com](https://atariage.com/store/index.php?l=product_detail&p=1305). ![Scorch physical release](Manuals/images/scorch_physical.jpg) diff --git a/ai.asm b/ai.asm index 5a281e8..9da48d8 100644 --- a/ai.asm +++ b/ai.asm @@ -246,6 +246,7 @@ LowBatteries jsr ClearTankNr ; we must hide tank to erase shields (issue #138) lda #ind_White_Flag sta ActiveDefenceWeapon,x + mva #sfx_white_flag sfx_effect jsr PutTankNr ; and draw tank witch Flag EnoughEnergy ; jsr DisplayStatus.DisplayEnergy ; not necessary - status update after othher defensives @@ -449,6 +450,7 @@ ItIsHuman beq lowestIsEqual bcc lowestIsHigher ; if lower + bcs lowestIsLower lowestIsEqual ; if equal then select random (of two tanks) bit RANDOM @@ -787,8 +789,7 @@ SetStartAndFlight ; set start point (virtual barrel end :) ) and make test fl sta ytraj+1 mva #0 ytraj+2 mva NewAngle Angle - lda CONSOL - and #%00000001 ; START KEY + jsr CheckStartKey ; START KEY beq @speedup jsr MoveBarrelToNewPosition bit escFlag diff --git a/artwork/talk.asm b/artwork/talk.asm index 7b0e4a0..e620fb6 100644 --- a/artwork/talk.asm +++ b/artwork/talk.asm @@ -1,34 +1,40 @@ .proc talk ; Maximum text length is 63 characters!!! - dta d"CYKA BLAT"^ dta d"DIE!"^ + dta d"FUR DEUTSCHLAND!"^ + dta d"YOU'RE DEAD MEAT."^ + dta d"DIE COMMIE PIG!"^ + dta d"VICTORY!"^ + dta d"DIE, ALIEN SWINE!"^ + dta d"AWRUK!!!"^ + dta d"CYKA BLAT"^ + dta d"TAKE THIS!"^ dta d"EAT MY SHORTS!"^ dta d"YOU'RE TOAST!"^ dta d"BANZAI!"^ - dta d"FROM HELL'S HEART I STAB AT THEE..."^ - dta d"DO YOU FEEL LUCKY, TANK?"^ - dta d"TAKE A HIKE!"^ - dta d"YOU'RE DEAD MEAT."^ - dta d"MAKE MY DAY."^ + dta d"OPEN WIDE!"^ + dta d"HA HA HA."^ dta d"CHARGE!"^ dta d"ATTACK!"^ + dta d"DIE, TANK-SCUM!"^ + dta d"IN YOUR FACE!"^ + dta d"TAKE A HIKE!"^ + dta d"MAKE MY DAY."^ + dta d"KNOCK, KNOCK."^ +; end of Propaganda :) + dta d"FROM HELL'S HEART I STAB AT THEE..."^ + dta d"DO YOU FEEL LUCKY, TANK?"^ dta d"YOU'RE OUTTA HERE."^ dta d"WATTSA MATTA YOU?"^ dta d"FREEZE, OR I'LL SHOOT!"^ - dta d"HA HA HA."^ dta d"WE COME IN PEACE - SHOOT TO KILL!"^ - dta d"IN YOUR FACE!"^ - dta d"DIE COMMIE PIG!"^ dta d"I LOVE THE SMELL OF NAPALM IN THE MORNING."^ - dta d"VICTORY!"^ dta d"SHOW SOME RESPECT."^ dta d"JUST WHO DO YOU THINK YOU ARE?"^ dta d"LOOK OUT BELOW!"^ - dta d"KNOCK, KNOCK."^ dta d"LOOK OVER THERE."^ dta d"GUESS WHAT'S COMING FOR DINNER?"^ dta d"MERRY CHRISTMAS."^ - dta d"OPEN WIDE!"^ dta d"HERE GOES NOTHING..."^ dta d"DON'T WORRY, IT ISN'T A LIVE ROUND."^ dta d"BLOOD, PAIN, VIOLENCE!"^ @@ -44,12 +50,8 @@ dta d"DON'T FORGET ABOUT ME!"^ dta d"HASTA LA VISTA, BABY!"^ dta d"THIS IS YOUR BRAIN ON SCORCH."^ - dta d"TAKE THIS!"^ dta d"THIS SCREEN AIN'T BIG ENOUGH FOR US."^ - dta d"DIE, ALIEN SWINE!"^ - dta d"AWRUK!!!"^ dta d"I SHALL OIL MY TURRET WITH YOUR BLOOD."^ - dta d"DIE, TANK-SCUM!"^ dta d"I'M GONNA BREAK YOUR FACE!"^ dta d"MAMA SAID KNOCK YOU OUT!"^ dta d"I HOPE YOU ENJOY PAIN!"^ @@ -118,8 +120,10 @@ dta d"CALL 1-900-SUE-TANK."^ dta d"YOU BIG DUMMY!"^ ;(sanford and son) LEND -NumberOfOffensiveTexts=54 +NumberOfOffensiveTexts=55 NumberOfDeffensiveTexts=62 +NumberOfPropagandaTexts=21 +VeryFunnyText=79 .endp hoverFull dta d"MY HOVERCRAFT IS FULL OF EELS!"^ hoverFullEnd diff --git a/artwork/weapons_AW6_mod.fnt b/artwork/weapons_AW6_mod.fnt index ef44e8c..9b59364 100644 Binary files a/artwork/weapons_AW6_mod.fnt and b/artwork/weapons_AW6_mod.fnt differ diff --git a/constants.asm b/constants.asm index 4be4296..b39a05f 100644 --- a/constants.asm +++ b/constants.asm @@ -250,7 +250,6 @@ WeaponPriceH ; weapons prices (tables with prices of weapons) .by >price_Riot_Blast .by >price_Riot_Bomb .by >price_Heavy_Riot_Bomb - .by >price_Baby_Digger .by >price_Digger .by >price_Heavy_Digger .by >price_Sandhog @@ -260,6 +259,7 @@ WeaponPriceH ; weapons prices (tables with prices of weapons) .by >price_Ton_of_Dirt .by >price_Liquid_Dirt .by >price_Dirt_Charge + .by >price_Propaganda .by >price_Punch .by >price_Buy_me .by >price_Laser @@ -299,7 +299,6 @@ WeaponPriceL .by 0 diff --git a/definitions.asm b/definitions.asm index 6131896..89f26d9 100644 --- a/definitions.asm +++ b/definitions.asm @@ -27,6 +27,8 @@ space = 0 ; space in screencodes KeyRepeatSpeed = 8 ; (max 127 !!!) FirstKeySpeed = 8 ; additional delay for first keypress +VuMeterTime = 12 ; Time of inactivity for VU Meter (1=5sec) + ;character codes for symbols (tank, parachute, etc. ) ; characters from tanks.fnt (graphics screen) char_parachute = $02 @@ -69,16 +71,16 @@ price_Riot_Charge = 230 ;_15 price_Riot_Blast = 241 ;_16 price_Riot_Bomb = 259 ;_17 price_Heavy_Riot_Bomb = 272 ;_18 -price_Baby_Digger = 136 ;_19 -price_Digger = 176 ;_20 -price_Heavy_Digger = 207 ;_21 -price_Sandhog = 191 ;_22 -price_Heavy_Sandhog = 223 ;_23 -price_Dirt_Clod = 104 ;_24 -price_Dirt_Ball = 130 ;_25 -price_Ton_of_Dirt = 171 ;_26 -price_Liquid_Dirt = 330 ;_27 -price_Dirt_Charge = 343 ;_28 +price_Digger = 176 ;_19 +price_Heavy_Digger = 207 ;_20 +price_Sandhog = 191 ;_21 +price_Heavy_Sandhog = 223 ;_22 +price_Dirt_Clod = 104 ;_23 +price_Dirt_Ball = 130 ;_24 +price_Ton_of_Dirt = 171 ;_25 +price_Liquid_Dirt = 330 ;_26 +price_Dirt_Charge = 343 ;_27 +price_Propaganda = 234 ;_28 price_Punch = 208 ;_29 price_Buy_me = 170 ;_30 price_Laser = 277 ;_31 @@ -119,16 +121,16 @@ ind_Riot_Charge = 15 ind_Riot_Blast = 16 ind_Riot_Bomb = 17 ind_Heavy_Riot_Bomb = 18 -ind_Baby_Digger = 19 -ind_Digger = 20 -ind_Heavy_Digger = 21 -ind_Sandhog = 22 -ind_Heavy_Sandhog = 23 -ind_Dirt_Clod = 24 -ind_Dirt_Ball = 25 -ind_Ton_of_Dirt = 26 -ind_Liquid_Dirt = 27 -ind_Dirt_Charge = 28 +ind_Digger = 19 +ind_Heavy_Digger = 20 +ind_Sandhog = 21 +ind_Heavy_Sandhog = 22 +ind_Dirt_Clod = 23 +ind_Dirt_Ball = 24 +ind_Ton_of_Dirt = 25 +ind_Liquid_Dirt = 26 +ind_Dirt_Charge = 27 +ind_Propaganda = 28 ind_Punch = 29 ind_Buy_me = 30 ind_Laser = 31 diff --git a/game.asm b/game.asm index 44e7153..23142c6 100644 --- a/game.asm +++ b/game.asm @@ -16,8 +16,7 @@ START jsr MakeDarkScreen bit escFlag bpl @+ - lda CONSOL - and #%00000001 ; START KEY + jsr CheckStartKey ; START KEY bne START jmp StartAfterSplash ; reset all game option if Start key pressed (and Esc) @ @@ -124,24 +123,23 @@ CalculateGainsLoop ; if lose is greater than money then zero money lda moneyH,x cmp loseH,x - bcc zeromoney - bne substractlose + bne @+ lda moneyL,x cmp loseL,x - bcc zeromoney +@ bcs substractlose +zeromoney + lda #0 + sta moneyL,x + sta moneyH,x + beq skipzeroing substractlose - sec +; sec ; C is allways set at this point lda moneyL,x sbc loseL,x sta moneyL,x lda moneyH,x sbc loseH,x sta moneyH,x - jmp skipzeroing -zeromoney - lda #0 - sta moneyL,x - sta moneyH,x skipzeroing ; and earned money for summary clc @@ -155,24 +153,23 @@ skipzeroing ; if lose is greater than money then zero money lda EarnedMoneyH,x cmp loseH,x - bcc ezeromoney - bne esubstractlose + bne @+ lda EarnedMoneyL,x cmp loseL,x - bcc ezeromoney +@ bcs esubstractlose +ezeromoney + lda #0 + sta EarnedMoneyL,x + sta EarnedMoneyH,x + beq eskipzeroing esubstractlose - sec +; sec ; C is allways set at this point lda EarnedMoneyL,x sbc loseL,x sta EarnedMoneyL,x lda EarnedMoneyH,x sbc loseH,x sta EarnedMoneyH,x - jmp eskipzeroing -ezeromoney - lda #0 - sta EarnedMoneyL,x - sta EarnedMoneyH,x eskipzeroing dex @@ -385,11 +382,7 @@ RoboTanks ;ldx TankNr jsr DisplayStatus ; to make visible AI selected defensive (and offensive :) ) jsr MoveBarrelToNewPosition - lda kbcode - cmp #@kbcode._esc ; 28 ; ESC - bne @+ - jsr AreYouSure -@ bit escFlag + jsr CheckExitKeys spl:rts ; keys Esc or O @@ -585,7 +578,7 @@ NotLastPlayerInRound ; in X there is a number of tank that died - lda #78 ; mumber of defensive text after BFG! ("VERY FUNNY.") + lda #talk.VeryFunnyText ; mumber of defensive text after BFG! ("VERY FUNNY.") bit AfterBFGflag ; check BFG flag bmi TextAfterBFG ; if BFG then no points for dead tanks ... @@ -732,14 +725,13 @@ NotNegativeShieldEnergy .proc Seppuku ;--------------------------------- lda #0 - sta ydraw+1 ; get position of the tank ldx TankNr ; lda #0 ; turn off defense weapons when hara-kiring sta ActiveDefenceWeapon,x sta ShieldEnergy,x jsr SetupXYdraw - lda #1 ; Missile + lda #ind_Missile ; Missile jsr ExplosionDirect jmp MainRoundLoop.continueMainRoundLoopAfterSeppuku .endp @@ -764,11 +756,14 @@ NotNegativeShieldEnergy lda random bmi @+ sec ; Wind = -Wind - .rept 4 + .rept 2 lda #$00 sbc Wind+# sta Wind+# .endr + lda #$ff + sta Wind+2 + sta Wind+3 @ rts .endp ;-------------------------------------------------- @@ -777,25 +772,16 @@ NotNegativeShieldEnergy ; Energy of tank X in A ;-------------------------------------------------- sta L1 - - ;DATA L1,L2 - ;Multiplication 8bit*8bit, - ;result 16bit - ;this algiorithm is a little longer than one in Ruszczyc 6502 book - ;but it is faster - - ldy #8 lda #0 + ldy #9 clc -LP0 ror +CYK ror ror L1 - bcc B0 + bcc NIE clc - adc #10 ; (L2) multiplication by 10 -B0 dey - bne LP0 - ror - ror L1 + adc #10 ; multiplication by 10 +NIE dey + bne CYK sta MaxForceTableH,x lda L1 sta MaxForceTableL,x @@ -934,26 +920,21 @@ MakeTanksVisible ; repeat untill NumberOfPlayers ldx #0 -GetRandomAgain0 - lda RANDOM - and #$07 ;NumberOfPlayers < 7 - cmp NumberOfPlayers - bcs GetRandomAgain0 - sta TankSequence,x - ;now first slot is ready, nexts slots are handled - ;in a more complicated way GetRandomAgainX + txy ; destroy A! + dey lda RANDOM - and #$07 ;NumberOfPlayers < 7 cmp NumberOfPlayers bcs GetRandomAgainX - + cpx #0 + bne NotFirstSlot + sta TankSequence,x ;now first slot is ready + inx + bne GetRandomAgainX +NotFirstSlot ;now we have to check if the value was not used ;in previous slots - - stx temp - ldy temp UsageLoop cmp TankSequence,y beq GetRandomAgainX ;apparently we have already used this value @@ -961,14 +942,11 @@ UsageLoop bpl UsageLoop ;well, looks like this value is new! - inx sta TankSequence,x + inx - stx temp - inc:lda temp ;x+1 - - cmp NumberOfPlayers - bne GetRandomAgainX + cpx NumberOfPlayers + bcc GetRandomAgainX rts .endp ;---------------------------------------------- @@ -979,9 +957,7 @@ UsageLoop ;---------------------------------------------- ; lets randomize someting between 0 and 180 - lda RANDOM - cmp #180 - bcs RandomizeAngle + randomize 0 180 rts .endp ;---------------------------------------------- @@ -1044,10 +1020,9 @@ LimitForce ;---------------------------------------------- mva #1 Erase jsr DrawTankNr.BarrelChange - mva #0 Erase MoveBarrel mva #sfx_set_power_2 sfx_effect - jsr DrawTankNr + jsr PutTankNr ; and Erase = 0 jsr DisplayStatus.displayAngle ; jsr CheckExitKeys @@ -1060,7 +1035,6 @@ MoveBarrel jsr WaitOneFrame AIaim jsr DrawTankNr.BarrelChange - mva #0 Erase lda NewAngle cmp AngleTable,x beq BarrelPositionIsFine @@ -1072,11 +1046,32 @@ rotateLeft ; older is bigger dec angleTable,x jmp MoveBarrel BarrelPositionIsFine - jmp DrawTankNr + jmp PutTankNr ; and Erase = 0 ; rts .endp +;-------------------------------------------------- +.proc DemoModeOrKey +; Waits for the key pressed if at least one human is playing. +; Otherwise, waits 3 seconds (demo mode). +;-------------------------------------------------- + ;check demo mode + ldx numberOfPlayers + dex +checkForHuman ; if all in skillTable other than 0 then switch to DEMO MODE + lda skillTable,x + beq peopleAreHere + dex + bpl checkForHuman + ; no people, just wait a bit + ldy #75 + jmp PauseYFrames + ; rts +peopleAreHere + jmp getkey ; jsr:rts +.endp + ;---------------------------------------------- .proc SortSequence ; ;---------------------------------------------- @@ -1429,4 +1424,65 @@ FinishResultDisplay jmp TypeLine4x4 ; jsr:rts .endp +.IF VU_METER = 1 +.proc VUMeter + ; No VUMeter if key pressed + jsr GetKeyFast + cmp #@kbcode._none + bne EndMeter + ; check timer + ; Atari 800 has 3 bytes clock, but 5200 only 2 bytes + .IF TARGET = 800 + LDA RTCLOK+1 + .ELIF TARGET = 5200 + lda RTCLOK + .ENDIF + cmp #VuMeterTime + bcc EndMeter + ; store all angles + ldx NumberOfPlayers +@ lda AngleTable,x + sta previousAngle,x + dex + bpl @- + ; let's go! +Meter + jsr ClearTanks + ldx NumberOfPlayers +@ txa + and #%00000001 + tay + lda trackn_audc+2,y + :4 asl + sta AngleTable,x + dex + bpl @- + jsr drawtanks + jsr WaitOneFrame + jsr GetKeyFast + cmp #@kbcode._none + beq Meter + ; restore all angles + jsr ClearTanks + ldx NumberOfPlayers +@ lda previousAngle,x + sta AngleTable,x + dex + bpl @- + jsr drawtanks + jsr drawtanknr +EndMeterAndReset + lda #0 + ; only older byte + .IF TARGET = 800 + sta RTCLOK+1 + .ELIF TARGET = 5200 + sta RTCLOK + .ENDIF +EndMeter + rts +.endp +.ENDIF + + .ENDIF \ No newline at end of file diff --git a/grafproc.asm b/grafproc.asm index 4d13726..4e327c8 100644 --- a/grafproc.asm +++ b/grafproc.asm @@ -362,11 +362,12 @@ not_endcircleloop lda ycircle adc YC sta ydraw - sta tempcir + sta ytempDRAW lda ycircle+1 adc #$00 sta ydraw+1 - sta tempcir+1 + sta ytempDRAW+1 + ; plot xcircle+XC,ycircle+YC jsr plot sec @@ -376,6 +377,7 @@ not_endcircleloop lda ycircle+1 sbc #$00 sta ydraw+1 + ; plot xcircle+XC,ycircle-YC jsr plot sec @@ -385,54 +387,60 @@ not_endcircleloop lda xcircle+1 sbc #0 sta xdraw+1 + ; plot xcircle-XC,ycircle-YC jsr plot - lda tempcir + lda ytempDRAW sta ydraw - lda tempcir+1 + lda ytempDRAW+1 sta ydraw+1 + ; plot xcircle-XC,ycircle+YC jsr plot ;--- clc lda xcircle - adc yC + adc YC sta xdraw lda xcircle+1 adc #0 sta xdraw+1 ;clc lda ycircle - adc xC + adc XC sta ydraw - sta tempcir + sta ytempDRAW lda ycircle+1 adc #$00 sta ydraw+1 - sta tempcir+1 + sta ytempDRAW+1 + ; plot xcircle+YC,ycircle+XC jsr plot sec lda ycircle - sbc xC + sbc XC sta ydraw lda ycircle+1 sbc #$00 sta ydraw+1 + ; plot xcircle+YC,ycircle-XC jsr plot sec lda xcircle - sbc yC + sbc YC sta xdraw lda xcircle+1 sbc #0 sta xdraw+1 + ; plot xcircle-YC,ycircle-XC jsr plot - lda tempcir + lda ytempDRAW sta ydraw - lda tempcir+1 + lda ytempDRAW+1 sta ydraw+1 + ; plot xcircle-YC,ycircle+XC jsr plot ;----- @@ -450,7 +458,7 @@ not_endcircleloop sbc FX sbc #4 sta FS - jmp endif01 + jmp circleloop ; endif01 else01 dec YC sec @@ -468,7 +476,7 @@ else01 endif01 jmp circleloop .endp -;-------------------------------*------------------ +;-------------------------------------------------- .proc placetanks ;-------------------------------------------------- ldx #(MaxPlayers-1) ;maxNumberOfPlayers-1 @@ -584,35 +592,38 @@ UnequalTanks ;------------------------------------------------- .proc ClearTanks jsr PMoutofScreen - mva #1 Erase ; erase tanks flag + lda #1 ; erase tanks flag + bne drawtanks.era .endp ;------------------------------------------------- .proc drawtanks ;------------------------------------------------- + lda #0 ; no erase tanks flag +era sta Erase lda TankNr pha - ldx #$00 + ldx NumberOfPlayers + dex stx TankNr DrawNextTank jsr drawtanknr - inc TankNr + dec TankNr ldx TankNr - Cpx NumberOfPlayers - bne DrawNextTank + bpl DrawNextTank pla sta TankNr - mva #0 Erase ; no erase tanks flag rts .endp ;--------- ClearTankNr - mva #1 Erase - bne DrawTankNr + lda #1 ; erase tank flag + bne @er PutTankNr - mva #0 Erase + lda #0 ; no erase tank flag +@er sta Erase .proc DrawTankNr ldx tankNr ; let's check the energy @@ -797,8 +808,7 @@ DoNotDrawTankNr ; number of blinking tank in TankNr mva #18 fs ; temp, how many times flash the tank tankflash_loop - lda CONSOL ; turbo mode - and #%00000001 ; START KEY + jsr CheckStartKey ; START KEY sne:mva #1 fs ; finish it mva #1 Erase ldx TankNr @@ -975,27 +985,25 @@ ToHighToParachute ; ; this proc change xdraw, ydraw and temp! ;-------------------------------------------------- + lda XtankstableL,x + sta xdraw + lda XtankstableH,x + sta xdraw+1 ; one pixel under tank clc lda Ytankstable,x adc #1 sta ydraw mva #0 ydraw+1 - lda XtankstableL,x - sta xdraw - lda XtankstableH,x - sta xdraw+1 + ; plot one (first - clear) and 6 random color pixels + mvy #7 temp ; clear first pixel under tank - mva #0 color - jsr plot - inw xdraw - ; plot 6 random color pixels - mva #6 temp + bne @pl ; A=0 @ lda Erase eor #%00000001 and random and #%00000001 - sta color +@pl sta color jsr plot inw xdraw dec temp @@ -1064,7 +1072,7 @@ DoNotClearParachute sta temp ; Loop Counter ByteBelowTank jsr point_plot - beq EmptyPoint2 + bne EmptyPoint2 sec ror UnderTank2 sec @@ -1310,8 +1318,7 @@ NoClearTanks .IF TARGET >= 800 lda FastSoilDown bne GoFast - lda CONSOL - and #%00000001 ; START KEY + jsr CheckStartKey ; START KEY bne @+ GoFast jmp SoilDownTurbo.NoClearTanks @@ -1331,18 +1338,14 @@ NextColumn1 mwa #0 ydraw NextPoint1 jsr point_plot - beq StillNothing - ldy #0 - lda ydraw - sta (tempor2),y - sta (temp),y - jmp FoundPeek1 + beq FoundFirstPoint StillNothing inc ydraw lda ydraw cmp #screenheight bne NextPoint1 ; no pixels on whole column !!! +FoundFirstPoint ldy #0 lda ydraw sta (tempor2),y @@ -1352,16 +1355,14 @@ FoundPeek1 inw temp inw xdraw ;vcmp xdraw,screenwidth,NextColumn1 - cpw xdraw RangeRight - bcc NextColumn1 - beq NextColumn1 + cpw RangeRight xdraw + bcs NextColumn1 ; we have both tables filled with starting values ; main loop starts here MainFallout2 .IF TARGET >= 800 - lda CONSOL - and #%00000001 ; START KEY + jsr CheckStartKey ; START KEY bne NoFastDown jmp SoilDownTurbo.NoClearTanks NoFastDown @@ -1389,7 +1390,7 @@ FalloutOfLine ; and checking if there is a pixel there sta ydraw jsr point_plot - bne ThereIsPixelHere + beq ThereIsPixelHere ; if no pixel we plot it mva #1 color jsr plot.MakePlot @@ -1410,9 +1411,8 @@ ColumnIsReady inw tempor2 inw xdraw ;vcmp xdraw,screenwidth,FalloutOfLine - cpw xdraw RangeRight - bcc FalloutOfLine - beq FalloutOfLine + cpw RangeRight xdraw + bcs FalloutOfLine jsr CheckExitKeys ; Check for O, Esc or Start+Option keys spl:rts ; exit if pressed 'Exit keys' @@ -1421,7 +1421,7 @@ ColumnIsReady ; level of the mountains jeq MainFallout2 ; now correct heights are in the mountaintable - sta color ; Pozor! :) we know - now A=1 + ;sta color ; Pozor! :) we know - now A=1 ... but DrawTanks set color to 1 NothingToFall jmp DrawTanks ; rts @@ -1433,7 +1433,7 @@ NothingToFall mwa #0 xdraw ; starting point -getrandomY ;getting random Y coordinate +/* getrandomY ;getting random Y coordinate ; sec ; ??? lda random cmp #screenheight-(margin*4) ;it means that max line=199 @@ -1441,8 +1441,8 @@ getrandomY ;getting random Y coordinate ; clc ; C is clear adc #(margin*2) sta ydraw - sta yfloat+1 - mva #0 yfloat ;yfloat equals to e.g. 140.0 + sta yfloat+1 */ + sta yfloat ;yfloat equals to e.g. 140.0 (A=0) mva #screenheight-margin-5 yfloat+1 sta ydraw @@ -1460,23 +1460,21 @@ NextPart sta delta+1 ; before the dot (delta+1.delta) lda random - and #$01 ;random sign (+/- or up/down) +; and #$01 ;random sign (+/- or up/down) sta UpNdown ; theoretically we have here ready ; fixed-point delta value - ; (-1*(UpNdown))*(delta+1.delta) + ; (-1*(UpNdown.7th.bit))*(delta+1.delta) ;loop drawing one line ChangingDirection lda random ;length of the line and #$0f ;max line length - tax - inx - inx - inx - stx deltaX + clc + adc #3 + sta deltaX OnePart jsr placeTanks.CheckTank @@ -1493,8 +1491,8 @@ OnePart sta (modify),y ; Up or Down - lda UpNdown - beq ToBottom + bit UpNdown + bpl ToBottom ToTop ;it means substracting ;sbw yfloat delta @@ -1509,8 +1507,8 @@ ToTop ;it means substracting cmp #margin bcs @+ ; if smaller than 10 - ldx #$00 - stx UpNdown +; ldy #$00 + sty UpNdown ; Y=0 jmp @+ ToBottom @@ -1526,8 +1524,8 @@ ToBottom cmp #screenheight-margin bcc @+ ; if higher than screen - ldx #$01 - stx UpNdown + dey ; Y=0 + sty UpNdown ; Y=$ff @ sta ydraw @@ -1646,8 +1644,15 @@ notZero sta temp lda xtankstableH,y sta temp+1 - ;now we should substract length of the text-1 - ;temp2 = (fx-1)*2 + jsr Calculate4x4TextPosition + jmp TypeLine4x4.noLengthNoColor ; rts + +.endp +;-------------------------------------------------------- +.proc Calculate4x4TextPosition + ; we have X coordinate of center of text in temp + ; now we should substract length of the text-1 + ; temp2 = (fx-1)*2 ldy fx dey tya @@ -1742,11 +1747,8 @@ DOTOldLowestValue lda temp2 sbc #(4+9) ;9 pixels above ground (and tanks...) sta LineYdraw - - jmp TypeLine4x4.noLengthNoColor ; rts - + rts .endp - ;-------------------------------------------------------- .proc DisplayTankNameAbove ; TankNr in X txa ; TankNr @@ -1870,8 +1872,7 @@ quit_areyousure mva #20 fs ; temp, how many times blink the billboard seppuku_loop - lda CONSOL ; turbo mode - and #%00000001 ; START KEY + jsr CheckStartKey ; START KEY sne:mva #1 fs ; finish it mva #4 ResultY ; where seppuku text starts Y-wise on the screen diff --git a/scorch.asm b/scorch.asm index 8c3288a..80930c9 100644 --- a/scorch.asm +++ b/scorch.asm @@ -4,33 +4,44 @@ ;--------------------------------------------------- ;by Tomasz 'pecus' Pecko and Pawel 'pirx' Kalinowski ;Warsaw 2000, 2001, 2002, 2003, 2009, 2012, 2013 -;Miami & Warsaw 2022, 2023 +;Miami & Warsaw 2022, 2023, 2024 -;WARNING! requires mads compiled on 2023-09-13 or later +;WUDSN run settings: ;atari800 -5200 -cart ${outputFilePath} -cart-type 4 ;atari800 -run ${outputFilePath} + +;WARNING! requires mads compiled on 2023-09-13 or later +;compilation: +;mads scorch.asm -o:scorch.bin -d:TARGET=5200 +;mads scorch.asm -o:scorch.xex -d:TARGET=800 +;mads scorch.asm -o:scorch.xex -d:TARGET=800 -d:SPLASH=1 #xex version with splash +;mads scorch.asm -o:scorch.xex -d:TARGET=800 -d:SPLASH=1 -d:CART_VERSION=1 #xex version for cart + + ;--------------------------------------------------- .IFNDEF TARGET .def TARGET = 800 ; 5200 .ENDIF ;--------------------------------------------------- -.def CART_VERSION = 0 -; if 1 - dual splash screen -.def METEORS = 1 -; if 1 - meteors on game -.def XCORRECTION_FOR_PM = 0 -; if 1 - active x position of tanks correction fo PMG -.def FASTER_GRAF_PROCS = 1 -; if 1 - activates faster graphics routines -; (direct writes to screen memory - atari only :) ) +.ifndef SPLASH + .def SPLASH = 0 ; if 0 - no splash screens +.endif +.ifndef CART_VERSION + .def CART_VERSION = 0 ; if 1 - dual splash screen +.endif +.def METEORS = 1 ; if 1 - meteors on game +.def VU_METER = 1 ; if 1 - VU Meter on game +.def XCORRECTION_FOR_PM = 0 ; if 1 - active x position of tanks correction fo PMG +.def FASTER_GRAF_PROCS = 1 ; if 1 - activates faster graphics routines + ; (direct writes to screen memory - atari only :) ) ;--------------------------------------------------- OPT r+ ; saves 10 bytes, and probably works :) https://github.com/tebe6502/Mad-Assembler/issues/10 ;--------------------------------------------------- .macro build - dta d"1.43" ; number of this build (4 bytes) + dta d"1.48" ; number of this build (4 bytes) .endm .macro RMTSong @@ -186,11 +197,22 @@ FirstZpageVariable = $50 .IF TARGET = 800 icl 'Atari/lib/ATARISYS.ASM' icl 'Atari/lib/MACRO.ASM' - icl 'artwork/splash_v2/splash.asm' ; new splash screen and musix - .IF CART_VERSION - icl 'artwork/splash_v1/splash.asm' ; old splash screen (plays music from new splash) - .ENDIF -; icl 'Atari/Manual/manual.asm' ; manuals display + .IF SPLASH = 1 + icl 'artwork/splash_v2/splash.asm' ; new splash screen and musix + .IF CART_VERSION = 1 + icl 'artwork/splash_v1/splash.asm' ; old splash screen (plays music from new splash) + .ENDIF + .ELSE + ; no splash.... dark screean and BASIC off + ORG $2000 + mva #0 dmactls ; dark screen + mva #$ff portb + ; and wait one frame :) + seq:wait ; or waitRTC ? + mva #$ff portb ; BASIC off + rts + ini $2000 + .ENDIF .ELIF TARGET = 5200 OPT h-f+ ; no headers, single block --> cart bin file icl 'Atari/lib/5200SYS.ASM' @@ -212,7 +234,7 @@ FirstZpageVariable = $50 _M = $0d _S = $0e _atari = $fd ; not used in 5200 - _ret = $fd ; not used in 5200 + _ret = $0c ; fire in 5200 _none = $0f .ende .ENDIF @@ -336,7 +358,11 @@ StartAfterSplash .IF CART_VERSION = 1 mva #$ff GradientNr ; #1 to set gradient number 2 :) (next one) - 0 (B/W) .ELSE - mva #0 GradientNr ; #1 to set gradient number 2 :) (next one) - 1 (polish rainbow) + .IF TARGET=5200 + mva #1 GradientNr + .ELSE + mva #0 GradientNr ; #1 to set gradient number 2 :) (next one) - 1 (polish rainbow) + .ENDIF .ENDIF jsr SelectNextGradient.NotWind @@ -404,169 +430,12 @@ NoRMT_PALchange sta JoystickNumber .IF TARGET = 800 ; second joy button state update only on A800 jsr WaitOneFrame ; is necessary for update shadow registers (PADDL0) in VBI - jmp GetKey.Check2button ; update state second joy button + jmp GetKeyFast.Check2button ; update state second joy button .ELSE rts .ENDIF .endp -;-------------------------------------------------- -.proc GetKey -; waits for pressing a key and returns pressed value in A -; when [ESC] is pressed, escFlag is set -; result: A=keycode -;-------------------------------------------------- - jsr WaitForKeyRelease -getKeyAfterWait - .IF TARGET = 800 - lda SKSTAT - cmp #$ff - beq checkJoyGetKey ; key not pressed, check Joy - cmp #$f7 ; SHIFT - beq checkJoyGetKey - .ELIF TARGET = 5200 - lda SkStatSimulator - and #%11111110 - bne checkJoyGetKey ; key not pressed, check Joy - .ENDIF - lda kbcode - cmp #@kbcode._none - beq checkJoyGetKey - and #$3f ; CTRL and SHIFT ellimination - cmp #@kbcode._esc ; 28 ; ESC - bne getkeyend - mvy #$80 escFlag - bne getkeyend - -checkJoyGetKey - ;------------JOY------------- - ;happy happy joy joy - ;check for joystick now - lda STICK0 - and #$0f - cmp #$0f - beq notpressedJoyGetKey - tay - lda joyToKeyTable,y - bne getkeyend - -notpressedJoyGetKey - ;fire - lda STRIG0 - beq JoyButton - .IF TARGET = 800 ; Second joy button , Select and Option key only on A800 - jsr Check2button - bcc SecondButton - bne checkSelectKey -checkSelectKey - lda CONSOL - and #%00000010 ; Select - beq SelectPressed - lda CONSOL - and #%00000100 ; Option - .ENDIF - bne getKeyAfterWait -OptionPressed - lda #@kbcode._atari ; Option key - bne getkeyend -SecondButton -SelectPressed - lda #@kbcode._tab ; Select key - bne getkeyend -JoyButton - lda #@kbcode._ret ; Return key -getkeyend - ldy #0 - sty ATRACT ; reset atract mode - mvy #sfx_keyclick sfx_effect - rts - .IF TARGET = 800 ; Second joy button only on A800 -Check2button - lda PADDL0 - and #$c0 - eor #$C0 - cmp PaddleState - sta PaddleState - rts - .ENDIF -.endp - -;-------------------------------------------------- -.proc getkeynowait -;-------------------------------------------------- - jsr WaitForKeyRelease - lda kbcode - and #$3f ; CTRL and SHIFT ellimination - rts -.endp - -;-------------------------------------------------- -.proc WaitForKeyRelease -;-------------------------------------------------- - lda #128-KeyRepeatSpeed ; tricky - sec - sbc FirstKeypressDelay ; tricky 2 :) - sta pressTimer -StillWait - bit pressTimer - bmi KeyAutoReleased - lda STICK0 - and #$0f - cmp #$0f - bne StillWait - lda STRIG0 - beq StillWait - .IF TARGET = 800 - lda SKSTAT - cmp #$ff - bne StillWait - lda CONSOL - and #%00000110 ; Select and Option only - cmp #%00000110 - bne StillWait - .ELIF TARGET = 5200 - lda SkStatSimulator - and #%11111110 - beq StillWait - .ENDIF -KeyReleased - mva #FirstKeySpeed FirstKeypressDelay - rts -KeyAutoReleased ; autorepeat - mva #0 FirstKeypressDelay - rts -.endp -;-------------------------------------------------- -.proc IsKeyPressed -; result: A=0 - yes , A>0 - no -;-------------------------------------------------- - lda SKSTAT - and #%00000100 - beq @+ - lda #1 -@ and STRIG0 - rts -.endp -;-------------------------------------------------- -.proc DemoModeOrKey -; Waits for the key pressed if at least one human is playing. -; Otherwise, waits 3 seconds (demo mode). -;-------------------------------------------------- - ;check demo mode - ldx numberOfPlayers - dex -checkForHuman ; if all in skillTable other than 0 then switch to DEMO MODE - lda skillTable,x - beq peopleAreHere - dex - bpl checkForHuman - ; no people, just wait a bit - ldy #75 - jmp PauseYFrames - ; rts -peopleAreHere - jmp getkey ; jsr:rts -.endp ;-------------------------------------------------- MakeDarkScreen @@ -577,8 +446,7 @@ MakeDarkScreen ;-------------------------------------------------- .proc WaitOneFrame ;-------------------------------------------------- - lda CONSOL - and #%00000001 ; START KEY + jsr CheckStartKey ; START KEY seq:wait ; or waitRTC ? rts .endp @@ -595,54 +463,11 @@ MakeDarkScreen rts .endp -;-------------------------------------------------- -.proc CheckExitKeys -;-------------------------------------------------- -; Checks keyboard and sets appropriate flags for exit procedures -; If START+OPTION is pressed - exit to GameOver screen -; If 'O' key is pressed - displays "Are you sure?" and - exit to GameOver screen -; If 'Esc' key is pressed - displays "Are you sure?" and - exit to Menu screen -; Just setting the right flags!!! - - ; Select and Option - lda CONSOL - and #%00000101 ; Start + Option - beq QuitToGameover - lda SKSTAT - cmp #$ff - jeq nokeys - cmp #$f7 ; SHIFT - jeq nokeys - - lda kbcode - and #%10111111 ; SHIFT elimination - - cmp #@kbcode._O ; $08 ; O - bne CheckEsc - jsr AreYouSure - bit escFlag - bpl nokeys - ;---O pressed-quit game to game over screen--- -QuitToGameover - mva #$C0 escFlag ; bits 7 and 6 set - rts -CheckEsc - cmp #@kbcode._esc ; 28 ; ESC - bne nokeys -DisplayAreYouSure - jsr AreYouSure - ;---esc pressed-quit game--- -nokeys - bit escFlag - rts -; -.endp ;-------------------------------------------------- .proc ShellDelay ;-------------------------------------------------- ldy flyDelay -Y lda CONSOL - and #%00000001 ; START KEY +Y jsr CheckStartKey ; START KEY beq noShellDelay DelayLoop lda VCOUNT @@ -693,6 +518,8 @@ noingame bne @- rts .endp +;-------------------------------------------------- + icl 'Atari/inputs.asm' ;-------------------------------------------------- icl 'Atari/interrupts.asm' ;---------------------------------------------- diff --git a/scorch.bin b/scorch.bin index 992d178..440bccf 100644 Binary files a/scorch.bin and b/scorch.bin differ diff --git a/scorch_cart_v00d.car b/scorch.car similarity index 96% rename from scorch_cart_v00d.car rename to scorch.car index c9275b6..afb0f3c 100644 Binary files a/scorch_cart_v00d.car and b/scorch.car differ diff --git a/scorch.xex b/scorch.xex index 705dfe2..9234e60 100644 Binary files a/scorch.xex and b/scorch.xex differ diff --git a/scorchC64.asm b/scorchC64.asm index 2585d42..525e402 100644 --- a/scorchC64.asm +++ b/scorchC64.asm @@ -3,7 +3,7 @@ ;--------------------------------------------------- ;by Tomasz 'pecus' Pecko and Pawel 'pirx' Kalinowski ;Warsaw 2000, 2001, 2002, 2003, 2009, 2012, 2013 -;Miami & Warsaw 2022, 2023 +;Miami & Warsaw 2022, 2023, 2024 ;--------------------------------------------------- .def TARGET = 64 ; :) @@ -14,6 +14,7 @@ ; if 1 - activates faster graphics routines ; (direct writes to screen memory - C64 only :) ) ;--------------------------------------------------- +.def VU_METER = 0 ; allways 0! (works only on Atari) opt h-f+ @@ -24,7 +25,7 @@ ;--------------------------------------------------- .macro build - dta d"1.43" ; number of this build (4 bytes) + dta d"1.48" ; number of this build (4 bytes) .endm .macro RMTSong @@ -35,8 +36,9 @@ icl 'definitions.asm' ;--------------------------------------------------- -FirstZpageVariable = $52 ; $57 +FirstZpageVariable = $51 ; $57 .zpvar DliColorBack .byte = FirstZpageVariable + .zpvar ClearSky .byte ; $ff - Crear sky during drawmountains, 0 - no clear sky .zpvar MeteorsFlag .byte ; set 7th bit - block meteors .zpvar MeteorsRound .byte ; set 7th bit - block meteors in round .zpvar GradientNr .byte @@ -246,63 +248,6 @@ StartAfterSplash rts .endp -;-------------------------------------------------- -.proc GetKey -; waits for pressing a key and returns pressed value in A -; when [ESC] is pressed, escFlag is set -; result: A=keycode -;-------------------------------------------------- - jsr WaitForKeyRelease - lda #0 - sta escFlag - lda #$ff - rts -.endp - -;-------------------------------------------------- -.proc getkeynowait -;-------------------------------------------------- - jsr WaitForKeyRelease - lda kbcode - and #$3f ;CTRL and SHIFT ellimination - rts -.endp - -;-------------------------------------------------- -.proc WaitForKeyRelease -;-------------------------------------------------- -StillWait - rts -.endp -;-------------------------------------------------- -.proc IsKeyPressed -; result: A=0 - yes , A>0 - no -;-------------------------------------------------- - lda #1 - rts -.endp -;-------------------------------------------------- -.proc DemoModeOrKey -; Waits for the key pressed if at least one human is playing. -; Otherwise, waits 3 seconds (demo mode). -;-------------------------------------------------- - ;check demo mode - ldx numberOfPlayers - dex -checkForHuman ; if all in skillTable other than 0 then switch to DEMO MODE - lda skillTable,x - beq peopleAreHere - dex - bpl checkForHuman - ; no people, just wait a bit - ;pause 150 - ldy #75 - jmp PauseYFrames - ; rts -peopleAreHere - jmp getkey ; jsr:rts -.endp - ;-------------------------------------------------- MakeDarkScreen ;-------------------------------------------------- @@ -311,7 +256,8 @@ MakeDarkScreen ;-------------------------------------------------- .proc WaitOneFrame ;-------------------------------------------------- - wait ; or waitRTC ? + jsr CheckStartKey ; START KEY + seq:wait ; or waitRTC ? rts .endp @@ -327,22 +273,11 @@ MakeDarkScreen rts .endp -;-------------------------------------------------- -.proc CheckExitKeys -;-------------------------------------------------- -; Checks keyboard and sets appropriate flags for exit procedures -; If START+OPTION is pressed - exit to GameOver screen -; If 'O' key is pressed - displays "Are you sure?" and - exit to GameOver screen -; If 'Esc' key is pressed - displays "Are you sure?" and - exit to Menu screen -; Just setting the right flags!!! - - rts -; -.endp ;-------------------------------------------------- .proc ShellDelay ldy flyDelay -Y +Y jsr CheckStartKey ; START KEY + beq noShellDelay DelayLoop lda $d012 @ cmp $d012 @@ -364,6 +299,8 @@ noShellDelay .proc CopyFromRom rts .endp +;-------------------------------------------------- + icl 'C64/inputs.asm' ;-------------------------------------------------- icl 'C64/interrupts.asm' ;---------------------------------------------- diff --git a/scorchC64.prg b/scorchC64.prg index f98da4a..b66360d 100644 Binary files a/scorchC64.prg and b/scorchC64.prg differ diff --git a/scorch_cart.xex b/scorch_cart.xex index 32c452b..98510f4 100644 Binary files a/scorch_cart.xex and b/scorch_cart.xex differ diff --git a/variables.asm b/variables.asm index 04a254c..627fdbe 100644 --- a/variables.asm +++ b/variables.asm @@ -28,6 +28,9 @@ TanksNames ; DO NOT ZERO ON GAME RESTART - ticket #24 skilltable ; computer controlled players' skills (1-8), 0 - human (no cleaning, ticket #30) .DS MaxPlayers ;---------------------------------------------------- +JoyNumber ; Joystick port number (from 0 to 3) + .DS MaxPlayers +;---------------------------------------------------- variablesToInitialize ;Options DO NOT ZERO ON RESTART GAME - ticket #27 OptionsTable .ds maxOptions ;.by 0,1,2,2,0,1,3,2,0 @@ -155,10 +158,6 @@ ytankstable ;Y positions of tanks (lower left point) .DS MaxPlayers LowResDistances ; coarse tank positions divided by 4 (to be in just one byte) .DS MaxPlayers -JoyNumber ; Joystick port number (from 0 to 3) - .DS MaxPlayers -TankShape ; Tank shape number (from 0 to 2) - .DS MaxPlayers ;---------------------------------------------------- TargetTankNr ; Target tank index (for AI routines) .DS 1 @@ -170,6 +169,8 @@ SecondTryFlag ; For precise AI aiming ;Erase .DS 1 ; if 1 only mask of the character is printed ; on the graphics screen. if 0 character is printed normally +TankShape ; Tank shape number (from 0 to 2) + .DS MaxPlayers ;---------------------------------------------------- ;RangeLeft .DS 2 ;range of the soil to be fallen down ;RangeRight .DS 2 ;it is being set by all Explosions @@ -210,7 +211,7 @@ YHit .DS 2 ;radius .DS 1 ;xcircle .DS 2 ;ycircle .DS 2 -tempcir .DS 2 +;tempcir .DS 2 ;TankFalls FallingSoundBit .DS 1 PreviousFall .DS 1 @@ -219,6 +220,7 @@ EndOfTheFallFlag .DS 1 ; in case of the infinite fall ;FloatingAlt .DS 1 ; floating tank altitude FunkyWallFlag = FloatingAlt ; reuse this variable in different weapon (Funky Bomb)! PreferHumansFlag = FloatingAlt ; second reuse in AI Aim proc +;PreferHumansFlag .DS 1 ;---------------------------------------------------- ;Flight ;variables for 5 missiles (used for mirv) diff --git a/weapons.asm b/weapons.asm index e54dabb..a614162 100644 --- a/weapons.asm +++ b/weapons.asm @@ -41,16 +41,16 @@ ExplosionRoutines .word riotblast-1 ;Riot_Blast ;_16 .word riotbomb-1 ;Riot_Bomb ;_17 .word heavyriotbomb-1 ;Heavy_Riot_Bomb;_18 - .word babydigger-1 ;Baby_Digger ;_19 - .word digger-1 ;Digger ;_20 - .word heavydigger-1 ;Heavy_Digger ;_21 - .word sandhog-1 ;Sandhog ;_22 - .word heavysandhog-1 ;Heavy_Sandhog ;_23 - .word dirtclod-1 ;Dirt_Clod ;_24 - .word dirtball-1 ;Dirt_Ball ;_25 - .word tonofdirt-1 ;Ton_of_Dirt ;_26 - .word liquiddirt-1 ;Liquid_Dirt ;_27 - .word dirtcharge-1 ;Dirt_Charge ;_28 + .word digger-1 ;Digger ;_19 + .word heavydigger-1 ;Heavy_Digger ;_20 + .word sandhog-1 ;Sandhog ;_21 + .word heavysandhog-1 ;Heavy_Sandhog ;_22 + .word dirtclod-1 ;Dirt_Clod ;_23 + .word dirtball-1 ;Dirt_Ball ;_24 + .word tonofdirt-1 ;Ton_of_Dirt ;_25 + .word liquiddirt-1 ;Liquid_Dirt ;_26 + .word dirtcharge-1 ;Dirt_Charge ;_27 + .word propaganda-1 ;Propaganda ;_28 .word punch-1 ;Baby_Sandhog ;_29 .word BFG-1 ;Buy_me ;_30 .word laser-1 ;Laser ;_31 @@ -380,9 +380,73 @@ GoRiotBomb ; jmp xriotbomb .endp ; ------------------------ -.proc babydigger - lda #1 ; diggery ; how many branches (-1) -GoBabydiggerSFX +.proc propaganda + ; It floods the target with propaganda texts. + lda #80 ; max text width with additional margins (left/right edges of the screen) + sta ExplosionRadius ; set soildown range + jsr CalculateExplosionRange + + mwa xdraw tempXROLLER ; save X coordinate of hitpoint + + mva #11 TempXfill ; number of text to display +nexttext + ; play SFX + mva #sfx_digger sfx_effect +@ lda random ; randomize propaganda messege + cmp #talk.NumberOfPropagandaTexts + bcs @- + + sta TextNumberOff + ; all text start from `talk` and end with an inverse. + ; we go through the `talk`, count number of inverses. + ; if equal to TextNumberOff, it is our text, printit + lda #$ff + sta plot4x4color + mwa #talk LineAddress4x4 + jsr _calc_inverse_display + ; now find length of the text +@ iny + lda (LineAddress4x4),y + bpl @- + iny + sty fx + mwa tempXROLLER temp ; X coordinate of hitpoint + ; calculate position of message + jsr Calculate4x4TextPosition + ; and randomize Y coordinate (+/- 16pixels) + lda random + and #%00011111 + adc LineYdraw + sbc #16 + sta LineYdraw + ; randomize X coordinate (+/- 8 pixels) + lda random + and #%00000111 + clc + adc LineXdraw + sta LineXdraw + bcc @+ + inc LineXdraw+1 +@ sec + sbc #4 + sta LineXdraw + bcs DisplayMessage + dec LineXdraw+1 +DisplayMessage + ; display propaganda message + jsr TypeLine4x4.noLengthNoColor + + ldy #7 + jsr PauseYFrames + + dec TempXfill + bne nexttext + rts +.endp +; ------------------------ +.proc digger ; + lda #3 ; diggery ; how many branches (-1) +GoDiggerSFX sta diggery mva #sfx_digger sfx_effect mva #0 sandhogflag @@ -390,14 +454,9 @@ GoBabydiggerSFX bne xdigger .endp ; ------------------------ -.proc digger ; - lda #3 ; diggery ; how many branches (-1) - bne babydigger.GoBabydiggerSFX -.endp -; ------------------------ .proc heavydigger lda #7 ; diggery ; how many branches (-1) - bne babydigger.GoBabydiggerSFX + bne digger.GoDiggerSFX .endp ; ------------------------ .proc babysandhog @@ -1218,29 +1277,22 @@ ContinueToCheckMaxForce2 ; $FB - any key ; $f7 - shift ; $f3 - shift+key - +.IF VU_METER = 1 + jsr VUMeter.EndMeterAndReset +.ENDIF notpressed jsr CheckExitKeys ; Check for O, Esc or Start+Option keys spl:rts ; exit if pressed 'Exit keys' - +.IF VU_METER = 1 + jsr VUMeter +.ENDIF ldx TankNr ; for optimize - ; Select and Option - lda CONSOL - tay - and #%00000100 - beq callActivation ; Option key - tya - and #%00000010 - jeq pressedTAB ; Select key - lda SKSTAT - cmp #$ff - jeq checkJoy - cmp #$f7 ; SHIFT - jeq checkJoy - - lda kbcode + jsr GetKeyFast + mvy #00 EscFlag ; prevent for set EscFalg in GetKey! we checking this in CheckExitKeys! and #%10111111 ; SHIFT elimination + cmp #@kbcode._atari ; Option key + beq callActivation cmp #@kbcode._A ; $3f ; A bne @+ callActivation @@ -1276,12 +1328,12 @@ NoSpyHard mva #0 escFlag jmp ReleaseAndLoop @ - cmp #$80|@kbcode._up +/*o cmp #$80|@kbcode._up jeq CTRLPressedUp cmp #$80|@kbcode._down jeq CTRLPressedDown cmp #$80|@kbcode._tab - jeq CTRLPressedTAB + jeq CTRLPressedTAB */ jumpFromStick .IF TARGET = 800 @@ -1290,10 +1342,7 @@ jumpFromStick .ELSE cmp #@kbcode._help ; Help (# in A5200) bne NoVdebugSwitch - sta pressTimer ; reset 0+@kbcode._help (tricky) - jsr WaitForKeyRelease.StillWait - lda pressTimer - cmp #(25+@kbcode._help) ; 1/2s - long press only + jsr WaitForLongPress bcc NoVdebugSwitch .ENDIF lda Vdebug @@ -1303,6 +1352,7 @@ jumpFromStick jmp ReleaseAndLoop NoVdebugSwitch + mvy #1 Erase ; optimization and #$3f ;CTRL and SHIFT ellimination cmp #@kbcode._up ; $e jeq pressedUp @@ -1314,6 +1364,8 @@ NoVdebugSwitch jeq pressedRight cmp #@kbcode._space ; $21 jeq pressedSpace + cmp #@kbcode._ret ; Fire (Joy) + jeq pressedSpace cmp #@kbcode._tab ; $2c jeq pressedTAB cmp #@kbcode._M ; $25 ; M @@ -1327,30 +1379,8 @@ NoVdebugSwitch jmp ReleaseAndLoop .ENDIF EndKeys + mva #$80 pressTimer jmp notpressed -checkJoy - ;------------JOY------------- - ;happy happy joy joy - ;check for joystick now - lda STICK0 - and #$0f - cmp #$0f - beq notpressedJoy - tay - mva #0 ATRACT ; reset atract mode - lda joyToKeyTable,y - jmp jumpFromStick -notpressedJoy - .IF TARGET = 800 - ;second fire only Atari 800 - jsr GetKey.Check2button - jcc pressedTAB - .ENDIF - ;fire - lda STRIG0 - jeq pressedSpace - mva #$ff pressTimer ; stop counting frames - jmp notpressed ; pressedUp @@ -1402,8 +1432,6 @@ pressedDown cmp #25 ; 1/2s bcs CTRLPressedDown - mva #sfx_set_power_1 sfx_effect - ;ldx TankNr ; optimized dec ForceTableL,x lda ForceTableL,x @@ -1416,6 +1444,7 @@ ForceGoesZero sta ForceTableH,x sta ForceTableL,x @ + mva #sfx_set_power_1 sfx_effect jmp BeforeFire CTRLPressedDown @@ -1429,7 +1458,7 @@ CTRLPressedDown jcs BeforeFire dec ForceTableH,x bmi ForceGoesZero - jmp BeforeFire + bpl @- pressedRight ;ldx TankNr ; optimized @@ -1438,30 +1467,30 @@ pressedRight cmp #25 ; 1/2s bcs CTRLPressedRight - mva #sfx_set_power_2 sfx_effect - mva #1 Erase +; mva #1 Erase jsr DrawTankNr.BarrelChange dec:lda AngleTable,x cmp #255 ; -1 - jne BeforeFire + bne @+ lda #180 sta AngleTable,x +@ + mva #sfx_set_power_2 sfx_effect jmp BeforeFire CTRLPressedRight ;ldx TankNr ; optimized - mva #sfx_set_power_2 sfx_effect - mva #1 Erase +; mva #1 Erase jsr DrawTankNr.BarrelChange lda AngleTable,x sec sbc #4 sta AngleTable,x cmp #4 ; smallest angle for speed rotating - jcs BeforeFire + bcs @- lda #180 sta AngleTable,x - jmp BeforeFire + bne @- pressedLeft @@ -1471,31 +1500,31 @@ pressedLeft cmp #25 ; 1/2s bcs CTRLPressedLeft - mva #sfx_set_power_2 sfx_effect - mva #1 Erase +; mva #1 Erase jsr DrawTankNr.BarrelChange INC AngleTable,x lda AngleTable,x cmp #180 - jcc BeforeFire + bcc @+ lda #0 sta AngleTable,x +@ + mva #sfx_set_power_2 sfx_effect jmp BeforeFire CTRLPressedLeft ;ldx TankNr ; optimized - mva #sfx_set_power_2 sfx_effect - mva #1 Erase +; mva #1 Erase jsr DrawTankNr.BarrelChange lda AngleTable,x clc adc #4 sta AngleTable,x cmp #180-4 - jcc BeforeFire + bcc @- lda #0 sta AngleTable,x - jmp BeforeFire + beq @- pressedTAB mva #sfx_purchase sfx_effect @@ -1544,6 +1573,7 @@ pressedS eor:sta noSfx ReleaseAndLoop jsr WaitForKeyRelease +; mva #$80 pressTimer jmp BeforeFire pressedSpace @@ -1551,12 +1581,9 @@ pressedSpace ;we shoot here!!! lda #0 sta ATRACT ; reset atract mode - sta pressTimer ; reset - jsr WaitForKeyRelease.StillWait - lda pressTimer - cmp #25 ; 1/2s - bcc fire - jmp callInventory + jsr WaitForLongPress + bcc fire ; short press + jmp callInventory ; long press fire RTS .endp @@ -2754,41 +2781,17 @@ notpressed jsr DrawTankEngine ; enimation ends - lda SKSTAT - cmp #$ff - jeq checkJoy - cmp #$f7 ; SHIFT - jeq checkJoy - - lda kbcode - and #%00111111 ; CTRL and SHIFT elimination - -jumpFromStick + jsr GetKeyFast cmp #@kbcode._left ; $6 jeq pressedLeft cmp #@kbcode._right ; $7 jeq pressedRight cmp #@kbcode._space ; $21 jeq pressedSpace - jmp notpressed -checkJoy - ;------------JOY------------- - ;happy happy joy joy - ;check for joystick now - lda STICK0 - and #$0f - cmp #$0f - beq notpressedJoy - tay - lda joyToKeyTable,y - jmp jumpFromStick -notpressedJoy - ;fire - lda STRIG0 + cmp #@kbcode._ret ; Fire (Joy) jeq pressedSpace jmp notpressed - pressedRight lda ShieldEnergy,x jeq pressedSpace