;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; INIT and MAIN JSL targets
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

incsrc subroutinedefs_xkas.asm

!FrameNum = $C2
!Direction = $157C
!Carrying = $1510
!Moving = $1504
!ClawPos = $1528
!WaitTimer = $1540
!InteractWaitTimer = $15AC
!JustGotFlag = $1594
!OpenClawTimer = $154C
!ClawRange = $7FAB34
!ClawSpriteNum = #$2B

                    print "INIT ",pc
                    STZ !FrameNum,x
                    STZ !Carrying,x
					LDA $7FAB10,x
					AND #$04
					LSR #2
                    STA !Direction,x
                    STZ !WaitTimer,x
                    STZ !JustGotFlag,x
					STZ !Moving,x
					STZ !ClawPos,x
                    RTL

	                print "MAIN ",pc			
                    PHB
                    PHK				
                    PLB
                    JSR SPRITE_ROUTINE			;Jump to the routine to keep organized
                    PLB
                    RTL     


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SPRITE_ROUTINE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

XSpeeds:
db $10,$F0



SPRITE_ROUTINE:	  	

					LDA $9D
					BNE .sendreturn
					LDA $14C8,x
					CMP #$08
					BEQ +
					.sendreturn
					JMP return
					+
					JSL $819138
					LDA !Carrying,x
					BEQ +
					STZ $140D
					+
					LDA !Carrying,x
					BNE +
					LDA !ClawPos,x
					BEQ +
					DEC !ClawPos,x
					+
					LDA $1588,x
					BEQ +
					LDA !Moving,x
					BEQ +
					STZ !Moving,x
					LDA #$30
					STA !WaitTimer,x
					LDA !Direction,x
					EOR #$01
					STA !Direction,x
					+
					LDA !InteractWaitTimer,x
					BNE +
					LDA !Carrying,x
					BNE +
					LDA !ClawPos,x
					STA $00
					STZ $01
					LDA $14D4,x
					PHA
					XBA
					LDA $D8,x
					PHA
					REP #$20
					CLC
					ADC $00
					SEP #$20
					STA $D8,x
					XBA
					STA $14D4,x
					JSL $81A7DC
					PHP
					PLA
					STA $00
					PLA
					STA $D8,x
					PLA
					STA $14D4,x
					LDA $00
					PHA
					PLP
					BCC +
					ldy #$0C
					-
						;Unsafe, doesn't check to make sure custom spite. Don't mix with sume brother's lightning.
						lda $009E,y
						cmp.b !ClawSpriteNum
						bne .NotClaw
							lda !Carrying,y
							bne +
						.NotClaw
						dey
						bpl -
					LDA #$01
					STA !Carrying,x
					STA !JustGotFlag,x
					STA !Moving,x
					+
					LDA !WaitTimer,x
					BNE .Waiting
					LDA !Moving,x
					BEQ +
					LDY !Direction,x
					LDA XSpeeds,y
					STA $B6,x
					STZ !JustGotFlag,x
					LDA !Carrying,x
					BEQ +++
					LDA $77
					BIT #$03
					BEQ ++
					STZ !Carrying,x
					LDA #$20
					STA !InteractWaitTimer,x
					++
					LDA $77
					BIT #$08
					BEQ ++
					++
					LDA $15
					BIT #$04
					BEQ ++
					LDA $77
					BIT #$04
					BNE +++
					LDA !ClawPos,x
					CMP !ClawRange,x
					BEQ +++
					INC !ClawPos,x
					BRA +++
					++
					LDA $15
					BIT #$08
					BEQ +++
					LDA !ClawPos,x
					BEQ +++
					LDA $77
					BIT #$08
					BNE +++
					DEC !ClawPos,x
					+++
					LDA $16
					BIT #$80
					BEQ +
					LDA !Carrying,x
					BEQ +
					LDA #$20
					STA !InteractWaitTimer,x
					STZ !Carrying,x
					LDA #$30
					STA !OpenClawTimer,x
					+
					BRA .NotWaiting
					.Waiting
					LDA !JustGotFlag,x
					BNE +
					LDA !WaitTimer,x
					AND #$07
					CMP #$07
					BNE +
					LDA !FrameNum,x
					BEQ ++
					DEC !FrameNum,x
					++
					LDA !Carrying,x
					BEQ +
					STZ !Carrying,x
					LDA #$20
					STA !InteractWaitTimer,x
					+
					STZ $B6,x
					.NotWaiting
					LDA !OpenClawTimer,x
					AND #$07
					CMP #$07
					BNE +
					LDA !FrameNum,x
					BEQ +
					DEC !FrameNum,x
					+
					JSL $818022
					LDA !Carrying,x
					Bne + 
						jmp return
					+
					LDA #$02
					STA !FrameNum,x
					STZ $7D
					STZ $7B
					LDA $14E0,x
					XBA
					LDA $E4,x
					REP #$20
					sta $00
					sec
					sbc $94
					sta $02
					bpl +
						eor #$FFFF
						inc
					+
					cmp #$0004
					lda $00
					bcc +
						lda $94
						clc
						adc #$0004
						sta $04
						lda $02
						bpl ++
							lda $04
							sec
							sbc #$0008
							sta $04
						++
						lda $04
					+
					STA $94
					SEP #$20
					LDA $19
					BNE +
					REP #$20
					LDA #$0013
					STA $00
					SEP #$20
					BRA ++
					+
					REP #$20
					LDA #$001B
					STA $00
					SEP #$20
					++
					LDA !ClawPos,x
					STA $02
					STZ $03
					LDA $14D4,x
					XBA
					LDA $D8,x
					REP #$20
					CLC
					ADC $00
					CLC
					ADC $02
					sta $00
					sec
					sbc $96
					sta $02
					bpl +
						eor #$FFFF
						inc
					+
					cmp #$0008
					lda $00
					bcc +
						lda $96
						clc
						adc #$0008
						sta $04
						lda $02
						bpl ++
							lda $04
							sec
							sbc #$0010
							sta $04
						++
						lda $04
					+
					STA $96
					SEP #$20
					LDA #$24
					STA $13E0
					return:
					JSR SUB_OFF_SCREEN_X5
					JSR SUB_GFX					;Draw the graphics
                    RTS							;End the routine
				

