//------------------------------- // Snakes of Atari Island // // Author: Jakub "JKR" Krzak // Katowice, April 2012 //------------------------------- OPT L+ OPT R+ ICL 'Macros.asm' ICL 'Consts.asm' ;-------------------------------------------------------- ; Zero page variables ORG $80 _arr .ds 2 ;used for accessing arrays SnW_Hx .ds 1 SnW_Hy .ds 1 SnW_Tx .ds 1 SnW_Ty .ds 1 SnW_Dir .ds 1 SnW_tmpDir .ds 1 SnW_State .ds 1 SnW_Score .ds 2 SnB_Hx .ds 1 SnB_Hy .ds 1 SnB_Tx .ds 1 SnB_Ty .ds 1 SnB_Dir .ds 1 SnB_tmpDir .ds 1 SnB_State .ds 1 SnB_Score .ds 2 cSSt_Grow equ 1 cSSt_Dead equ 2 cSSt_Fast equ 4 GameCntrFast .ds 1 GameCntr .ds 1 _selectedMode .ds 1 _selectedArea .ds 1 Level .ds 1 LevDelay .ds 1 LevelTmp .ds 1 HiScore .ds 2 fruitExtraCntr .ds 1 fruitExtra_X .ds 1 fruitExtra_Y .ds 1 fruit_Y .ds 1 _mute .ds 1 _bgrndColorPtr .ds 1 _bgrndClr .ds 1 ; multi purpose variables __x .ds 1 __y .ds 1 __z .ds 1 __a .ds 1 __b .ds 1 __c .ds 1 _tmpState .ds 1 tmrBase .ds 1 clckSeconds .ds 1 clckMinutes .ds 1 _msgNum .ds 1 _msgNum2 .ds 1 tmrDisplMsgs .ds 2 _msgFlags .ds 1 cMsgUp_Change equ 1 cMsgDown_Change equ 2 cMsgUp_Blink equ 4 cMsgDown_Blink equ 8 cMsgUp_SH equ 16 cMsgDown_SH equ 32 _msgBrLower .ds 1 _msgBrUpper .ds 1 _tmrMsg .ds 1 vcnt .ds 1 _sfx_ptr .ds 1 _sfx_tmr .ds 1 ; Splash screen ICL 'Splash.asm' ICL 'CMC.asm' INI Splash ORG $2e0 dta a(Main) ORG $2000 ICL 'Screen.asm' ICL 'Misc.asm' ICL 'include\STDLib.asm' ICL 'VBI.asm' Main mva #0 _scrL25 mva #0 _selectedMode mwa #$FFFF HiScore mvza fruitExtraCntr mvza fruitExtra_X mvza fruitExtra_Y mvza fruit_Y mvza _mute mvza _bgrndColorPtr getColor #0 _bgrndColorPtr sta _bgrndClr mvza _selectedArea mvza tmrBase mwa #0 tmrDisplMsgs mvza _msgNum mvza _msgNum2 mvza _msgFlags mva #cMaxMsgBrtnss _msgBrLower mva #cMaxMsgBrtnss _msgBrUpper mvza _tmrMsg mvza vcnt mvza _sfx_ptr mvza _sfx_tmr mwa #DList SDLSTL ; set DL mvza COLOR0+2 mvza COLOR0+5 mva #$F0 COL_BK_S mva #$F0 COL_PF2_S mva #14 HSCROL ; select characters set lda #>fontFile sta CHBAS ; set VBI vector mva #0 NMIEN mwa #VBI_Proc VVBLKD mva #64 NMIEN jsr CMC_Init loopMain: #if .byte _mute = #0 ldx #0 jsr CMC_PlaySong #end loopTP: jsr TitlePage jsr SelectionPage jcc loopTP jsr CMC_Stop jsr GameProcedure jmp loopMain .align 1024 fontFile: ins 'include\snake.fnt' .array arrPosHLL .byte 54 90 130 166 .enda .array arrPosHLR .byte 58 98 134 170 .enda ICL 'fields' arrSnakeFldW .ds 40*24 arrSnakeFldW_End arrSnakeFldB .ds 40*24 arrSnakeFldB_End _msg .ds 41 _msg2 .ds 40 _scr_lo: :25 dta l(_scr + #*40) _scr_hi: :25 dta h(_scr + #*40) ColorSchemes_lo: :6 dta l(ColorSchemes + #*4) ColorSchemes_hi: :6 dta h(ColorSchemes + #*4) arrFields_lo: :7 dta l(arrFields + #*36) arrFields_hi: :7 dta h(arrFields + #*36) arrSnakeFldW_lo: :24 dta l(arrSnakeFldW + #*40) arrSnakeFldW_hi: :24 dta h(arrSnakeFldW + #*40) arrSnakeFldB_lo: :24 dta l(arrSnakeFldB + #*40) arrSnakeFldB_hi: :24 dta h(arrSnakeFldB + #*40) drawSnakeBeginW .proc ; __x, __y - head location ; __a - snake's length ldx __x ldy __y stx SnW_Hx sty SnW_Hy sty SnW_Ty dec __a #if .byte SnW_Dir = #cRight txa sec sbc __a sta SnW_Tx sta __a inc __a #while .byte __a < SnW_Hx setScrAt __a SnW_Hy #chrBody_H setFldW __a SnW_Hy #chrBody_H inc __a #end setScrAt SnW_Hx SnW_Hy #chrHead_R setFldW SnW_Hx SnW_Hy #chrHead_R setScrAt SnW_Tx SnW_Ty #chrTail_R setFldW SnW_Tx SnW_Ty #chrTail_R #else txa clc adc __a sta SnW_Tx sta __a dec __a #while .byte __a > SnW_Hx setScrAt __a SnW_Hy #chrBody_H setFldW __a SnW_Hy #chrBody_H dec __a #end setScrAt SnW_Hx SnW_Hy #chrHead_L setFldW SnW_Hx SnW_Hy #chrHead_L setScrAt SnW_Tx SnW_Ty #chrTail_L setFldW SnW_Tx SnW_Ty #chrTail_L #end rts .endp drawSnakeBeginB .proc ; __x, __y - head location ; __a - snake's length ldx __x ldy __y stx SnB_Hx sty SnB_Hy sty SnB_Ty dec __a #if .byte SnB_Dir = #cRight txa sec sbc __a sta SnB_Tx sta __a inc __a #while .byte __a < SnB_Hx setScrAt __a SnB_Hy #chrBodyB_H setFldB __a SnB_Hy #chrBodyB_H inc __a #end setScrAt SnB_Hx SnB_Hy #chrHeadB_R setFldB SnB_Hx SnB_Hy #chrHeadB_R setScrAt SnB_Tx SnB_Ty #chrTailB_R setFldB SnB_Tx SnB_Ty #chrTailB_R #else txa clc adc __a sta SnB_Tx sta __a dec __a #while .byte __a > SnB_Hx setScrAt __a SnB_Hy #chrBodyB_H setFldB __a SnB_Hy #chrBodyB_H dec __a #end setScrAt SnB_Hx SnB_Hy #chrHeadB_L setFldB SnB_Hx SnB_Hy #chrHeadB_L setScrAt SnB_Tx SnB_Ty #chrTailB_L setFldB SnB_Tx SnB_Ty #chrTailB_L #end rts .endp calculateNextHeadCoordW .proc mva SnW_Hx __x mva SnW_Hy __y // TODO: check teleport #if .byte SnW_Dir = #cRight #if .byte SnW_Hx = #39 ; Max. x on screen mva #0 __x ; Min. x on screen #else mva SnW_Hx __x inc __x #end rts #end #if .byte SnW_Dir = #cUp #if .byte SnW_Hy = #1 ; Min. y on screen mva #23 __y ; Max. y on screen #else mva SnW_Hy __y dec __y #end rts #end #if .byte SnW_Dir = #cLeft #if .byte SnW_Hx = #0 ; Min. x on screen mva #39 __x ; Max. x on screen #else mva SnW_Hx __x dec __x #end rts #end #if .byte SnW_Dir = #cDown #if .byte SnW_Hy = #23 ; Max. y on screen mva #1 __y ; Min. y on screen #else mva SnW_Hy __y inc __y #end rts #end .endp calculateNextHeadCoordB .proc mva SnB_Hx __x mva SnB_Hy __y // TODO: check teleport #if .byte SnB_Dir = #cRight #if .byte SnB_Hx = #39 ; Max. x on screen mva #0 __x ; Min. x on screen #else mva SnB_Hx __x inc __x #end rts #end #if .byte SnB_Dir = #cUp #if .byte SnB_Hy = #1 ; Min. y on screen mva #23 __y ; Max. y on screen #else mva SnB_Hy __y dec __y #end rts #end #if .byte SnB_Dir = #cLeft #if .byte SnB_Hx = #0 ; Min. x on screen mva #39 __x ; Max. x on screen #else mva SnB_Hx __x dec __x #end rts #end #if .byte SnB_Dir = #cDown #if .byte SnB_Hy = #23 ; Max. y on screen mva #1 __y ; Min. y on screen #else mva SnB_Hy __y inc __y #end rts #end .endp calculateNextTailCoordW .proc #if .byte __a = #chrTail_R ldx SnW_Tx cpx #39 sne ldx #-1 inx stx __x mva SnW_Ty __y #else #if .byte __a = #chrTail_U ldx SnW_Ty cpx #1 sne ldx #24 dex stx __y mva SnW_Tx __x #else #if .byte __a = #chrTail_L ldx SnW_Tx cpx #0 sne ldx #40 dex stx __x mva SnW_Ty __y #else #if .byte __a = #chrTail_D ldx SnW_Ty cpx #23 sne ldx #0 inx stx __y mva SnW_Tx __x #end #end #end #end rts .endp calculateNextTailCoordB .proc #if .byte __a = #chrTailB_R ldx SnB_Tx cpx #39 sne ldx #-1 inx stx __x mva SnB_Ty __y #else #if .byte __a = #chrTailB_U ldx SnB_Ty cpx #1 sne ldx #24 dex stx __y mva SnB_Tx __x #else #if .byte __a = #chrTailB_L ldx SnB_Tx cpx #0 sne ldx #40 dex stx __x mva SnB_Ty __y #else #if .byte __a = #chrTailB_D ldx SnB_Ty cpx #23 sne ldx #0 inx stx __y mva SnB_Tx __x #end #end #end #end rts .endp moveTailW .proc getFldW SnW_Tx SnW_Ty sta __a ; current __tail__ character jsr calculateNextTailCoordW getFldW __x __y sta __b ; snake's character next to the 'tail' ; erase the tail setFldW SnW_Tx SnW_Ty #0 getScrAt SnW_Tx SnW_Ty cmp __a jne l1 getFldB SnW_Tx SnW_Ty sta __c setScrAt SnW_Tx SnW_Ty __c l1 #if .byte __b = #chrBody_UL #if .byte __a = #chrTail_R mva #chrTail_U __c #else mva #chrTail_L __c #end #else #if .byte __b = #chrBody_DL #if .byte __a = #chrTail_R mva #chrTail_D __c #else mva #chrTail_L __c #end #else #if .byte __b = #chrBody_DR #if .byte __a = #chrTail_U mva #chrTail_R __c #else mva #chrTail_D __c #end #else #if .byte __b = #chrBody_UR #if .byte __a = #chrTail_L mva #chrTail_U __c #else mva #chrTail_R __c #end #else mva __a __c #end #end #end #end ; put the tail setFldW __x __y __c getScrAt __x __y cmp __b jne l2 setScrAt __x __y __c l2 mva __x SnW_Tx mva __y SnW_Ty rts .endp moveTailB .proc getFldB SnB_Tx SnB_Ty sta __a ; current __tail__ character jsr calculateNextTailCoordB getFldB __x __y sta __b ; snake's character next to the 'tail' ; erase the tail setFldB SnB_Tx SnB_Ty #0 getScrAt SnB_Tx SnB_Ty cmp __a jne l1 getFldW SnB_Tx SnB_Ty sta __c setScrAt SnB_Tx SnB_Ty __c l1 #if .byte __b = #chrBodyB_UL #if .byte __a = #chrTailB_R mva #chrTailB_U __c #else mva #chrTailB_L __c #end #else #if .byte __b = #chrBodyB_DL #if .byte __a = #chrTailB_R mva #chrTailB_D __c #else mva #chrTailB_L __c #end #else #if .byte __b = #chrBodyB_DR #if .byte __a = #chrTailB_U mva #chrTailB_R __c #else mva #chrTailB_D __c #end #else #if .byte __b = #chrBodyB_UR #if .byte __a = #chrTailB_L mva #chrTailB_U __c #else mva #chrTailB_R __c #end #else mva __a __c #end #end #end #end ; put the tail setFldB __x __y __c getScrAt __x __y cmp __b jne l2 setScrAt __x __y __c l2 mva __x SnB_Tx mva __y SnB_Ty rts .endp ;------------------------------------------------------------------------- .array snakeCharsW .byte chrHead_R chrHead_U chrHead_D chrHead_L chrBody_UL chrBody_UR chrBody_DL chrBody_DR chrBody_V chrBody_H chrTail_U chrTail_L chrTail_D chrTail_R 10 61 62 .enda .array snakeCharsB .byte chrHeadB_R chrHeadB_U chrHeadB_D chrHeadB_L chrBodyB_UL chrBodyB_UR chrBodyB_DL chrBodyB_DR chrBodyB_V chrBodyB_H chrTailB_U chrTailB_L chrTailB_D chrTailB_R 10 61 62 .enda checkIfSnakeCharW .proc ldx #.len(snakeCharsW) l1: dex bmi l2 cmp snakeCharsW,X bne l1 sec rts l2: clc rts .endp checkIfSnakeCharB .proc ldx #.len(snakeCharsB) l1: dex bmi l2 cmp snakeCharsB,X bne l1 sec rts l2: clc rts .endp changeSnakeChars .proc ldx #.len(snakeChars1) l1: dex bmi l2 cmp snakeChars1,X bne l1 lda snakeChars2,X sec rts l2: clc rts .endp .array snakeChars1 .byte chrHead_R chrHead_U chrHead_D chrHead_L chrBody_UL chrBody_UR chrBody_DL chrBody_DR chrBody_V chrBody_H chrTail_U chrTail_L chrTail_D chrTail_R chrHeadB_R chrHeadB_U chrHeadB_D chrHeadB_L chrBodyB_UL chrBodyB_UR chrBodyB_DL chrBodyB_DR chrBodyB_V chrBodyB_H chrTailB_U chrTailB_L chrTailB_D chrTailB_R 0 .enda .array snakeChars2 .byte chrHeadB_R chrHeadB_U chrHeadB_D chrHeadB_L chrBodyB_UL chrBodyB_UR chrBodyB_DL chrBodyB_DR chrBodyB_V chrBodyB_H chrTailB_U chrTailB_L chrTailB_D chrTailB_R chrHead_R chrHead_U chrHead_D chrHead_L chrBody_UL chrBody_UR chrBody_DL chrBody_DR chrBody_V chrBody_H chrTail_U chrTail_L chrTail_D chrTail_R 0 .enda clearSnakeBlack .proc cmp #chrHeadB_R jeq l1 cmp #chrHeadB_U jeq l1 cmp #chrHeadB_D jeq l1 cmp #chrHeadB_L jeq l1 cmp #62 jeq l1 clc rts l1 lda #0 sec rts .endp clearSnakeWhite .proc cmp #chrHead_R jeq l1 cmp #chrHead_U jeq l1 cmp #chrHead_D jeq l1 cmp #chrHead_L jeq l1 cmp #62 jeq l1 clc rts l1 lda #0 sec rts .endp showSnakeBlackDead .proc ldx #.len(snakeChars3) l1: dex bmi l2 cmp snakeChars3,X bne l1 lda #62 sec rts l2: clc rts .endp showSnakeWhiteDead .proc ldx #.len(snakeChars4) l1: dex bmi l2 cmp snakeChars4,X bne l1 lda #62 sec rts l2: clc rts .endp .array snakeChars3 .byte chrBodyB_UL chrBodyB_UR chrBodyB_DL chrBodyB_DR chrBodyB_V chrBodyB_H chrTailB_U chrTailB_L chrTailB_D chrTailB_R .enda .array snakeChars4 .byte chrBody_UL chrBody_UR chrBody_DL chrBody_DR chrBody_V chrBody_H chrTail_U chrTail_L chrTail_D chrTail_R .enda ;------------------------------------------------------------------------- MoveHeadW .proc mvza __z getFldW SnW_Hx SnW_Hy ; current 'head' character sta __a jsr calculateNextHeadCoordW getScrAt __x __y sta __b ; character in front of the 'head' #if .byte SnW_Dir = #cRight ldx #chrHead_R #else #if .byte SnW_Dir = #cUp ldx #chrHead_U #else #if .byte SnW_Dir = #cLeft ldx #chrHead_L #else #if .byte SnW_Dir = #cDown ldx #chrHead_D #end #end #end #end stx __c setFldW SnW_Hx SnW_Hy __c ; turn the head (no move yet) getScrAt SnW_Hx SnW_Hy cmp __a jne l1 setScrAt SnW_Hx SnW_Hy __c l1: ; check character in front of the head #if .byte __b = #chrFruit ldy fruit_Y lda #0 sta FHighlight,Y mvza fruit_Y setScrAt __x __y #0 mva #1 __z #else #if .byte __b = #chrFruitEx ldy fruitExtra_Y lda #0 sta FHighlightEx,Y mvza fruitExtra_Y setScrAt __x __y #0 mva #2 __z #else #if .byte __b <> #0 jsr CheckMovePossibleW jcs l2 mva #3 __z ; game over rts l2: #end #end #end ; move the head #if .byte __a = #chrHead_R #if .byte SnW_Dir = #cUp mva #chrBody_UL __b #else #if .byte SnW_Dir = #cDown mva #chrBody_DL __b #else mva #chrBody_H __b #end #end #else #if .byte __a = #chrHead_U #if .byte SnW_Dir = #cLeft mva #chrBody_DL __b #else #if .byte SnW_Dir = #cRight mva #chrBody_DR __b #else mva #chrBody_V __b #end #end #else #if .byte __a = #chrHead_L #if .byte SnW_Dir = #cUp mva #chrBody_UR __b #else #if .byte SnW_Dir = #cDown mva #chrBody_DR __b #else mva #chrBody_H __b #end #end #else #if .byte __a = #chrHead_D #if .byte SnW_Dir = #cLeft mva #chrBody_UL __b #else #if .byte SnW_Dir = #cRight mva #chrBody_UR __b #else mva #chrBody_V __b #end #end #end #end #end #end setFldW SnW_Hx SnW_Hy __b setFldW __x __y __c getScrAt SnW_Hx SnW_Hy cmp __c jne l3 setScrAt SnW_Hx SnW_Hy __b setScrAt __x __y __c jmp l4 l3: getScrAt __x __y cmp #0 jne l4 setScrAt __x __y __c l4: mva __x SnW_Hx mva __y SnW_Hy rts .endp ;------------------------------------------------------------------------- MoveHeadB .proc mvza __z getFldB SnB_Hx SnB_Hy ; current 'head' character sta __a jsr calculateNextHeadCoordB getScrAt __x __y sta __b ; character in front of the 'head' #if .byte SnB_Dir = #cRight ldx #chrHeadB_R #else #if .byte SnB_Dir = #cUp ldx #chrHeadB_U #else #if .byte SnB_Dir = #cLeft ldx #chrHeadB_L #else #if .byte SnB_Dir = #cDown ldx #chrHeadB_D #end #end #end #end stx __c setFldB SnB_Hx SnB_Hy __c ; turn the head (no move yet) getScrAt SnB_Hx SnB_Hy cmp __a jne l1 setScrAt SnB_Hx SnB_Hy __c l1: ; check character in front of the head #if .byte __b = #chrFruit ldy fruit_Y lda #0 sta FHighlight,Y mvza fruit_Y setScrAt __x __y #0 mva #1 __z #else #if .byte __b = #chrFruitEx ldy fruitExtra_Y lda #0 sta FHighlightEx,Y mvza fruitExtra_Y setScrAt __x __y #0 mva #2 __z #else #if .byte __b <> #0 jsr CheckMovePossibleB jcs l2 mva #3 __z ; game over rts l2: #end #end #end ; move the head #if .byte __a = #chrHeadB_R #if .byte SnB_Dir = #cUp mva #chrBodyB_UL __b #else #if .byte SnB_Dir = #cDown mva #chrBodyB_DL __b #else mva #chrBodyB_H __b #end #end #else #if .byte __a = #chrHeadB_U #if .byte SnB_Dir = #cLeft mva #chrBodyB_DL __b #else #if .byte SnB_Dir = #cRight mva #chrBodyB_DR __b #else mva #chrBodyB_V __b #end #end #else #if .byte __a = #chrHeadB_L #if .byte SnB_Dir = #cUp mva #chrBodyB_UR __b #else #if .byte SnB_Dir = #cDown mva #chrBodyB_DR __b #else mva #chrBodyB_H __b #end #end #else #if .byte __a = #chrHeadB_D #if .byte SnB_Dir = #cLeft mva #chrBodyB_UL __b #else #if .byte SnB_Dir = #cRight mva #chrBodyB_UR __b #else mva #chrBodyB_V __b #end #end #end #end #end #end setFldB SnB_Hx SnB_Hy __b setFldB __x __y __c getScrAt SnB_Hx SnB_Hy cmp __c jne l3 setScrAt SnB_Hx SnB_Hy __b setScrAt __x __y __c jmp l4 l3: getScrAt __x __y cmp #0 jne l4 setScrAt __x __y __c l4: mva __x SnB_Hx mva __y SnB_Hy rts .endp ;------------------------------------------------------------------------- DrawSnakeAtRandomPos .proc ; C flag - 0: white, 1: black php l2 lda RANDOM and #15 sta __y #if .byte __y > #(.len(Lines) -1) SBB __y #.len(Lines) #end ldy __y lda Lines,Y cmp fruit_Y jeq l2 cmp fruitExtra_Y jeq l2 sta __y lda RANDOM and #31 sta __x #if .byte __x > #19 SBB __x #20 #end #if .byte __x < __a ADB __x __a #end plp jcs l1 #if .byte SnW_Dir = #cLeft lda #39 sec sbc __x sta __x #end jmp drawSnakeBeginW l1 #if .byte SnB_Dir = #cLeft lda #39 sec sbc __x sta __x #end jmp drawSnakeBeginB .array Lines .byte 2, 3, 5, 6, 17, 18, 19, 20, 21, 22 .enda .endp ;------------------------------------------------------------------------- DrawSnakeRandomW .proc mva #cLeft SnW_Dir lda RANDOM and #1 beq _l1 mva #cRight SnW_Dir _l1 ; a = RND 10..19 lda RANDOM and #15 sta __a #if .byte __a > #9 SBB __a #10 #end ADB __a #10 clc jmp DrawSnakeAtRandomPos .endp ;------------------------------------------------------------------------- DrawSnakeRandomB .proc mva #cLeft SnB_Dir lda RANDOM and #1 beq _l1 mva #cRight SnB_Dir _l1 ; a = RND 10..19 lda RANDOM and #15 sta __a #if .byte __a > #9 SBB __a #10 #end ADB __a #10 sec jmp DrawSnakeAtRandomPos .endp ;------------------------------------------------------------------------- CheckMovePossibleW .proc getScrAt __x __y jeq l1 checkIfSnakeCharB jcc l2 getFldW __x __y jne l2 l1: ; yes sec rts l2: ; no clc rts .endp CheckMovePossibleB .proc getScrAt __x __y jeq l1 checkIfSnakeCharW jcc l2 getFldB __x __y jne l2 l1: ; yes sec rts l2: ; no clc rts .endp ;------------------------------------------------------------------------- ChangeDirectionW .proc ; check if there's any move yet mva SnW_Hx __x mva SnW_Hy __y #if .byte __x = #39 \ mva #0 __x \ #else \ inc __x \ #end jsr CheckMovePossibleW jcs l1 mva SnW_Hx __x #if .byte __x = #0 \ mva #39 __x \ #else \ dec __x \ #end jsr CheckMovePossibleW jcs l1 mva SnW_Hx __x #if .byte __y = #23 \ mva #1 __y \ #else \ inc __y \ #end jsr CheckMovePossibleW jcs l1 mva SnW_Hy __y #if .byte __y = #1 \ mva #23 __y \ #else \ dec __y \ #end jsr CheckMovePossibleW jcs l1 ; move is not possible mva #8 SnW_State clc rts l1 ; turn #if .byte RANDOM >= #128 l2: ;turn left #if .byte SnW_Dir = #cRight mva #cUp SnW_Dir #else #if .byte SnW_Dir = #cUp mva #cLeft SnW_Dir #else #if .byte SnW_Dir = #cLeft mva #cDown SnW_Dir #else mva #cRight SnW_Dir #end #end #end calculateNextHeadCoordW jsr CheckMovePossibleW jcs l4 jmp l2 #else l3: ;turn right #if .byte SnW_Dir = #cRight mva #cDown SnW_Dir #else #if .byte SnW_Dir = #cUp mva #cRight SnW_Dir #else #if .byte SnW_Dir = #cLeft mva #cUp SnW_Dir #else mva #cLeft SnW_Dir #end #end #end calculateNextHeadCoordW jsr CheckMovePossibleW jcs l4 jmp l3 #end l4: sec rts .endp ;------------------------------------------------------------------------- ChangeDirectionB .proc ; check if there's any move yet mva SnB_Hx __x mva SnB_Hy __y #if .byte __x = #39 \ mva #0 __x \ #else \ inc __x \ #end jsr CheckMovePossibleB jcs l1 mva SnB_Hx __x #if .byte __x = #0 \ mva #39 __x \ #else \ dec __x \ #end jsr CheckMovePossibleB jcs l1 mva SnB_Hx __x #if .byte __y = #23 \ mva #1 __y \ #else \ inc __y \ #end jsr CheckMovePossibleB jcs l1 mva SnB_Hy __y #if .byte __y = #1 \ mva #23 __y \ #else \ dec __y \ #end jsr CheckMovePossibleB jcs l1 ; change is not possible mva #8 SnB_State clc rts l1 ; turn #if .byte RANDOM >= #128 l2: ;turn left #if .byte SnB_Dir = #cRight mva #cUp SnB_Dir #else #if .byte SnB_Dir = #cUp mva #cLeft SnB_Dir #else #if .byte SnB_Dir = #cLeft mva #cDown SnB_Dir #else mva #cRight SnB_Dir #end #end #end calculateNextHeadCoordB jsr CheckMovePossibleB jcs l4 jmp l2 #else l3: ;turn right #if .byte SnB_Dir = #cRight mva #cDown SnB_Dir #else #if .byte SnB_Dir = #cUp mva #cRight SnB_Dir #else #if .byte SnB_Dir = #cLeft mva #cUp SnB_Dir #else mva #cLeft SnB_Dir #end #end #end calculateNextHeadCoordB jsr CheckMovePossibleB jcs l4 jmp l3 #end l4: sec rts .endp ;------------------------------------------------------------------------- AnimateSnakeW .proc #if .byte SnW_State <> #0 jmp hideSnake #end jsr moveTailW jsr calculateNextHeadCoordW jsr CheckMovePossibleW jcs l1 jsr ChangeDirectionW jcs l2 rts l1: lda RANDOM and #15 cmp #3 jcs l2 jsr ChangeDirectionW l2: jsr moveHeadW rts hideSnake: #if .byte SnW_Hx <> SnW_Tx .or .byte SnW_Hy <> SnW_Ty jsr moveTailW #if .byte SnW_Hx <> SnW_Tx .or .byte SnW_Hy <> SnW_Ty rts #end #end getScrAt SnW_Hx SnW_Hy checkIfSnakeCharW jcc l5 #if .byte SnW_State = #8 setScrAt SnW_Hx SnW_Hy #10 #else #if .byte SnW_State = #7 setScrAt SnW_Hx SnW_Hy #61 #else #if .byte SnW_State = #6 setScrAt SnW_Hx SnW_Hy #62 #else #if .byte SnW_State = #5 setScrAt SnW_Hx SnW_Hy #0 #else #end #end #end #end l5: #if .byte SnW_State = #8 setFldW SnW_Hx SnW_Hy #10 #else #if .byte SnW_State = #7 setFldW SnW_Hx SnW_Hy #61 #else #if .byte SnW_State = #6 setFldW SnW_Hx SnW_Hy #62 #else #if .byte SnW_State = #5 setFldW SnW_Hx SnW_Hy #0 #else #end #end #end #end dec SnW_State jne l6 jsr DrawSnakeRandomW l6: rts .endp ;------------------------------------------------------------------------- AnimateSnakeB .proc #if .byte SnB_State <> #0 jmp hideSnake #end jsr moveTailB jsr calculateNextHeadCoordB jsr CheckMovePossibleB jcs l1 jsr ChangeDirectionB jcs l2 rts l1: lda RANDOM and #15 cmp #3 jcs l2 jsr ChangeDirectionB l2: jsr moveHeadB rts hideSnake: #if .byte SnB_Hx <> SnB_Tx .or .byte SnB_Hy <> SnB_Ty jsr moveTailB #if .byte SnB_Hx <> SnB_Tx .or .byte SnB_Hy <> SnB_Ty rts #end #end getScrAt SnB_Hx SnB_Hy checkIfSnakeCharB jcc l5 #if .byte SnB_State = #8 setScrAt SnB_Hx SnB_Hy #10 #else #if .byte SnB_State = #7 setScrAt SnB_Hx SnB_Hy #61 #else #if .byte SnB_State = #6 setScrAt SnB_Hx SnB_Hy #62 #else #if .byte SnB_State = #5 setScrAt SnB_Hx SnB_Hy #0 #else #end #end #end #end l5: #if .byte SnB_State = #8 setFldB SnB_Hx SnB_Hy #10 #else #if .byte SnB_State = #7 setFldB SnB_Hx SnB_Hy #61 #else #if .byte SnB_State = #6 setFldB SnB_Hx SnB_Hy #62 #else #if .byte SnB_State = #5 setFldB SnB_Hx SnB_Hy #0 #else #end #end #end #end dec SnB_State jne l6 jsr DrawSnakeRandomB l6: rts .endp ;------------------------------------------------------------------------- ShowGameMode .proc clearFldW clearFldB mvza SnW_State mvza SnB_State #if .byte _selectedMode = #0 putArrOnScr 0 1 40 7 arrMode12 mva #cLeft SnW_Dir mva #15 __x mva #6 __y mva #10 __a jsr drawSnakeBeginW #else #if .byte _selectedMode = #1 putArrOnScr 0 1 40 7 arrMode12 mva #cLeft SnB_Dir mva #15 __x mva #6 __y mva #10 __a jsr drawSnakeBeginB #else #if .byte _selectedMode = #2 putArrOnScr 0 1 40 7 arrMode34 mva #cLeft SnW_Dir mva #5 __x mva #6 __y mva #10 __a jsr drawSnakeBeginW mva #cRight SnB_Dir mva #34 __x mva #2 __y mva #10 __a jsr drawSnakeBeginB #else #if .byte _selectedMode = #3 putArrOnScr 0 1 40 7 arrMode34 mva #cLeft SnB_Dir mva #5 __x mva #6 __y mva #10 __a jsr drawSnakeBeginB mva #cRight SnW_Dir mva #34 __x mva #2 __y mva #10 __a jsr drawSnakeBeginW #end #end #end #end rts .endp ChangeSnakes .proc exchangeMemory arrSnakeFldW \ arrSnakeFldW_End \ arrSnakeFldB \ changeSnakeChars changeMemory (_scr + 40) \ (_scr + 40*8) \ changeSnakeChars lda SnW_Hx ldx SnB_Hx sta SnB_Hx stx SnW_Hx lda SnW_Hy ldx SnB_Hy sta SnB_Hy stx SnW_Hy lda SnW_Tx ldx SnB_Tx sta SnB_Tx stx SnW_Tx lda SnW_Ty ldx SnB_Ty sta SnB_Ty stx SnW_Ty lda SnW_Dir ldx SnB_Dir sta SnB_Dir stx SnW_Dir rts .endp .array arrMode12 .byte :40 $4A :10 $4A \ :21 $00 \ :9 $4A :10 $4A \ $00 \ :19 $4A \ $00 \ :9 $4A :10 $4A \ $00, $4A, "GET", $4A, "READY", $4A, "PLAYER!", $4A, $00 \ :9 $4A :10 $4A \ $00 \ :19 $4A \ $00 \ :9 $4A :10 $4A \ :21 $00 \ :9 $4A :40 $4A .enda .array arrMode34 .byte :40 $4A $4A \ :18 $00 \ :2 $4A \ :18 $00 \ $4A $4A, $00 \ :16 $4A \ $00 \ :2 $4A \ $00 \ :16 $4A \ $00, $4A $4A, $00, $4A, " PLAYER - 1 - ", $4A, $00 \ :2 $4A \ $00, $4A, " PLAYER - 2 - ", $4A, $00, $4A $4A, $00 \ :16 $4A \ $00 \ :2 $4A \ $00 \ :16 $4A \ $00, $4A $4A \ :18 $00 \ :2 $4A \ :18 $00 \ $4A :40 $4A .enda arrMode12_lo: :7 dta l(arrMode12 + #*40) arrMode12_hi: :7 dta h(arrMode12 + #*40) arrMode34_lo: :7 dta l(arrMode34 + #*40) arrMode34_hi: :7 dta h(arrMode34 + #*40) ;------------------------------------------------------------------------- TitlePage .proc ; Credits page ClearScr getColor #3 _bgrndColorPtr sta PM_COLS0 sta PM_COLS1 sta PM_COLS2 mva #80 PM_XPOS mva #112 PM_XPOS+1 mva #144 PM_XPOS+2 mva #3 PM_WIDTH mva #3 PM_WIDTH+1 mva #3 PM_WIDTH+2 mwa #DList SDLSTL mva #0 NMIEN mwa #DLI_Proc2 VDSLST mva #192 NMIEN fillMemory FHighlight (FHighlight + .len(FHighlight)) 0 fillMemory FHighlightEx (FHighlightEx + .len(FHighlightEx)) 0 mvza fruit_Y mvza fruitExtra_Y mvza tmrBase jsr ClearMsg jsr WriteTitle mwza tmrDisplMsgs mvza _msgNum mvza _msgNum2 clearFldW clearFldB lda RANDOM and #1 jne l1 jsr drawArea1 jmp l2 l1 jsr drawArea2 l2 jsr WriteCredits jsr ChangeMsg jsr DrawSnakeRandomW jsr DrawSnakeRandomB mvza CH mvza SnW_State mvza SnB_State loop #if .byte tmrBase >= #9 jsr animateSnakeW jsr animateSnakeB mvza tmrBase #end #if .word tmrDisplMsgs >= #250 jsr ChangeMsg #end jsr CheckKeys jsr CheckTrigger jcc loop rts .endp SelectionPage .proc ; Mode selection jsr ClearMsg jsr clearScr clearFldW clearFldB mwa #DList2 SDLSTL mva #10 _msgNum mva #255 _msgNum2 jsr changeMsg mva #0 NMIEN mwa #DLI_Proc2A VDSLST mva #192 NMIEN mvza PM_PATRN+2 getColor #3 _bgrndColorPtr ora #$03 sta PM_COLS0 sta PM_COLS1 ldx _selectedArea mva arrPosHLL,x PM0_XPOS ldx _selectedArea mva arrPosHLR,x PM1_XPOS jsr writeTitle jsr ShowGameMode putArrOnScr 2 12 36 7 arrFields mvza CH mva #$F _tmpState loop jsr CheckKeys #if .byte CH = #28 ;ESC clc rts #end lda STICK0 and #$F cmp #$F jne l3 lda STICK1 and #$F cmp #$F jne l3 #if .byte _tmpState = #cUp inc _selectedMode #if .byte _selectedMode = #4 mvza _selectedMode #end #if .byte _selectedMode = #0 .or .byte _selectedMode = #2 jsr ShowGameMode #else jsr ChangeSnakes #end #else #if .byte _tmpState = #cDown dec _selectedMode #if .byte _selectedMode = #-1 mva #3 _selectedMode #end #if .byte _selectedMode = #1 .or .byte _selectedMode = #3 jsr ShowGameMode #else jsr ChangeSnakes #end #else #if .byte _tmpState = #cLeft .and .byte _selectedArea > #0 dec _selectedArea ldx _selectedArea mva arrPosHLL,x __a mva __a PM0_XPOS ldx _selectedArea mva arrPosHLR,x __b mva __b PM1_XPOS #else #if .byte _tmpState = #cRight .and .byte _selectedArea < #3 inc _selectedArea ldx _selectedArea mva arrPosHLL,x __a mva __a PM0_XPOS ldx _selectedArea mva arrPosHLR,x __b mva __b PM1_XPOS #end #end #end #end lda #$F l3: sta _tmpState #if .byte tmrBase >= #9 #if .byte _selectedMode <> #1 jsr animateSnakeW #end #if .byte _selectedMode <> #0 jsr animateSnakeB #end mvza tmrBase #end #if .word tmrDisplMsgs >= #250 jsr changeMsg #end jsr CheckTrigger jcc loop sec rts .endp ICL 'GameProc.asm'