Files
Young-lumberjack/lumber.asm
T
2025-03-19 14:39:50 +01:00

1728 lines
40 KiB
NASM

;Young lumberjack closure
;---------------------------------------------------
.IFNDEF TARGET
.def TARGET = 800 ; 5200
.ENDIF
;---------------------------------------------------
OPT r+ ; saves 10 bytes, and probably works :) https://github.com/tebe6502/Mad-Assembler/issues/10
;---------------------------------------------------
.macro build
dta d"0.20" ; number of this build (4 bytes)
.endm
.macro RMTSong
lda #:1
jsr RMTSongSelect
.endm
;---------------------------------------------------
icl 'lib/ATARISYS.ASM'
icl 'lib/MACRO.ASM'
display = $a000
.zpvar temp .word = $80
.zpvar temp2 .word
.zpvar tempbyte .byte
.zpvar SyncByte .byte
.zpvar StateFlag .byte ; 0 - game, 1 - start screen, 2 game over screen, etc.
.zpvar PowerValue .byte ; power: 0 - 48
.zpvar PowerTimer .byte
.zpvar PowerDownSpeed .byte
.zpvar PowerSpeedIndex .byte
.zpvar LevelValue .byte
.zpvar LumberjackDir .byte ; 2 - on left , 1 - on right
.zpvar PaddleState .byte
.zpvar LowCharsetBase .byte
.zpvar displayposition .word
.zpvar LastKey .byte ; $ff if no key pressed or last key released
.zpvar RMT_blocked noSfx SFX_EFFECT .byte
.zpvar AutoPlay .byte ; Auto Play flag ($80 - auto)
.zpvar birdsHpos .byte ; 0 - no birds on screen
.zpvar birdsOffset .byte
.zpvar clouds1Hpos,clouds2Hpos,clouds3Hpos .byte ; 0 - no cloud on screen
; PMG registers for sprites over horizon
.zpvar HPOSP0_u .byte
.zpvar HPOSP1_u .byte
.zpvar HPOSP2_u .byte
.zpvar HPOSP3_u .byte
.zpvar HPOSM0_u .byte
.zpvar HPOSM1_u .byte
.zpvar HPOSM2_u .byte
.zpvar HPOSM3_u .byte
.zpvar SIZEP0_u .byte
.zpvar SIZEP1_u .byte
.zpvar SIZEP2_u .byte
.zpvar SIZEP3_u .byte
.zpvar SIZEM_u .byte
; PMG registers for sprites under horizon
.zpvar HPOSP0_d .byte
.zpvar HPOSP1_d .byte
.zpvar HPOSP2_d .byte
.zpvar HPOSP3_d .byte
.zpvar HPOSM0_d .byte
.zpvar HPOSM1_d .byte
.zpvar HPOSM2_d .byte
.zpvar HPOSM3_d .byte
.zpvar SIZEP0_d .byte
.zpvar SIZEP1_d .byte
.zpvar SIZEP2_d .byte
.zpvar SIZEP3_d .byte
.zpvar SIZEM_d .byte
.zpvar GRAFP0_d .byte
.zpvar GRAFP1_d .byte
.zpvar GRAFP2_d .byte
.zpvar GRAFP3_d .byte
.zpvar GRAFM_d .byte
.zpvar COLPM0_d .byte
.zpvar COLPM1_d .byte
.zpvar COLPM2_d .byte
.zpvar COLPM3_d .byte
RMT_zpvars = AutoPlay+1 ; POZOR!!! RMT vars go here
;---------------------------------------------------
org $2000
MODUL
;ins 'art/muzyka_stripped.rmt',+5 ; my RMT 1.28 on WINE is apparently broken. I lost some hair here (5, not 6)
;.align $100
;icl 'art/rmtplayr.a65'
;---------------------------------------------------
.align $400
PMmemory
.ds $400
font_game_upper
ins 'art/tu.fnt' ;
font_game_lower_right
ins 'art/tl_r.fnt' ;
font_game_lower_left
ins 'art/tl_l.fnt' ;
font_game_rip
ins 'art/t_rip.fnt' ;
dl_level
.by $10
.by $44
.wo power_bar ; power indicator
.by $04
.by $44
.wo gamescreen_middle ; branches
:2 .by $04
.by $84 ; DLI1 - color change (power bar - letters) and second clouds
:5 .by $04
.by $84 ; DLI2 - last clouds
:7 .by $04
.by $84 ; DLI3
.by $44
animation_addr
.wo gamescreen_r_ph1p1
.by $84 ; DLI4
:3 .by $04
.by $84 ; DLI5
.by $84 ; DLI6
.by $04
.by $44
lastline_addr
.wo last_line_r
.by $41
.wo dl_level
;---------------------------------------------------
Power = power_bar+32+10
gamescreen_middle
.ds 32*18 ; 18 lines
screen_score = gamescreen_middle+6*32+14
screen_level = gamescreen_middle+9*32+13
;---------------------------------------------------
icl 'art/anim_exported.asm'
; Animations:
; v1 - if no branches
; v2 - if the branch under (due to change of sides) the lumberjack and none above
; v3 - if the branch opposite the lumberjack and no branch and none above
; v4 - if no branch at the level of the lumberjack and branch above (kill)
; v5 - if the branch under (due to change of sides) the lumberjack and branch above (kill)
; v6 - if the branch opposite the lumberjack and branch above (kill)
; v7 - if no branch at the level of the lumberjack and branch above on the other side
; v8 - if the branch under (due to change of sides) the lumberjack and branch above on the other side
; v9 - if the branch opposite the lumberjack and branch above on the other side
;--------------------------------------------------
;--------------------------------------------------
.proc vint
;--------------------------------------------------
vdli IngameDLI1
; over horizon
; PMG horizontal coordinates and sizes
txa
pha
ldx #$0c
@ lda HPOSP0_u,x
sta HPOSP0,x
dex
bpl @-
pla
tax
; fly birds
lda birdsHpos
bne fly_birds
; if no birds then randomize new birds start
lda RANDOM
and #%11111100 ; 1:64
bne no_birds
fly_birds
lda RTCLOK+2
and #%00000011
bne no_wings_change
inc birdsHpos
lda birdsHpos
sta HPOSP0_u
clc
adc #6
sta HPOSP1_u
; wings
lda birdsHpos
and #%00000011
bne no_wings_change
lda birdsHpos
and #%00000100
bne wings_phase_a
jsr PrepareBirdsPM.bird_b
jmp no_wings_change
wings_phase_a
jsr PrepareBirdsPM.bird_a
no_wings_change
no_birds
lda RTCLOK+2
and #%00000111
bne no_clouds_change
; fly clouds
lda clouds1Hpos
bne cloud1_fly
; if no cloud 1 then randomize new cloud 2 start
lda RANDOM
and #%11111100 ; 1:64
bne no_new_cloud1
; then randomize new cloud 1 shape
lda RANDOM
;
cloud1_fly
dec clouds1Hpos
lda clouds1Hpos
clc
sta HPOSM2_u
adc #4
sta HPOSP2_u
adc #8
sta HPOSP3_u
adc #8
sta HPOSM3_u
no_new_cloud1
lda clouds2Hpos
bne cloud2_fly
; if no cloud 2 randomize new cloud 2 start
lda RANDOM
and #%11111100 ; 1:64
bne no_new_cloud2
; then randomize new cloud 2 shape
lda RANDOM
;
cloud2_fly
dec clouds2Hpos
no_new_cloud2
lda clouds3Hpos
bne cloud3_fly
; if no cloud 3 then randomize new cloud 3 start
lda RANDOM
and #%11111100 ; 1:64
bne no_new_cloud3
; then randomize new cloud 3 shape
lda RANDOM
;
cloud3_fly
dec clouds3Hpos
no_new_cloud3
no_clouds_change
lda StateFlag
bne wait_for_timer
; only during game
; power down
dec PowerTimer
bne wait_for_timer
; one bar down
mva PowerDownSpeed PowerTimer
jsr PowerDown
wait_for_timer
; mva #13 VSCROL ; FOX gfx mode only
/*
bit RMT_blocked
bmi SkipRMTVBL
; ------- RMT -------
lda sfx_effect
bmi lab2
asl @ ; * 2
tay ;Y = 2,4,..,16 instrument number * 2 (0,2,4,..,126)
ldx #0 ;X = 0 channel (0..3 or 0..7 for stereo module)
lda #0 ;A = 0 note (0..60)
bit noSfx
smi:jsr RASTERMUSICTRACKER+15 ;RMT_SFX start tone (It works only if FEAT_SFX is enabled !!!)
lda #$ff
sta sfx_effect ;reinit value
lab2
jsr RASTERMUSICTRACKER+3 ;1 play
; ------- RMT -------
SkipRMTVBL
*/
/* ;sfx
lda sfx_effect
bmi lab2
asl ; * 2
tay ;Y = 2,4,..,16 instrument number * 2 (0,2,4,..,126)
ldx #3 ;X = 3 channel (0..3 or 0..7 for stereo module)
lda #12 ;A = 12 note (0..60)
jsr RASTERMUSICTRACKER+15 ;RMT_SFX start tone (It works only if FEAT_SFX is enabled !!!)
;
lda #$ff
sta sfx_effect ;reinit value
;
lab2
jsr RASTERMUSICTRACKER+3
skipSoundFrame */
; key release flag
lda LastKey
cmp #$ff
beq key_released
jsr GetKeyFast
cmp LastKey
beq last_key_still_press
mva #$ff LastKey
last_key_still_press
key_released
jmp XITVBV
.endp
;--------------------------------------------------
.proc IngameDLI1
;--------------------------------------------------
pha
mva #$0c COLPF2 ; white (numbers and letters)
; set cloud 2 horizontal position
lda clouds2Hpos
clc
sta HPOSM2
adc #4
sta HPOSP2
adc #8
sta HPOSP3
adc #8
sta HPOSM3
mwa #IngameDLI1.DLI2 VDSLST
pla
rti
DLI2
pha
; set cloud 3 horizontal position
lda clouds3Hpos
clc
sta HPOSM2
adc #4
sta HPOSP2
adc #8
sta HPOSP3
adc #8
sta HPOSM3
mwa #IngameDLI1.DLI3 VDSLST
pla
rti
DLI3
pha
sta WSYNC
mva LowCharsetBase CHBASE
mva #$f6 COLPF3 ; light brown
;nop
;nop
;nop
mva #$B4 COLBAK ; thin line
sta WSYNC
mva #$DA COLBAK ; additional lines
sta WSYNC
sta WSYNC
mva #$c8 COLBAK ; green
; under horizon
; PMG colors, horizontal coordinates and sizes
txa
pha
ldx #$15
@ lda HPOSP0_d,x
sta HPOSP0,x
dex
bpl @-
pla
tax
inc SyncByte
mwa #IngameDLI1.DLI4 VDSLST
pla
rti
DLI4
pha
sta WSYNC
mva #$82 COLPF2 ; hat
:4 STA WSYNC
mva #$0c COLPF2
mwa #IngameDLI1.DLI5 VDSLST
pla
rti
DLI5
pha
sta WSYNC
mva #$ea COLPF2 ; button and buckle
mva #>font_game_upper CHBASE
mwa #IngameDLI1.DLI6 VDSLST
pla
rti
DLI6
pha
sta WSYNC
sta WSYNC
sta WSYNC
mva #$94 COLPF2 ; blue pants
pla
rti
.endp
;--------------------------------------------------
main
;--------------------------------------------------
jsr WaitForKeyRelease
jsr MakeDarkScreen
jsr initialize
RMTsong song_main_menu
jsr StartScreen
RMTSong song_ingame
jsr ScoreClear
gameloop
jsr MakeDarkScreen
jsr LevelScreen
jsr PlayLevel
jsr MakeDarkScreen
;jsr NextLevel
; RMTSong song_ingame
jsr AudioInit ; after I/O
jmp gameloop
EndOfLife
;dec Lives ; decrease Lives
;lda Lives
;cmp #"0"
;beq gameOver ; if no lives - game over
;jsr NextLife
jmp gameloop
gameOver
;game over
;RMTSong song_game_over
;jsr HiScoreCheckWrite
jsr GameOverScreen
@ lda CONSOL
and #@consol(start) ; START
beq main
lda TRIG0 ; fire
jeq main
jmp @-
;--------------------------------------------------
.proc StartScreen
;--------------------------------------------------
/* jsr MakeDarkScreen
mwa #dl_start dlptrs
lda #$0 ;+GTIACTLBITS
sta GPRIOR
sta COLBAKS
lda #@dmactl(standard|dma) ; normal screen width, DL on, P/M off
sta dmactls
pause 1
StartLoop
;jmp StartLoop
EndOfStartScreen */
mva #1 StateFlag
rts
.endp
;--------------------------------------------------
.proc LevelScreen
;--------------------------------------------------
jsr MakeDarkScreen
jsr PrepareLevelPM
jsr PrepareBirdsPM
jsr PrepareCloudsPM
ldx #2
mwa #dl_level dlptrs
lda #@dmactl(narrow|dma|missiles|players|lineX2) ; narrow screen width, DL on, P/M on (2lines)
sta dmactls
mva #%00000011 GRACTL
mva #>font_game_upper CHBAS
jsr SetPMr1
pause 5
mva #0 StateFlag
rts
.endp
;--------------------------------------------------
.proc GameOverScreen
;--------------------------------------------------
/* jsr MakeDarkScreen
ldx #5
mwa #dl_over dlptrs
lda #%00110010 ; normal screen width, DL on, P/M off
sta dmactls
pause 20 */
mva #2 StateFlag
rts
.endp
;--------------------------------------------------
.proc MakeDarkScreen
;--------------------------------------------------
mva #0 dmactls ; dark screen
; and wait one frame :)
pause 1
rts
.endp
;--------------------------------------------------
.proc PlayLevel
;--------------------------------------------------
loop
; PUT GAME HERE
lda branches_list+5
cmp LumberjackDir ; branch and Lumberjack ?
jeq LevelDeath
lda LastKey
cmp #$ff
beq key_released_before
bne No_keys
key_released_before
jsr GetKeyFast
cmp #@kbcode._left
beq left_pressed
cmp #@kbcode._right
beq right_pressed
; other keys or no key
cmp #@kbcode._up
bne NoNextLevel
; next level if joy UP
sta LastKey
jsr LevelUp
NoNextLevel
No_keys
lda PowerValue
jeq LevelDeath
jmp loop
right_pressed
sta LastKey
/*
; test for right lower branch
lda branches_list+5
cmp #1
bne no_r_branch
; death by lower right branch
mva #>font_game_lower_right LowCharsetBase
mwa #last_line_r lastline_addr
WaitForSync
mwa #gamescreen_r_ph1p1 animation_addr
mva #1 LumberjackDir ; right side
bne LevelDeath
no_r_branch
*/
jsr ScoreUp
jsr PowerUp
jsr SetPMr1
lda branches_list+4 ; check branch over
beq no_brancho_r
; branch over lumberjack
cmp #1 ; right branch (kill)
bne no_kill_r
;
lda branches_list+5 ; check branch on lumberjack level
beq kill_2branch_r
cmp #2 ; left branch - animation v4
bne kill_2branch_r ; animation v5 (=v4)
jsr AnimationR6
jmp go_loop
kill_2branch_r
jsr AnimationR4
jmp go_loop
no_kill_r
lda branches_list+5 ; check branch on lumberjack level
beq no_kill_2branch_r
cmp #2 ; left branch - animation v7
bne no_kill_2branch_r ; animation v8 (=v7)
jsr AnimationR9
jmp go_loop
no_kill_2branch_r
jsr AnimationR7
jmp go_loop
no_brancho_r
;no branch over lumberjack
lda branches_list+5 ; check branch on lumberjack level
beq no_2branch_r
cmp #2 ; left branch - animation v3
bne no_2branch_r ; animation v2 (=v1)
jsr AnimationR3
jmp go_loop
no_2branch_r
jsr AnimationR1
jmp go_loop
left_pressed
sta LastKey
/*
; test for left lower branch
lda branches_list+5
cmp #2
bne no_l_branch
; death by lower left branch
mva #>font_game_lower_left LowCharsetBase
mwa #last_line_l lastline_addr
WaitForSync
mwa #gamescreen_l_ph1p1 animation_addr
mva #2 LumberjackDir ; left side
bne LevelDeath
no_l_branch
*/
jsr ScoreUp
jsr PowerUp
jsr SetPMl1
lda branches_list+4 ; check branch over
beq no_brancho_l
; branch over lumberjack
cmp #2 ; left branch (kill)
bne no_kill_l
;
lda branches_list+5 ; check branch on lumberjack level
beq kill_2branch_l
cmp #1 ; right branch - animation v4
bne kill_2branch_l ; animation v5 (=v4)
jsr AnimationL6
jmp go_loop
kill_2branch_l
jsr AnimationL4
jmp go_loop
no_kill_l
lda branches_list+5 ; check branch on lumberjack level
beq no_kill_2branch_l
cmp #1 ; right branch - animation v7
bne no_kill_2branch_l ; animation v8 (=v7)
jsr AnimationL9
jmp go_loop
no_kill_2branch_l
jsr AnimationL7
jmp go_loop
no_brancho_l
; no branch over lumberjack
lda branches_list+5 ; check branch on lumberjack level
beq no_2branch_l
cmp #1 ; right branch - animation v3
bne no_2branch_l ; animation v2 (=v1)
jsr AnimationL3
jmp go_loop
no_2branch_l
jsr AnimationL1
jmp go_loop
LevelDeath
jsr SetRIPscreen
mva #2 StateFlag
@
;mva RANDOM COLBAK
jsr GetKey
cmp #@kbcode._space
bne @-
; restart game
jsr ScoreClear
;jsr InitBranches
;jsr draw_branches
lda branches_list+5
cmp LumberjackDir
bne branch_ok
mva #0 branches_list+5 ; branches at Lumberjack level and position - remove it
branch_ok
jsr SetLumberjackPosition
jsr LevelReset
mva #24 PowerValue ; half power
jsr draw_PowerBar
mva #0 StateFlag
go_loop
;jsr WaitForKeyRelease
jmp loop
LevelOver
; level over
jsr WaitForKeyRelease
rts
.endp
;--------------------------------------------------
icl 'art/animations.asm'
;--------------------------------------------------
;--------------------------------------------------
.proc SetRIPscreen
;--------------------------------------------------
:5 WaitForSync
mva #>font_game_rip LowCharsetBase
mwa #last_line_RIP lastline_addr
jsr HidePM
lda LumberjackDir ; branch and Lumberjack ?
cmp branches_list+5
beq BranchDeath
;no branch death
cmp #1
bne leftside
; right death
lda branches_list+5
beq no_branch_r
; left side branch
mwa #RIPscreen_r_Lbranch animation_addr
rts
no_branch_r
mwa #RIPscreen_r_nobranch animation_addr
rts
leftside
; right death
lda branches_list+5
beq no_branch_l
; right side branch
mwa #RIPscreen_l_Rbranch animation_addr
rts
no_branch_l
mwa #RIPscreen_l_nobranch animation_addr
rts
BranchDeath
cmp #1
bne leftbranch
; right branch
mwa #RIPscreen_r_branch animation_addr
rts
leftbranch
mwa #RIPscreen_l_branch animation_addr
rts
.endp
;--------------------------------------------------
.proc SetLumberjackPosition
;--------------------------------------------------
WaitForSync
lda LumberjackDir
cmp #1
beq right_side
left_side
jsr SetPMl1
mva #>font_game_lower_left LowCharsetBase
mwa #last_line_l lastline_addr
lda branches_list+5
cmp #1
bne no_branch_r
mwa #gamescreen_l_ph1p2 animation_addr
rts
no_branch_r
mwa #gamescreen_l_ph1p1 animation_addr
rts
right_side
jsr SetPMr1
mva #>font_game_lower_right LowCharsetBase
mwa #last_line_r lastline_addr
lda branches_list+5
cmp #2
bne no_branch_l
mwa #gamescreen_r_ph1p2 animation_addr
rts
no_branch_l
mwa #gamescreen_r_ph1p1 animation_addr
rts
.endp
;--------------------------------------------------
.proc AudioInit
;--------------------------------------------------
; pokeys init
lda #3
sta skctl ; put Pokey into Init
sta skctl+$10
ldx #8
lda #0
@
sta $D200,x ; clear all voices, set AUDCTL to 00
sta $D210,x ; clear all voices, set AUDCTL to 00
dex
bpl @-
rts
.endp
;--------------------------------------------------
.proc RestoreRedBar
;--------------------------------------------------
mva #$36 COLOR2 ; red
rts
.endp
;--------------------------------------------------
.proc initialize
;--------------------------------------------------
mva #>font_game_upper CHBAS
mva #>font_game_lower_right LowCharsetBase
mva #$00 PCOLR0 ; = $02C0 ;- - rejestr-cień COLPM0
mva #$00 COLOR0
mva #$88 COLBAKS ; sky
mva #$f4 COLOR1 ; dark brown
mva #$36 COLOR2 ; red
mva #$f6 COLOR3 ; light brown
;mva #$ff COLOR4
;clear P/M memory
lda #0
tax
@ sta PMmemory,x
sta PMmemory+$100,x
sta PMmemory+$200,x
sta PMmemory+$300,x
inx
bne @-
mva #>PMmemory PMBASE
jsr HidePM
mva #%00100100 GPRIOR
mva #0 RMT_blocked
lda #$ff
sta sfx_effect
JSR AudioInit
jsr LevelReset
jsr InitBranches
jsr draw_branches
mva #24 PowerValue ; half power
mva #1 PowerTimer ; reset timer ( 1, not 0! )
jsr draw_PowerBar
mva #1 LumberjackDir ; right side
/* ;RMT INIT
ldx #<MODUL ;low byte of RMT module to X reg
ldy #>MODUL ;hi byte of RMT module to Y reg
lda #0 ;starting song line 0-255 to A reg
jsr RASTERMUSICTRACKER ;Init
*/
jsr PrepareLevelPM
jsr PrepareBirdsPM
jsr PrepareCloudsPM
jsr SetPMr1
mwa #gamescreen_r_ph1p1 animation_addr
lda #@dmactl(narrow|dma|missiles|players|lineX2) ; narrow screen width, DL on, P/M on (2lines)
sta dmactls
mva #%00000011 GRACTL
mwa #dl_level dlptrs
vdli IngameDLI1
;VBI
vmain vint,7
rts
.endp
;--------------------------------------------------
.proc HidePM
; hide P/M on right side of screen
;--------------------------------------------------
lda #$e0
ldx #$07 ; 8 registers. from HPOSP0_d to HPOSM3_d
@ sta HPOSP0_d,x
;sta HPOSP0_u,x
sta HPOSP0,x
dex
;sta birdsHpos
bpl @-
rts
.endp
;--------------------------------------------------
.proc PrepareLevelPM
;--------------------------------------------------
; Lumberjack shirt
ldx #datalinesP2-1
@ lda P2_data,x
sta PMmemory+$300+HoffsetP2,x
lda P3_data,x
sta PMmemory+$380+HoffsetP2,x
lda M23_data,x
sta PMmemory+$180+HoffsetP2,x
dex
bpl @-
mva #1 SIZEP2_d
sta SIZEP3_d
lda #%01011111
sta SIZEM_d
mva #$22 COLPM2_d
mva #$24 COLPM3_d
; Lumberjack hand
ldx #datalinesP0-1
@ lda P0_data,x
sta PMmemory+$200+HoffsetP0,x
dex
bpl @-
mva #0 SIZEP0_d
mva #$2a COLPM0_d
; Lumberjack face
ldx #datalinesM0-1
@ lda PMmemory+$180+HoffsetM0,x
ora M0_data,x
sta PMmemory+$180+HoffsetM0,x
dex
bpl @-
; Lumberjack second hand
ldx #datalinesM1-1
@ lda PMmemory+$180+HoffsetM1,x
ora M1_data,x
sta PMmemory+$180+HoffsetM1,x
dex
bpl @-
mva #$2a COLPM1_d
; Lumberjack both hands
ldx #datalinesP1-1
@ lda P1_data,x
sta PMmemory+$280+HoffsetP1,x
dex
bpl @-
mva #1 SIZEP1_d
rts
; Lumberjack shirt data
P2_data
.by $55,$55,$aa,$aa,$55,$55,$aa,$aa,$55,$55,$aa,$aa,$55,$55,$ff,$ff
P3_data
.by $ff,$ff,$55,$55,$ff,$ff,$55,$55,$ff,$ff,$55,$55,$ff,$ff,$00,$00
M23_data
.by $80,$80,$20,$20,$80,$80,$20,$20,$80,$80,$20,$20,$80,$80,$20,$20
HoffsetP2=98
datalinesP2=16
; Lumberjack hand data
P0_data
.by %11111000
.by %11111000
.by %11111000
.by %11111000
.by %11111000
HoffsetP0=95
datalinesP0=5
; Lumberjack face data
M0_data
.by %00000011
.by %00000011
.by %00000011
.by %00000011
.by %00000011
.by %00000011
.by %00000011
.by %00000011
.by %00000011
HoffsetM0=94
datalinesM0=9
; Lumberjack second hand data
M1_data
.by %00001100
.by %00001100
.by %00001100
.by %00001100
.by %00001100
HoffsetM1=103
datalinesM1=5
; Lumberjack both hands data
P1_data
.by %11101110
.by %11101110
.by %11101110
.by %11101110
.by %11101110
HoffsetP1=103
datalinesP1=5
.endp
;--------------------------------------------------
.proc PrepareBirdsPM
;--------------------------------------------------
; bird 2, 1 and 3
jsr bird_a
mva #0 SIZEP0_u
sta SIZEP1_u
mva #$04 PCOLR0
sta PCOLR1
lda #0
sta birdsHpos
sta HPOSP0_u
sta HPOSP1_u
rts
bird_a
ldx #datalines_bird-1
@ lda bird_data_a,x
sta PMmemory+$200+Hoffset_bird2,x
sta PMmemory+$280+Hoffset_bird1,x
sta PMmemory+$280+Hoffset_bird3,x
dex
bpl @-
rts
bird_b
ldx #datalines_bird-1
@ lda bird_data_b,x
sta PMmemory+$200+Hoffset_bird2,x
sta PMmemory+$280+Hoffset_bird1,x
sta PMmemory+$280+Hoffset_bird3,x
dex
bpl @-
rts
; bird data
bird_data_a
dta $00, $00, $00, $3f, $7c, $18, $18, $08
bird_data_b
dta $00, $30, $18, $18, $3f, $7c, $00, $00
Hoffset_bird1=25
Hoffset_bird2=35
Hoffset_bird3=45
datalines_bird=8
.endp
;--------------------------------------------------
.proc PrepareCloudsPM
;--------------------------------------------------
; 3 clouds
; 1 - vertical offset in PM from 5 (first byte) to 28 (last byte)
; 2 - vertical offset in PM from 29 (first byte) to 52 (last byte)
; 3 - vertical offset in PM from 53 (first byte) to 84 (last byte)
; cloud
jsr make_cloud1
jsr make_cloud2
jsr make_cloud3
mva #0 SIZEP2_u
sta SIZEP3_u
lda #%01010101
sta SIZEM_u
mva #$0c PCOLR2
sta PCOLR3
lda #36
sta clouds1Hpos
clc
sta HPOSM2_u
adc #4
sta HPOSP2_u
adc #8
sta HPOSP3_u
adc #8
sta HPOSM3_u
rts
make_cloud1
ldx #datalines_clouds-1
@ lda cloud2_P2,x
sta PMmemory+$300+Hoffset_cloud1,x
lda cloud2_P3,x
sta PMmemory+$380+Hoffset_cloud1,x
lda cloud2_M,x
sta PMmemory+$180+Hoffset_cloud1,x
dex
bpl @-
make_cloud2
ldx #datalines_clouds-1
@ lda cloud3_P2,x
sta PMmemory+$300+Hoffset_cloud2,x
lda cloud3_P3,x
sta PMmemory+$380+Hoffset_cloud2,x
lda cloud3_M,x
sta PMmemory+$180+Hoffset_cloud2,x
dex
bpl @-
make_cloud3
ldx #datalines_clouds-1
@ lda cloud4_P2,x
sta PMmemory+$300+Hoffset_cloud3,x
lda cloud4_P3,x
sta PMmemory+$380+Hoffset_cloud3,x
lda cloud4_M,x
sta PMmemory+$180+Hoffset_cloud3,x
dex
bpl @-
rts
; clouds data
; shape 1
cloud1_P2
.by $00,$00,$00,$00,$00,$00,$00,$00,$08,$1D,$3F,$3F
cloud1_P3
.by $00,$00,$00,$00,$00,$00,$00,$00,$00,$80,$E0,$F8
cloud1_M
.by $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
; shape2
cloud2_P2
.by $00,$00,$00,$00,$00,$00,$00,$00,$07,$1F,$3F,$FF
cloud2_P3
.by $00,$00,$00,$00,$00,$00,$00,$00,$80,$DC,$FE,$FF
cloud2_M
.by $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
; shape 3
cloud3_P2
.by $00,$00,$00,$00,$00,$00,$00,$38,$7D,$FF,$FF,$FF
cloud3_P3
.by $00,$00,$00,$00,$00,$00,$00,$C0,$F0,$FC,$FE,$FF
cloud3_M
.by $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$10,$30
; shape 4
cloud4_P2
.by $00,$00,$00,$00,$00,$00,$0E,$1F,$1F,$7F,$FF,$FF
cloud4_P3
.by $00,$00,$00,$00,$00,$00,$30,$78,$78,$FB,$FF,$FF
cloud4_M
.by $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$90
datalines_clouds=12
Hoffset_cloud1=8
Hoffset_cloud2=30
Hoffset_cloud3=54
.endp
;--------------------------------------------------
.proc SetPMl1
;--------------------------------------------------
mva #$4f HPOSP2_d
sta HPOSP3_d
mva #$5f HPOSM2_d
sta HPOSM3_d
mva #$4c HPOSP0_d
mva #$54 HPOSM0_d
mva #$4c HPOSM1_d
mva #$e0 HPOSP1_d ; hide
rts
.endp
;--------------------------------------------------
.proc SetPMr1
;--------------------------------------------------
mva #$9f HPOSP2_d
sta HPOSP3_d
mva #$af HPOSM2_d
sta HPOSM3_d
mva #$af HPOSP0_d
mva #$a4 HPOSM0_d
mva #$ac HPOSM1_d
mva #$e0 HPOSP1_d ; hide
rts
.endp
;--------------------------------------------------
.proc SetPMl2
;--------------------------------------------------
mva #$4f HPOSP2_d
sta HPOSP3_d
mva #$5f HPOSM2_d
sta HPOSM3_d
mva #$e0 HPOSP0_d ; hide
mva #$55 HPOSM0_d
mva #$e0 HPOSM1_d ; hide
mva #$50 HPOSP1_d
rts
.endp
;--------------------------------------------------
.proc SetPMr2
;--------------------------------------------------
mva #$9f HPOSP2_d
sta HPOSP3_d
mva #$af HPOSM2_d
sta HPOSM3_d
mva #$e0 HPOSP0_d ; hide
mva #$a3 HPOSM0_d
mva #$e0 HPOSM1_d ; hide
mva #$a2 HPOSP1_d
rts
.endp
;--------------------------------------------------
.proc SetPMl3
;--------------------------------------------------
mva #$4f HPOSP2_d
sta HPOSP3_d
mva #$5f HPOSM2_d
sta HPOSM3_d
mva #$e0 HPOSP0_d ; hide
mva #$54 HPOSM0_d
mva #$56 HPOSM1_d
mva #$5b HPOSP1_d
rts
.endp
;--------------------------------------------------
.proc SetPMr3
;--------------------------------------------------
mva #$9f HPOSP2_d
sta HPOSP3_d
mva #$af HPOSM2_d
sta HPOSM3_d
mva #$e0 HPOSP0_d ; hide
mva #$a4 HPOSM0_d
mva #$a4 HPOSM1_d
mva #$97 HPOSP1_d
rts
.endp
;--------------------------------------------------
.proc RmtSongSelect
; starting song line 0-255 to A reg
;--------------------------------------------------
/*
cmp #song_main_menu
beq noingame ; noMusic blocks only ingame songs
bit noMusic
spl:lda #song_silencio
noingame
*/
/* mvx #$ff RMT_blocked
ldx #<MODUL ; low byte of RMT module to X reg
ldy #>MODUL ; hi byte of RMT module to Y reg
jsr RASTERMUSICTRACKER ; Init
mva #0 RMT_blocked
*/ rts
.endp
;--------------------------------
; non ZP variables
;--------------------------------
branches_list
.by 1,0,2,0,1,0 ;
branches_anim_phase ; from 0 to 4
.by 1
score
dta d"0000"
level
dta $1a, $1b, $1c, $1b, $1a, $A4
dta d"1"
;--------------------------------------------------
.proc ScoreUp
;--------------------------------------------------
inc score+3
lda score+3
cmp #"9"+1 ; 9+1 character code
bne ScoreReady
lda #"0" ; 0 character code
sta score+3
inc score+2
lda score+2
cmp #"5"
bne no_speed_power
jsr PowerSpeedUP ; every 50pts.
no_speed_power
cmp #"9"+1 ; 9+1 character code
bne ScoreReady
lda #"0" ; 0 character code
sta score+2
jsr PowerSpeedUP ; every 50pts.
jsr LevelUp ; every 100pts.
inc score+1
lda score+1
cmp #"9"+1 ; 9+1 character code
bne ScoreReady
lda #"0" ; 0 character code
sta score+1
inc score
ScoreReady
rts
.endp
;--------------------------------------------------
.proc ScoreClear
;--------------------------------------------------
lda #"0"
ldx #3
@ sta score,x
dex
bpl @-
rts
.endp
;--------------------------------------------------
.proc ScoreToScreen
;--------------------------------------------------
ldx #3
@ lda score,x
sta screen_score,x
dex
bpl @-
rts
.endp
;--------------------------------------------------
.proc LevelToScreen
;--------------------------------------------------
lda LevelValue
clc
adc #"0"
sta screen_level+6
ldx #5
@ lda level,x
sta screen_level,x
dex
bpl @-
rts
.endp
;--------------------------------------------------
.proc LevelReset
;--------------------------------------------------
; set level to 1 and PowerDownSpeed to ??
mvx #1 LevelValue
dex
stx PowerSpeedIndex
lda PowerSpeedTable,x
sta PowerDownSpeed
jsr LevelToScreen
rts
.endp
;--------------------------------------------------
.proc LevelUp
;--------------------------------------------------
inc LevelValue
lda LevelValue
cmp #10
bne not_max_lev
mva #9 LevelValue
not_max_lev
jsr LevelToScreen
rts
.endp
;--------------------------------------------------
.proc PowerSpeedUP
;--------------------------------------------------
inc PowerSpeedIndex
ldx PowerSpeedIndex
lda PowerSpeedTable,x
sta PowerDownSpeed
rts
.endp
;--------------------------------------------------
.proc PowerUp
;--------------------------------------------------
mva #$3F COLOR2 ; red
inc PowerValue
lda PowerValue
cmp #49
bne not_max_pwr
mva #48 PowerValue
not_max_pwr
jsr draw_PowerBar
rts
.endp
;--------------------------------------------------
.proc PowerDown
;--------------------------------------------------
dec PowerValue
bpl not_min_pwr
mva #0 PowerValue
not_min_pwr
jsr draw_PowerBar
rts
.endp
;--------------------------------------------------
.proc draw_PowerBar
;--------------------------------------------------
lda PowerValue
cmp #48
bcc not_to_high
mva #48 PowerValue
not_to_high
tay
and #%00000011
clc
adc #PowerChar0
tax ; code of last char in bar
tya
:2 lsr ; value/4 - number of full char in bar
sta tempbyte
ldy #0
lda #PowerCharFull
draw_bar_loop
cpy tempbyte
bne not_last_bar_char
; last char in bar
txa
sta Power,y
lda #PowerCharEmpty ; because next in bar chars are empty
bne next_char
not_last_bar_char
sta Power,y
next_char
iny
cpy #12
bne draw_bar_loop
rts
.endp
;--------------------------------------------------
.proc draw_branches
;--------------------------------------------------
; branch 0 (off-screen if phase 0)
draw_branch0
lda branches_anim_phase
beq draw_branch1
tax
; this is partialy off-screen branch
; we must draw only visible lines
; now calculate start screen address
lda #5
sec
sbc branches_anim_phase
:5 asl ; skippedlines*32
tay ; to skip lines
txa
; now calculate start screen address
:5 asl ; phase*32
;clc
adc #<(gamescreen_middle-5*32)
sta temp
lda #>(gamescreen_middle-5*32)
adc #0
sta temp+1
ldx branches_list ; branch0
lda branch_addr_tableL,x
sta temp2
lda branch_addr_tableH,x
sta temp2+1
; skiping off-screen lines
; ldy #$00 ; we have value in Y
@ lda (temp2),y
sta (temp),y
iny
cpy #(5*32) ;5 lines - skipped lines
bne @-
draw_branch1
lda branches_anim_phase
; now calculate start screen address
:5 asl ; phase*32
;clc
adc #<gamescreen_middle
sta temp
lda #>gamescreen_middle
adc #0
sta temp+1
ldy branches_list+1 ; branch1
lda branch_addr_tableL,y
sta temp2
lda branch_addr_tableH,y
sta temp2+1
ldy #$00
@ lda (temp2),y
sta (temp),y
iny
cpy #(5*32) ;5 lines
bne @-
draw_branch2
lda branches_anim_phase
; now calculate start screen address
:5 asl ; phase*32
;clc
adc #<(gamescreen_middle+5*32)
sta temp
lda #>(gamescreen_middle+5*32)
adc #0
sta temp+1
ldy branches_list+2 ; branch2
lda branch_addr_tableL,y
sta temp2
lda branch_addr_tableH,y
sta temp2+1
ldy #$00
@ lda (temp2),y
sta (temp),y
iny
cpy #(5*32) ;5 lines
bne @-
jsr ScoreToScreen
jsr LevelToScreen
draw_branch3
lda branches_anim_phase
ldx #(5*32) ; how many lines draw
cmp #4
bne not_phase4
ldx #(4*32) ; how many lines draw
not_phase4
stx tempbyte
; now calculate start screen address
:5 asl ; phase*32
;clc
adc #<(gamescreen_middle+10*32)
sta temp
lda #>(gamescreen_middle+10*32)
adc #0
sta temp+1
ldy branches_list+3 ; branch3
lda branch_addr_tableL,y
sta temp2
lda branch_addr_tableH,y
sta temp2+1
ldy #$00
@ lda (temp2),y
sta (temp),y
iny
cpy tempbyte ;? lines
bne @-
draw_branch4
lda branches_anim_phase
; draw only if phase 0 or 1 or 2
cmp #3
bcs all_drawed
ldx #(3*32) ; how many lines draw
cmp #1
bne not_phase1
ldx #(2*32) ; how many lines draw
not_phase1
cmp #2
bne not_phase2
ldx #(1*32) ; how many lines draw
not_phase2
stx tempbyte
; now calculate start screen address
:5 asl ; phase*32
;clc
adc #<(gamescreen_middle+15*32)
sta temp
lda #>(gamescreen_middle+15*32)
adc #0
sta temp+1
ldy branches_list+4 ; branch3
lda branch_addr_tableL,y
sta temp2
lda branch_addr_tableH,y
sta temp2+1
ldy #$00
@ lda (temp2),y
sta (temp),y
iny
cpy tempbyte ;? lines
bne @-
all_drawed
rts
.endp
;--------------------------------------------------
.proc branches_go_down
;--------------------------------------------------
inc branches_anim_phase
lda branches_anim_phase
cmp #5
bne next_phase_only
jsr new_branch
next_phase_only
jsr draw_branches
rts
.endp
;--------------------------------------------------
.proc new_branch
;--------------------------------------------------
mva #0 branches_anim_phase
mva branches_list+4 branches_list+5
mva branches_list+3 branches_list+4
mva branches_list+2 branches_list+3
mva branches_list+1 branches_list+2
mva branches_list+0 branches_list+1
; ----- less branches -----
beq make_random_branch
lda #0
beq branch_ready
; -----
make_random_branch
lda RANDOM ; branch or not (50%)
and #%00000001
beq branch_ready ; no branches
lda RANDOM ; left or right (50%)
and #%00000001
tax
inx
txa
branch_ready
sta branches_list+0
rts
.endp
;--------------------------------------------------
.proc GetKey
; waits for pressing a key and returns pressed value in A
; result: A=keycode
;--------------------------------------------------
jsr WaitForKeyRelease
getKeyAfterWait
jsr GetKeyFast
cmp #@kbcode._none
beq getKeyAfterWait
ldy #0
sty ATRACT ; reset atract mode
rts
.endp
;--------------------------------------------------
.proc GetKeyFast
; returns pressed value in A - no waits for press
; result: A=keycode ($ff - no key pressed)
;--------------------------------------------------
.IF TARGET = 800
lda SKSTAT
and #%00000100 ; any key
bne checkJoyGetKey ; key not pressed, check Joy
.ELIF TARGET = 5200
lda SkStatSimulator
and #%11111110
bne checkJoyGetKey ; key not pressed, check Joy
.ENDIF
lda kbcode
cmp #@kbcode._none
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 elimination
rts
.endp
;--------------------------------------------------
.proc WaitForKeyRelease
;--------------------------------------------------
StillWait
lda STICK0
and #$0f
cmp #$0f
bne StillWait
lda STRIG0
beq StillWait
.IF TARGET = 800
lda SKSTAT
and #%00000100 ; any key
beq StillWait
lda CONSOL
and #%00000110 ; Select and Option only
cmp #%00000110
bne StillWait
.ELIF TARGET = 5200
lda SkStatSimulator
and #%11111110
beq StillWait
.ENDIF
KeyReleased
rts
.endp
;--------------------------------------------------
.proc CheckStartKey
;--------------------------------------------------
lda CONSOL ; turbo mode
and #%00000001 ; START KEY
rts
.endp
;--------------------------------------------------
.proc InitBranches
;--------------------------------------------------
ldy #5
@ lda initial_branches_list,y
sta branches_list,y
dey
bpl @-
rts
.endp
;--------------------------------------------------
.proc WaitForSync
;--------------------------------------------------
lda SyncByte
@ cmp SyncByte
beq @-
rts
.endp
;--------------------------------------------------
initial_branches_list
.by 1,0,2,0,1,0 ;
branch_addr_tableL
.by <branch0
.by <branch1
.by <branch2
branch_addr_tableH
.by >branch0
.by >branch1
.by >branch2
; power speed table - every 50pts.
PowerSpeedTable
; in original game double speed after 400pts.
; 000,050,100,150,200,250,300,350,400,450,500,550,600,650,700,750,800,850,900,950
.by 011,010,010,009,008,007,007,006,005,005,004,004,004,003,003,003,002,002,001,001
; level for old men
.by 022,020,018,017,015,013,012,011,010,010,009,009,008,007,006,005,004,003,002,001,001,001,001
;--------------------------------
PowerChar0 = $07 ; power bar first (0) character
PowerCharFull = $0b
PowerCharEmpty = PowerChar0
;--------------------------------
joyToKeyTable
.by $ff ;00
.by $ff ;01
.by $ff ;02
.by $ff ;03
.by $ff ;04
.by $ff ;05
.by $ff ;06
.by @kbcode._right ;07
.by $ff ;08
.by $ff ;09
.by $ff ;0a
.by @kbcode._left ;0b
.by $ff ;0c
.by @kbcode._down ;0d
.by @kbcode._up ;0e
.by $ff ;0f
;-----------------------------------
; names of RMT instruments (sfx)
;--------------------------------
sfx_ping = $07
sfx_pong = $08
;--------------------------------
; RMT songs (lines)
;--------------------------------
song_main_menu = $00
song_ingame = $07
song_game_over = $12
RUN main