TileSize:
db $02,$02,$02

TileProperties:
db $00,$00,$40

XOff:
db $00,$F8,$08

YOff:
db $00,$18,$18

ClawTiles:
db $80,$82,$84									;Tiles to use for the first, second, and third frames of the claw

SUB_GFX:            JSL !GetDrawInfo       	;Get all the drawing info, duh
					LDA !Carrying,x				;This is a bit confusing, but these are the tile numbers. Didn't make any sense to use a table for this
					BEQ +
					LDA #$E4					;Tile number for the green block
					BRA ++
					+
					LDA #$E2					;Tile number for the red block
					++
					STA $02
					LDA !FrameNum,x
					PHX
					TAX
					LDA ClawTiles,x				;The tile to use for the claw. Defined above.
					STA $03
					STA $04
					
					LDX #$02
					.GFXLoop
					LDA $00
					CLC
					ADC XOff,x
					STA $0300,y
					
					LDA $01
					CLC
					ADC YOff,x
					CPX #$01
					BCC +
					PHX
					LDX $15E9
					CLC
					ADC !ClawPos,x
					PLX
					+
					STA $0301,y
					
					LDA $02,x
					STA $0302,y
					PHX
					LDX $15E9
					LDA $15F6,x
					PLX
					ORA $64
					ORA TileProperties,x
					STA $0303,y
					PHY
					TYA
					LSR #2
					TAY
					LDA TileSize,x
					PHX
					LDX $15E9
					ORA $15A0,x	; horizontal offscreen flag
					PLX
					STA $0460,y	;
					PLY
					INY
					INY
					INY
					INY
					DEX
					BPL .GFXLoop
					PLX
					LDA #$04
					LDY #$FF
					JSL $81B7B3					;/and then draw em
					EndIt:
					RTS
					
					
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_OFF_SCREEN
; This subroutine deals with sprites that have moved off screen
; It is adapted from the subroutine at $01AC0D
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                    
SPR_T12:             db $40,$B0
SPR_T13:             db $01,$FF
SPR_T14:             db $30,$C0,$A0,$C0,$A0,$F0,$60,$90		;bank 1 sizes
		            db $30,$C0,$A0,$80,$A0,$40,$60,$B0		;bank 3 sizes
