;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Green Elite Koopa
; by yoshicookiezeus
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

incsrc subroutinedefs_xkas.asm

			!RAM_FrameCounter	= $13
			!RAM_FrameCounterB	= $14
			!RAM_ScreenBndryXLo	= $1A
			!RAM_ScreenBndryYLo	= $1C
			!RAM_MarioDirection	= $76
			!RAM_MarioSpeedX	= $7B
			!RAM_MarioSpeedY	= $7D
			!RAM_MarioXPos		= $94
			!RAM_MarioXPosHi	= $95
			!RAM_MarioYPos		= $96
			!RAM_SpritesLocked	= $9D
			!RAM_SpriteNum		= $9E
			!RAM_SpriteSpeedY	= $AA
			!RAM_SpriteSpeedX	= $B6
			!RAM_SpriteState	= $C2
			!RAM_SpriteYLo		= $D8
			!RAM_SpriteXLo		= $E4
			!OAM_DispX		= $0300
			!OAM_DispY		= $0301
			!OAM_Tile		= $0302
			!OAM_Prop		= $0303
			!OAM_Tile2DispX		= $0304
			!OAM_Tile2DispY		= $0305
			!OAM_Tile2		= $0306
			!OAM_Tile2Prop		= $0307
			!OAM_TileSize		= $0460
			!RAM_RandomByte1	= $148D
			!RAM_RandomByte2	= $148E
			!RAM_KickImgTimer	= $149A
			!RAM_SpriteYHi		= $14D4
			!RAM_SpriteXHi		= $14E0
			!RAM_Reznor1Dead	= $1520
			!RAM_Reznor2Dead	= $1521
			!RAM_Reznor3Dead	= $1522
			!RAM_Reznor4Dead	= $1523
			!RAM_DisableInter	= $154C
			!RAM_SpriteDir		= $157C
			!RAM_SprObjStatus	= $1588
			!RAM_OffscreenHorz	= $15A0
			!RAM_SprOAMIndex	= $15EA
			!RAM_SpritePal		= $15F6
			!RAM_Tweaker1662	= $1662
			!RAM_ExSpriteNum	= $170B
			!RAM_ExSpriteYLo	= $1715
			!RAM_ExSpriteXLo	= $171F
			!RAM_ExSpriteYHi	= $1729
			!RAM_ExSpriteXHi	= $1733
			!RAM_ExSprSpeedY	= $173D
			!RAM_ExSprSpeedX	= $1747
			!RAM_OffscreenVert	= $186C
			!RAM_OnYoshi		= $187A

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite init JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

			print "INIT ",pc
			JSL !SubHorizPos
			TYA
			STA !RAM_SpriteDir,x
			LDA #$40			;\
			STA $1540,x			;/ set time before attacking
			RTL				; return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite code JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

			print "MAIN ",pc
			PHB
			PHK
			PLB
			JSR MainCode
			PLB
			RTL


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MainCode:		JSR SpriteGraphics
			LDA $14C8,x			;\ if sprite status not normal,
			CMP #$08			; |
			BNE Return1			;/ branch
			LDA !RAM_SpritesLocked		;\ if sprites locked,
			BNE Return0			;/ branch
			JSL !SubOffscreenX0
			LDA $151C,x			;\ call pointer for current action
			JSL $8086DF			;/

Pointers:		dw Walk
			dw Attack
			dw Hurt
			dw Dead

Return0:		RTS				; return

Return1:		INC $1540,x
			RTS

HurtInState:		db $01,$00,$00
!Hitpoints		= $03

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

XSpeedWalk:		db $0C,$F4

Walk:			LDY !RAM_SpriteDir,x		;\ set sprite speed depending on direction
			LDA XSpeedWalk,y		; |
			STA !RAM_SpriteSpeedX,x		;/
			JSL $81802A			; update sprite position
			JSL $819138			; interact with objects
			JSL $818032			; interact with sprites
			LDA !RAM_SprObjStatus,x		;\ if sprite isn't touching wall,
			AND #$03			; |
			BEQ DontFlipWalk		;/ branch
			LDA !RAM_SpriteDir,x		;\ flip sprite direction
			EOR #$01			; |
			STA !RAM_SpriteDir,x		;/
DontFlipWalk:		LDA !RAM_SprObjStatus,x		;\ if sprite is on ground,
			AND #$04			; |
			BNE OnGroundWalk		;/
			INC $1540,x
OnGroundWalk:		LDA $1540,x			;\ if not yet time to attack,
			BNE StillState0			;/ branch
			LDA #$01			;\ set new sprite state (attacking)
			STA $151C,x			;/
			LDA #$40			;\ set time to attack
			STA $1540,x			;/
			JSL !SubHorizPos
			TYA
			STA !RAM_SpriteDir,x
StillState0:		JSR MarioInteract			
			RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

XSpeedAttack:		db $20,$E0

Attack:			LDY !RAM_SpriteDir,x		;\ set sprite speed depending on direction
			LDA XSpeedAttack,y		; |
			STA !RAM_SpriteSpeedX,x		;/
			JSL $81802A			; update sprite position
			JSL $819138			; interact with objects
			JSL $818032			; interact with sprites
			LDA !RAM_SprObjStatus,x		;\ if sprite isn't touching wall,
			AND #$03			; |
			BEQ DontFlipAttack		;/ branch
			LDA !RAM_SpriteDir,x		;\ flip sprite direction
			EOR #$01			; |
			STA !RAM_SpriteDir,x		;/
			LDA #$36
			STA $1DFC
