;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Blue Elite Koopa
; by yoshicookiezeus
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


			!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
			JSR SubHorzPos
			TYA
			STA $C2,x
			LDA #$10
			STA $1540,x
			LDA #$40
			STA $1594,x
			RTL


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

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


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

XSpeed:			db $20,$E0

MainCode:		JSR SpriteGraphics
			LDA $14C8,x			;\ if sprite status not normal,
			CMP #$08			; |
			BNE .Return			;/ branch
			LDA !RAM_SpritesLocked		;\ if sprites locked,
			BNE .Return			;/ branch
			JSR SubOffScreenX0

			LDY $C2,x			;\ set sprite speed depending on direction
			LDA XSpeed,y			; |
			STA !RAM_SpriteSpeedX,x		;/
			JSL $018022			; update sprite position
			JSL $01803A			; interact with Mario

			DEC $1594,x			;\ if time to split,
			BEQ Split			;/ branch

.Return			RTS


Split:			JSR Smoke			; display smoke
			LDA #$01
			STA $1528,x
.LoopStart		JSL $02A9DE			; get empty slot for spawned sprite
			BMI .Return

			LDA #$08			;\ set status of new sprite
			STA $14C8,y			;/
			LDA #$1C			;\ set number of new sprite (bullet bill)
			STA.w !RAM_SpriteNum,y		;/
			LDA !RAM_SpriteXLo,x		;\ set position of new sprite
			STA.w !RAM_SpriteXLo,y		; |
			LDA !RAM_SpriteXHi,x		; |
			STA !RAM_SpriteXHi,y		; |
			LDA !RAM_SpriteYLo,x		; |
			STA.w !RAM_SpriteYLo,y		; |
			LDA !RAM_SpriteYHi,x		; |
			STA !RAM_SpriteYHi,y		; /

			PHX				;\ clear out sprite table values for new sprite
			TYX				; |
			JSL $07F7D2			; |
			PLX				;/

			LDA $C2,x			;\ set direction of new sprite
			ASL				; |
			CLC				; |
			ADC #$04			; |
			CLC
			ADC $1528,x			; |
			STA.w $C2,y			;/

			LDA #$09			;\ play sound effect
			STA $1DFC			;/

			DEC $1528,x			;\ if still sprites left to spawn,
			BPL .LoopStart			;/ branch

.Return			STZ $14C8,x			; erase sprite
			
			RTS


Smoke:			LDY #$03
.LoopStart		LDA $17C0,y
			BEQ .SlotFound
			DEY
			BPL .LoopStart
			RTS

.SlotFound		LDA #$01
			STA $17C0,y
			LDA !RAM_SpriteYLo,x
			STA $17C4,y
			LDA !RAM_SpriteXLo,x
			STA $17C8,y
			LDA #$18
			STA $17CC,y
			RTS


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

!Tile			= $A6
Properties:		db $40,$00

SpriteGraphics:		JSL $20CA4F

			LDA $C2,x
			PHX
			TAX
			LDA Properties,x
			STA $02
			PLX

			LDA $14C8,x
			CMP #$08
			BEQ .NoFlip
			LDA $02
			ORA #$80
			STA $02

.NoFlip			LDA $1540,x
			BNE .LowPriority
			LDA $02
			ORA $64
			STA $02
			BRA .GraphicsMain

.LowPriority		LDA $02
			ORA #$10
			STA $02			

.GraphicsMain		LDA $00
			STA !OAM_DispX,y
			LDA $01
			STA !OAM_DispY,y
			LDA #!Tile
			STA !OAM_Tile,y
			LDA !RAM_SpritePal,x
			ORA $02
			STA !OAM_Prop,y

			LDA #$00
			LDY #$02
			JSL $01B7B3
			RTS
			



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_OFF_SCREEN
; This subroutine deals with sprites that have moved off screen
; It is adapted from the subroutine at $01AC0D
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
			
SprT12:			db $40,$B0
SprT13:			db $01,$FF
SprT14:			db $30,$C0,$A0,$C0,$A0,$F0,$60,$90		;bank 1 sizes
			db $30,$C0,$A0,$80,$A0,$40,$60,$B0		;bank 3 sizes
SprT15:			db $01,$FF,$01,$FF,$01,$FF,$01,$FF		;bank 1 sizes
			db $01,$FF,$01,$FF,$01,$00,$01,$FF		;bank 3 sizes

SubOffScreenX1:		LDA #$02		;\ entry point of routine determines value of $03
			BRA Store03		; | (table entry to use on horizontal levels)
SubOffScreenX2:		LDA #$04		; | 
			BRA Store03		; |
SubOffScreenX3:		LDA #$06		; |
			BRA Store03		; |
SubOffScreenX4:		LDA #$08		; |
			BRA Store03		; |
SubOffScreenX5:		LDA #$0A		; |
			BRA Store03		; |
SubOffScreenX6:		LDA #$0C		; |
			BRA Store03		; |
SubOffScreenX7:		LDA #$0E		; |
Store03:		STA $03			; |            
			BRA SubOffScreenMain	; |
SubOffScreenX0:		STZ $03			;/

SubOffScreenMain:	JSR .SubIsOffScreen	;\ if sprite is not off screen, return
			BEQ .Return		;/
			LDA $5B			;\  goto VERTICAL_LEVEL if vertical level
			AND #$01		; |
			BNE .VerticalLevel	;/     
			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 .EraseSprite	;/    ...erase the sprite
			LDA $167A,x		;\ if "process offscreen" flag is set, return
			AND #$04		; |
			BNE .Return		;/
			LDA $13
			AND #$01
			ORA $03
			STA $01
			TAY
			LDA $1A
			CLC
			ADC SprT14,y
			ROL $00
			CMP $E4,x
			PHP
			LDA $1B
			LSR $00
			ADC SprT15,y
			PLP
			SBC $14E0,x
			STA $00
			LSR $01
			BCC .Label31
			EOR #$80
			STA $00
.Label31		LDA $00
			BPL .Return
.EraseSprite		LDA $14C8,x		;\ if sprite status < 8, permanently erase sprite
			CMP #$08		; |
			BCC .KillSprite		;/    
			LDY $161A,x		;
			CPY #$FF		;
			BEQ .KillSprite		;
			LDA #$00		;
			STA $1938,y		;
.KillSprite		STZ $14C8,x		; erase sprite
.Return			RTS			; return

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

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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_HORZ_POS
; This routine determines which side of the sprite Mario is on.  It sets the Y register
; to the direction such that the sprite would face Mario
; It is ripped from $03B817
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SubHorzPos:		LDY #$00
			LDA $D1
			SEC
			SBC $E4,x
			STA $0F
			LDA $D2
			SBC $14E0,x
			BPL .Return
			INY
.Return			RTS