SPR_T15:             db $01,$FF,$01,$FF,$01,$FF,$01,$FF		;bank 1 sizes
					db $01,$FF,$01,$FF,$01,$00,$01,$FF		;bank 3 sizes

SUB_OFF_SCREEN_X1:   LDA #$02                ; \ entry point of routine determines value of $03
                    BRA STORE_03            ;  | (table entry to use on horizontal levels)
SUB_OFF_SCREEN_X2:   LDA #$04                ;  | 
                    BRA STORE_03            ;  |
SUB_OFF_SCREEN_X3:   LDA #$06                ;  |
                    BRA STORE_03            ;  |
SUB_OFF_SCREEN_X4:   LDA #$08                ;  |
                    BRA STORE_03            ;  |
SUB_OFF_SCREEN_X5:   LDA #$0A                ;  |
                    BRA STORE_03            ;  |
SUB_OFF_SCREEN_X6:  LDA #$0C                ;  |

                    BRA STORE_03            ;  |
SUB_OFF_SCREEN_X7:   LDA #$0E                ;  |
STORE_03:			STA $03					;  |            
					BRA START_SUB			;  |
SUB_OFF_SCREEN_X0:   STZ $03					; /

START_SUB:           JSR SUB_IS_OFF_SCREEN   ; \ if sprite is not off screen, return
                    BEQ RETURN_35           ; /
                    LDA $5B                 ; \  goto VERTICAL_LEVEL if vertical level
                    AND #$01                ; |
                    BNE VERTICAL_LEVEL      ; /     
                    LDA $D8,x               ; \
                    CLC                     ; | 
                    ADC #$50                ; | if the sprite has gone off the bottom of the level...
                    LDA $14D4,x             ; | (if adding 0x50 to the sprite y position would make the high byte >= 2)
                    ADC #$00                ; | 
                    CMP #$02                ; | 
                    BPL ERASE_SPRITE        ; /    ...erase the sprite
                    LDA $167A,x             ; \ if "process offscreen" flag is set, return
                    AND #$04                ; |
                    BNE RETURN_35           ; /
                    LDA $13
                    AND #$01
                    ORA $03
                    STA $01
                    TAY
                    LDA $1A
                    CLC
                    ADC SPR_T14,y
                    ROL $00
                    CMP $E4,x
                    PHP
                    LDA $1B
                    LSR $00
                    ADC SPR_T15,y
                    PLP
                    SBC $14E0,x
                    STA $00
                    LSR $01
                    BCC SPR_L31
                    EOR #$80
                    STA $00
SPR_L31:             LDA $00
                    BPL RETURN_35
ERASE_SPRITE:        LDA $14C8,x             ; \ if sprite status < 8, permanently erase sprite
                    CMP #$08                ; |
                    BCC KILL_SPRITE         ; /    
                    LDY $161A,x
                    CPY #$FF
                    BEQ KILL_SPRITE
                    LDA #$00
                    STA $1938,y
KILL_SPRITE:         STZ $14C8,x             ; erase sprite
RETURN_35:           RTS                     ; return

VERTICAL_LEVEL:      LDA $167A,x             ; \ if "process offscreen" flag is set, return
                    AND #$04                ; |
                    BNE RETURN_35           ; /
                    LDA $13                 ; \
                    LSR A                   ; | 
                    BCS RETURN_35           ; /
                    LDA $E4,x               ; \ 
                    CMP #$00                ;  | if the sprite has gone off the side of the level...
                    LDA $14E0,x             ;  |
                    SBC #$00                ;  |
                    CMP #$02                ;  |
                    BCS ERASE_SPRITE        ; /  ...erase the sprite
                    LDA $13
                    LSR A
                    AND #$01
                    STA $01
                    TAY
                    LDA $1C
                    CLC
                    ADC SPR_T12,y
                    ROL $00
                    CMP $D8,x
                    PHP
                    LDA.w $001D 
                    LSR $00
                    ADC SPR_T13,y
                    PLP
                    SBC $14D4,x
                    STA $00
                    LDY $01
                    BEQ SPR_L38
                    EOR #$80
                    STA $00
SPR_L38:             
					LDA $00
                    BPL RETURN_35
                    BMI ERASE_SPRITE

SUB_IS_OFF_SCREEN:   LDA $15A0,x             ; \ if sprite is on screen, accumulator = 0 
                    ORA $186C,x             ; |  
                    RTS                     ; / return