DontFlipAttack:		LDA $1540,x			;\ if not yet time to stop attack,
			BNE StillState1			;/ branch
			LDA #$00			;\ set new sprite state (walking)
			STA $151C,x			;/
			LDA #$40			;\ set time to attack
			STA $1540,x			;/
			JSL !SubHorizPos
			TYA
			STA !RAM_SpriteDir,x
StillState1:		JSR MarioInteract			
			RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Hurt:			STZ !RAM_SpriteSpeedX,x		; clear sprite speed
			JSL $81802A			; update sprite position
			JSL $819138			; interact with objects
			JSL $818032			; interact with sprites
			LDA $1540,x			; if not yet time to stop being hurt,
			BNE StillState2			; branch
			LDA #$00			;\ set new sprite state (walking)
			STA $151C,x			;/
			LDA #$40			;\ set time to attack
			STA $1540,x			;/
StillState2:		JSR MarioInteract
			RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Dead:			RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Mario interaction routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MarioInteract:		JSL $81A7DC			;\ interact with Mario
			BCC Return03CEF1		;/ if no contact, branch
			LDA $1490			;\ if star timer isn't zero,
			BNE KillSprite			;/ branch
			LDA $154C,x
			BNE Return03CEF1
			LDA !RAM_MarioSpeedY		;\ if Mario is moving upwards,
			CMP #$10			; |
			BMI CODE_03CEED			;/  branch
			JSL $81AB99			; display contact graphic
			JSL $81AA33			; boost Mario upwards
			LDA #$02			;\ play sound effect
			STA $1DF9			;/
			LDA #$08
			STA $154C,x
			LDY $151C,x			;\ if current state is set to be invincible,
			LDA HurtInState,y		; |
			BEQ Return03CEEC		;/ branch
			INC $1534,x			; increase hitpoint counter
			LDA $1534,x			;\ if sprite hasn't been hit enough times,
			CMP #!Hitpoints			; |
			BNE CODE_03CEDB			;/ branch
KillSprite:		LDA #$02			;\ kill sprite
			STA $14C8,x			;/
			LDA #$E0
			STA !RAM_SpriteSpeedY,x
			LDA #$13			;\ play sound effect
			STA $1DF9			;/
			LDA #$03			;\ set new action (dead)
			STA $151C,x			;/
			LDA #$04			;\ give Mario 400 points
			JSL $82ACE5			;/
			RTS
CODE_03CEDB:		LDA #$02			;\ set action (stomped)
			STA $151C,x			;/
			LDA #$13			;\ play sound effect
			STA $1DF9			;/
			LDA #$40			;\ set time to stay in hurt state
			STA $1540,x			;/
Return03CEEC:		RTS				; return

CODE_03CEED:		JSL $80F5B7			; hurt Mario
Return03CEF1:		RTS				; return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; graphics routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Tilemap:		db $08,$28			; walking frame 1, right
			db $06,$26			; walking frame 2, right
			db $20,$40			; walking frame 1, left
			db $22,$42			; walking frame 2, left
			db $0C,$0A,$0E,$2D		; attacking frames
			db $0C				; hurt frame
			db $64				; dead frame

OffsetY:		db $F0,$00
			db $F0,$00
			db $F0,$00
			db $F0,$00
			db $00,$00,$00,$00
			db $00
			db $00

TilesToDraw:		db $01,$00,$00,$00		; walking, attacking, hurt

StartOffset:		db $00,$08,$0C,$0D		; walking, attacking, hurt

FrameDeterminatorBits:	db $02,$03,$00,$00		; walking, attacking, hurt, dead

DirectionOffset:	db $04,$00,$00,$00
			

SpriteGraphics:		JSL !GetDrawInfo

			STZ $02
			LDA !RAM_SpriteDir,x
			BEQ Right
			LDA $151C,x

			PHX
			TAX
			LDA DirectionOffset,x
			STA $02
			PLX

Right:			PHX
			LDA $151C,x
			TAX
			LDA FrameDeterminatorBits,x
			STA $03

			LDA StartOffset,x
			STA $04

			PLX
			LDA $1540,x
			LSR
			LSR
			AND $03
			CLC
			ADC $02
			CLC
			ADC $04
			STA $05
			PHX
			LDA $151C,x
			TAX
			LDA TilesToDraw,x
			STA $06
			TAX

Loop_Start:		PHX				; preserve loop counter

			LDX $05

			LDA $00				;\ set tile x position
			STA !OAM_DispX,y		;/

			LDA $01				;\ set tile y position
			CLC				; |
			ADC OffsetY,x			; |
			STA !OAM_DispY,y		;/

			LDA Tilemap,x			;\ set tile number
			STA !OAM_Tile,y			;/

			LDX $15E9			;\ set tile properties
			LDA $15F6,x			; |
			ORA $64				; |
			STA !OAM_Prop,y			;/

			INY				;\ increase OAM index by four, so that the next tile can be drawn
			INY				; |
			INY				; |
			INY				;/

			INC $05
			PLX				; retrieve loop counter
			DEX				; decrease loop counter
			BPL Loop_Start			; if more tiles left to draw, branch

			PLX				; retrieve sprite index

			LDY #$02
			LDA $06
			JSL $81B7B3
			
			RTS				; return

