;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Doc Croc, by yoshicookiezeus
; for ASMWCP2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

			!BulletNbr		= $0E	; cluster sprite number for bullet_croc.asm
			!MiscSpriteNbr		= $B8	; sprite number for croc_misc.asm
			!VialNbr		= $2F	; sprite number for ThrownVial.asm
			!DropperNbr		= $0D	; sprite number for droppable item to help (Bob-omb)
			!DropperNbr2		= $09	; sprite number for droppable item to help (Bob-omb)

			!FreeRAM		= $7EC400	; needs to be at least 20 (decimal) bytes
								; THIS MUST BE SET TO THE SAME VALUE AS THE DEFINE IN croc_bullet.asm!
			!GetSpriteClippingA 	= $03B69F
			!CheckForContact 	= $03B72B
			!TimeToExplode		= $FF

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; RAM address defines - don't change these
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

			!RAM_FrameCounter	= $13
			!RAM_FrameCounterB	= $14
			!RAM_MarioPowerUp	= $19
			!RAM_ScreenBndryXLo	= $1A
			!RAM_ScreenBndryYLo	= $1C
			!RAM_ScreensInLvl	= $5D
			!RAM_MarioAnimation	= $71
			!RAM_IsDucking		= $73
			!RAM_MarioDirection	= $76
			!RAM_MarioObjStatus	= $77
			!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_ExtendedDispX	= $0200
			!OAM_ExtendedDispY	= $0201
			!OAM_ExtendedTile	= $0202
			!OAM_ExtendedProp	= $0203
			!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_IsBehindScenery	= $13F9
			!RAM_RandomByte1	= $148D
			!RAM_RandomByte2	= $148E
			!RAM_KickImgTimer	= $149A
			!RAM_SpriteYHi		= $14D4
			!RAM_SpriteXHi		= $14E0
			!RAM_DisableInter	= $154C
			!RAM_SpriteDir		= $157C
			!RAM_SprObjStatus	= $1588
			!RAM_OffscreenHorz	= $15A0
			!RAM_SprOAMIndex	= $15EA
			!RAM_SpritePal		= $15F6
			!RAM_Tweaker1662	= $1662
			!RAM_Tweaker1686	= $1686
			!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
			!RAM_ShakeGrndTimer	= $1887
			!RAM_ClusterSpriteNum	= $1892
			!RAM_LockMarioTimer	= $18BD
			!RAM_ClusterYPosLo	= $1E02
			!RAM_ClusterYPosHi	= $1E2A
			!RAM_ClusterXPosLo	= $1E16
			!RAM_ClusterXPosHi	= $1E3E
			!RAM_ClusterYSpeed	= $1E52
			!RAM_ClusterXSpeed	= $1E66

			!RAM_DirectionTimer	= !FreeRAM

			!RAM_ExtraBits 		= $7FAB10
			!RAM_CustSpriteNum	= $7FAB9E


			!SpecialFlag		= $1510
			!CurrentAction		= $151C
			!GraphicsFrame		= $1528
			!HitCounter		= $1534
			!GenericTimer		= $1540
			!DisableContact		= $154C
			!AttackCounter		= $157C
			
			!Count8Down		= $13E6

; GraphicsFrame: ccddddxx
; c - cannon position
; d - doc pose
; x - unused

; HitCounter:
; 0 - spread
; 1 - bomb
; 2 - vials
; 3 - aimed
; 4-7 - random
; 6 - summon drone
; 8 - final

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

			!TimeTeleporting	= $20
			!Hitpoints		= $09

			!Gen_OffsetY		= $0B


TimeToWait1:		db $40,$40,$40,$40,$30,$20,$30,$20,$40
TimeToWait2:		db $60,$60,$60,$60,$58,$50,$58,$50,$40
TimeGone:		db $30,$30,$30,$30,$28,$20,$20,$18,$30

XPositions:		db $44,$4C,$54,$5C,$64,$6C,$74,$7C
			db $84,$8C,$94,$9C,$A4,$AC,$B4,$BC
YPositions:		db $02,$04,$06,$08,$0A,$0C,$0E,$10
			db $12,$14,$16,$18,$1A,$1C,$1E,$20

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

			print "INIT ",pc
			LDA !RAM_SpriteXLo,x
			CLC
			ADC #$08
			STA !RAM_SpriteXLo,x
			LDA #$F0
			STA !GenericTimer,x
			LDA #$01
			STA $18B8
			STA $13FB
			STZ !SpecialFlag,x

			LDA #$8E				;\ set up KooPhD vial tilemap
			STA $7F8809				; |
			STA $7F880C				; |
			LDA #$AE				; |
			STA $7F880A				; |
			STA $7F880B				;/
			RTL


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

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


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

Main:			JSR SpriteGraphics
			JSR CountAppear
			LDA $14C8,x			;\ if sprite state not normal,
			CMP #$08			; |
			BNE .Return			;/ return
			LDA !RAM_SpritesLocked		;\ if sprites locked,
			BNE .Return			;/ return
			STZ $149F			; disable cape flight
			LDA !CurrentAction,x		;\ jump to current action
			JSL $0086DF			;/

.Pointers:		dw Start
			dw TeleportOut
			dw Gone
			dw TeleportIn
			dw Hurt
			dw Dead
			dw Waiting
			dw Spread
			dw Bomb
			dw Vials
			dw Aimed
			dw Drone
			dw Break
			dw Final
			dw Mushroom
			dw FallAndEnd

.Return			RTS

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

Start:			LDA !GenericTimer,x
			CMP #$50
			BCC .DontMove
			AND #$01
			BNE .DontMove

			LDA !RAM_SpriteYLo,x
			CLC
			ADC #$01
			STA !RAM_SpriteYLo,x
			LDA !RAM_SpriteYHi,x
			ADC #$00
			STA !RAM_SpriteYHi,x

.DontMove		LDA !GenericTimer,x
			BEQ .Next
			CMP #$34
			BEQ .Label1
			CMP #$2C
			BEQ .Label1
			CMP #$30
			BEQ .Label2
			CMP #$20
			BEQ .Label2			
			RTS

.Label1			LDA !GraphicsFrame,x
			EOR #$04
			STA !GraphicsFrame,x
			RTS

.Label2			INC !GraphicsFrame,x
			RTS

.Next			DEC $13FB
			LDA #!TimeTeleporting		;\ set time teleporting out
			STA !GenericTimer,x		;/
			INC !CurrentAction,x		; set next sprite action
			LDA #$10
			STA $1DF9

.Return			RTS

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

CountAppear:		LDA $14
			AND #$7F
			BNE .NoInc
			LDA !Count8Down
			EOR #$01
			STA !Count8Down
			STA $0DBF
			BNE .NoInc
			LDA !RAM_SpriteState,x
			CMP #$FF
			BEQ .NoInc
			JSR BobOmb
.NoInc			RTS

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

TeleportOut:		LDA !GraphicsFrame,x
			AND #$03
			STA !GraphicsFrame,x

			LDA !GenericTimer,x
			BNE .Return

			LDY !HitCounter,x
			LDA TimeGone,y
			STA !GenericTimer,x
			INC !CurrentAction,x
			STZ !AttackCounter,x
.Return			RTS

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

BobOmb:			LDY #$0B
.SpringLoop		TYA
			CMP #$FF
			BEQ .AddSpring
			LDA $14C8,y
			BEQ .NextCheck
			LDA $009E,y
			CMP #!DropperNbr
			BEQ .NoAdd
			CMP #!DropperNbr2
			BEQ .NoAdd
.NextCheck		DEY
			BRA .SpringLoop
.AddSpring		JSL $02A9DE
			BMI .NoAdd
			LDA #$08
			STA $14C8,y
		
			LDA !HitCounter,x
			AND #$01
			BEQ .ChangeDroppable
			LDA #!DropperNbr2
			STA $009E,y
			BRA .StoreDrop
.ChangeDroppable	LDA #!DropperNbr
			STA $009E,y

.StoreDrop		LDA $00E4,x
			STA $00E4,y
			
			LDA $00D8,x
			STA $00D8,y

			LDA $14E0,x
			STA $14E0,y

			LDA $14D4,x
			STA $14D4,y

			LDA #$88
			STA $7FAB10,x
			
			LDA #$13
			STA $1DF9

			PHX
			TYX
			JSL $07F7D2             ;  | ...and loads in new values for the 6 main sprite tables
             		PLX                     ; / \

			LDA #$40	
			STA $00AA,y

			LDA #$00
			STA $00B6,y

			LDA !HitCounter,x
			AND #$01
			BNE .NoAdd
                    	LDA #!TimeToExplode
                    	STA $1540,y 

.NoAdd			RTS	


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

Gone:			LDA !GenericTimer,x
			BNE .Return

			LDA #!TimeTeleporting
			STA !GenericTimer,x

			LDA !SpecialFlag,x
			BEQ .RandomTeleport

			LDA #$78
			STA !RAM_SpriteXLo,x
			LDA #$E0
			STA !RAM_SpriteYLo,x
			STZ !RAM_SpriteYHi,x
			BRA .Continue

.RandomTeleport		JSL $01ACF9
			LDA !RAM_RandomByte1
			EOR !RAM_MarioXPos
			EOR !RAM_MarioYPos
			PHA
			AND #$0F
			TAY
			LDA XPositions,y
			STA !RAM_SpriteXLo,x
			PLA
			LSR
			LSR
			LSR
			LSR
			TAY
			LDA YPositions,y
			STA !RAM_SpriteYLo,x
			LDA #$01
			STA !RAM_SpriteYHi,x

.Continue		INC !CurrentAction,x

			LDA #$10
			STA $1DF9

.Return			RTS		

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

TeleportIn:		LDA !SpecialFlag,x
			CMP #$02
			BNE .NotFinal

			LDA !GenericTimer,x
			AND #$10
			BNE .Continue

			LDA !GraphicsFrame,x
			EOR #$10
			STA !GraphicsFrame,x
			BRA .Continue

.NotFinal		LDA !GenericTimer,x
			CMP #$08
			BNE .Continue

			LDA !GraphicsFrame,x
			EOR #$04
			STA !GraphicsFrame,x
			RTS

.Continue		LDA !GenericTimer,x
			BNE .Return

			JSR DetermineAttack
			STA !CurrentAction,x

.Return			RTS

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

Hurt:			LDA !GenericTimer,x
			AND #$07
			BNE .DontChangeGraphics

			LDA !GraphicsFrame,x
			EOR #$04
			STA !GraphicsFrame,x

.DontChangeGraphics	LDA !GenericTimer,x		;\ if not time to exit hurt state,
			BNE .Return			;/ branch

			STZ !Count8Down
			JSR RemoveSpring
			LDA #$01
			STA !CurrentAction,x		; set next action (teleporting out)
			LDY !HitCounter,x
			LDA TimeToWait1,y
			STA !GenericTimer,x
			LDA #$10
			STA $1DF9
			LDA !HitCounter,x
			CMP #$04
			BEQ .TimeForMushroom
			CMP #$06
			BEQ .TimeForDrone
			CMP #$08
			BEQ .TimeForFinal
.Return			RTS

.TimeForMushroom	INC !SpecialFlag,x
.TimeForFinal		INC !SpecialFlag,x
.TimeForDrone		INC !SpecialFlag,x
			RTS

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

RemoveSpring:		LDY #$0B
.SpringLoop		TYA
			CMP #$FF
			BEQ .StopLoop
			LDA $14C8,y
			BEQ .NextCheck
			LDA $009E,y
			CMP #!DropperNbr
			BEQ .Remove
			CMP #!DropperNbr2
			BEQ .Remove
.NextCheck		DEY
			BRA .SpringLoop
.StopLoop		RTS	
.Remove			LDA #$04
			STA $14C8,y
			JSR DrawSmoke
			BRA .NextCheck


DrawSmoke:		LDY #$03                ; \ find a free slot to display effect
.Find			LDA $17C0,y             ;  |
			BEQ .Done	        ;  |
			DEY                     ;  |
 			BPL .Find	        ;  |
			RTS                     ; / return if no slots open

.Done 			LDA #$01                ; \ set effect graphic to smoke graphic
			STA $17C0,y             ; /
			LDA #$1B                ; \ set time to show smoke
			STA $17CC,y             ; /
			LDA $D8,x               ; \ smoke y position = generator y position
			STA $17C4,y             ; /
			LDA $E4,x               ; \ load generator x position and store it for later
			STA $17C8,y             ; /
			RTS

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

Dead:			LDA #$FF
			STA !RAM_SpriteState,x
			LDA !GenericTimer,x
			BEQ .DeadTimer
			CMP #$01
			BEQ .ExplodeEnd
			LDA !RAM_FrameCounterB
			AND #$03
			BNE .NoSmoke
			JSR RandomSmoke 
			LDA #$07
			STA $1DFC
			LDA !GraphicsFrame
			INC A
			AND #$03
			STA !GraphicsFrame
.NoSmoke		RTS
.DeadTimer		LDA #$80
			STA !GenericTimer,x
			RTS
.ExplodeEnd		LDA #$0F
			STA !CurrentAction,x
			RTS

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

FallAndEnd:		LDA !GenericTimer,x
			BEQ .FallTimer
			CMP #$01
			BEQ .EndPhase
			INC $AA,x
			JSL $01802A		; Apply speed.
			RTS
.FallTimer		LDA #$A0
			STA !GenericTimer,x
			LDA #$99
			STA $1686,x		; Objects don't affect this.
			LDA #$98
			STA $AA,x
			JSL $01802A		; Apply speed.
			RTS
.EndPhase		LDA #$0A
			STA $14C8,x             ; Destroy Sprite 
			;LDA #$1F
			;STA $1540,x
			LDA #$08
			STA $1DF9
			INC $13C6               ; Prevent Mario from walking.
			LDA #$FF                ; \ Set Goal
			STA $1493               ; /
			LDA #$0B                ; \ Set Ending Eusic
			STA $1DFB               ; /
			RTS                     ; return			

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

Waiting:		JSR MarioInteract

			LDA !GenericTimer,x
			BNE .Return
			LDA #!TimeTeleporting
			STA !GenericTimer,x
			LDA #$01
			STA !CurrentAction,x
			LDA #$10
			STA $1DF9

.Return			RTS

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

Bomb:			JSR MarioInteract

			LDA !GraphicsFrame,x
			EOR #$04
			STA !GraphicsFrame,x

			JSR DropBomb

			LDA #$06
			STA !CurrentAction,x
			LDY !HitCounter,x
			LDA TimeToWait2,y
			STA !GenericTimer,x
			RTS

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

Spread:			JSR MarioInteract

			LDA !AttackCounter,x
			CMP #$05
			BCC .Continue
			LDA #$06
			STA !CurrentAction,x
			LDY !HitCounter,x
			LDA TimeToWait2,y
			STA !GenericTimer,x
.Return			RTS

.Continue		LDA !GenericTimer,x
			BNE .Return

			LDA !AttackCounter,x
			BNE .DontChangeGraphics

			LDA !GraphicsFrame,x
			EOR #$04
			STA !GraphicsFrame,x

.DontChangeGraphics	LDA #$08
			STA !GenericTimer,x

			LDA #$27
			STA $1DFC

			LDY #$01

.LoopStart		PHY
			JSR FindClusterSlot
			BMI .LoopReturn

			LDA #!BulletNbr
			STA !RAM_ClusterSpriteNum,y

			LDA !RAM_SpriteXLo,x
			STA !RAM_ClusterXPosLo,y
			LDA !RAM_SpriteXHi,x
			STA !RAM_ClusterXPosHi,y

			LDA !RAM_SpriteYLo,x
			CLC
			ADC #!Gen_OffsetY
			STA !RAM_ClusterYPosLo,y
			LDA !RAM_SpriteYHi,x
			ADC #$00
			STA !RAM_ClusterYPosHi,y

			STY $00
			PLY
			PHY
			STY $01
			LDA !AttackCounter,x
			ASL
			CLC
			ADC $01
			TAY
			LDA .SpeedX,y
			PHY
			LDY $00
			STA !RAM_ClusterXSpeed,y
			PLY
			LDA .SpeedY,y
			LDY $00
			STA !RAM_ClusterYSpeed,y

			PHY
			PHX
			TYX
			LDA #$00
			STA !RAM_DirectionTimer,x
			PLX
			PLY

			PLY
			DEY
			BPL .LoopStart

			INC !AttackCounter,x
			RTS

.LoopReturn		PLY			
			INC !AttackCounter,x
			RTS

.SpeedX			db $04,$FC,$0B,$F4,$12,$EE,$17,$E9,$18,$E8
.SpeedY			db $18,$18,$15,$15,$0F,$0F,$08,$08,$00,$00

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

Cross:			JSR MarioInteract

			LDA !AttackCounter,x
			CMP #$03
			BCC .Continue
			LDA #$06
			STA !CurrentAction,x
			LDY !HitCounter,x
			LDA TimeToWait2,y
			STA !GenericTimer,x
.Return			RTS

.Continue		LDA !GenericTimer,x
			BNE .Return

			LDA !AttackCounter,x
			BNE .DontChangeGraphics

			LDA !GraphicsFrame,x
			EOR #$04
			STA !GraphicsFrame,x

.DontChangeGraphics	LDA #$10
			STA !GenericTimer,x

			LDA #$27
			STA $1DFC

			LDY #$03

.LoopStart		PHY
			JSR FindClusterSlot
			BMI .LoopReturn

			LDA #!BulletNbr
			STA !RAM_ClusterSpriteNum,y

			LDA !RAM_SpriteXLo,x
			STA !RAM_ClusterXPosLo,y
			LDA !RAM_SpriteXHi,x
			STA !RAM_ClusterXPosHi,y

			LDA !RAM_SpriteYLo,x
			CLC
			ADC #!Gen_OffsetY
			STA !RAM_ClusterYPosLo,y
			LDA !RAM_SpriteYHi,x
			ADC #$00
			STA !RAM_ClusterYPosHi,y

			STY $00
			PLY
			PHY
			LDA .SpeedX,y
			PHY
			LDY $00
			STA !RAM_ClusterXSpeed,y
			PLY
			LDA .SpeedY,y
			LDY $00
			STA !RAM_ClusterYSpeed,y

			PHY
			PHX
			TYX
			LDA #$00
			STA !RAM_DirectionTimer,x
			PLX
			PLY

			PLY
			DEY
			BPL .LoopStart

			INC !AttackCounter,x
			RTS

.LoopReturn		PLY			
			INC !AttackCounter,x
			RTS

.SpeedX			db $14,$EC,$14,$EC
.SpeedY			db $14,$14,$EC,$EC

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

Aimed:			JSR MarioInteract

			LDA !AttackCounter,x
			CMP #$04
			BCC .Continue
			LDA #$06
			STA !CurrentAction,x
			LDY !HitCounter,x
			LDA TimeToWait2,y
			STA !GenericTimer,x
.Return			RTS

.Continue		LDA !GenericTimer,x
			BNE .Return

			LDA !AttackCounter,x
			BNE .DontChangeGraphics

			LDA !GraphicsFrame,x
			EOR #$04
			STA !GraphicsFrame,x

.DontChangeGraphics	LDA #$20
			STA !GenericTimer,x

			LDA #$27
			STA $1DFC

			LDY #$02

.LoopStart		PHY
			JSR FindClusterSlot
			BMI .LoopReturn

			LDA #!BulletNbr
			STA !RAM_ClusterSpriteNum,y

			LDA !RAM_SpriteXLo,x
			STA !RAM_ClusterXPosLo,y
			LDA !RAM_SpriteXHi,x
			STA !RAM_ClusterXPosHi,y

			LDA !RAM_SpriteYLo,x
			CLC
			ADC #!Gen_OffsetY
			STA !RAM_ClusterYPosLo,y
			LDA !RAM_SpriteYHi,x
			ADC #$00
			STA !RAM_ClusterYPosHi,y

			STY $00
			PLY
			PHY
			STY $01
			LDA !AttackCounter,x
			AND #$01
			ASL
			ASL
			CLC
			ADC $01
			TAY
			LDA .SpeedX,y
			PHY
			LDY $00
			STA !RAM_ClusterXSpeed,y
			PLY
			LDA .SpeedY,y
			LDY $00
			STA !RAM_ClusterYSpeed,y

			PHY
			PHX
			TYX
			LDA #$20
			STA !RAM_DirectionTimer,x
			PLX
			PLY

			PLY
			DEY
			BPL .LoopStart

			INC !AttackCounter,x
			RTS

.LoopReturn		PLY			
			INC !AttackCounter,x
			RTS

.SpeedX			db $F6,$F1,$EE,$00,$0A,$0F,$12,$00
.SpeedY			db $EE,$F1,$F6,$00,$EE,$F1,$F6,$00

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

Vials:			JSR MarioInteract

			LDA !AttackCounter,x
			CMP #$03
			BCC .Continue
			LDA #$06
			STA !CurrentAction,x
			LDY !HitCounter,x
			LDA TimeToWait2,y
			STA !GenericTimer,x
.Return			RTS

.Continue		LDA !GenericTimer,x
			BNE .Return

			LDA !AttackCounter,x
			BNE .DontChangeGraphics

			LDA !GraphicsFrame,x
			EOR #$04
			STA !GraphicsFrame,x

.DontChangeGraphics	LDA #$20
			STA !GenericTimer,x

			LDA #$09
			STA $1DFC

			LDY !AttackCounter,x
			LDA .SpeedX,y
			STA $08
			STZ $09
			LDA #$02
			STA $0A
			JSR ThrowVial
			INC !AttackCounter,x

			RTS

.SpeedX			db $E0,$20,$00

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

Drone:			JSL $02A9DE			;\ get index for empty sprite slot
			BMI .DontSpawn			;/ if no empty slots, branch

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

			LDA !GraphicsFrame,x
			EOR #$04
			STA !GraphicsFrame,x

			LDA #$08			;\ set new sprite status
			STA $14C8,y			;/

			LDA !RAM_SpriteXLo,x		;\ set new sprite position
			STA.w !RAM_SpriteXLo,y		; |
			LDA !RAM_SpriteXHi,x		; |
			STA !RAM_SpriteXHi,y		; |
			LDA !RAM_SpriteYLo,x		; |
			CLC				; |
			ADC #!Gen_OffsetY		; |
			STA.w !RAM_SpriteYLo,y		; |
			LDA !RAM_SpriteYHi,x		; |
			ADC #$00			; |
			STA !RAM_SpriteYHi,y		;/

			LDA #!MiscSpriteNbr		;\ set new sprite number
			PHX				; |
			TYX				; |
			STA !RAM_CustSpriteNum,x	;/

			JSL $07F7D2			; clear out old sprite table values
			JSL $0187A7			; get table values for custom sprite
			LDA #$08			;\ mark sprite as custom
			STA !RAM_ExtraBits,x		;/
			PLX

			LDA #$04
			STA.w !RAM_SpriteState,y

.DontSpawn		LDA #$06
			STA !CurrentAction,x
			LDY !HitCounter,x
			LDA TimeToWait2,y
			STA !GenericTimer,x
			RTS

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

Mushroom:		STZ $08
			STZ $09
			LDA #$04
			STA $0A
			JSR ThrowVial

			LDA #$09
			STA $1DFC

			LDA #$06
			STA !CurrentAction,x
			LDY !HitCounter,x
			LDA TimeToWait2,y
			STA !GenericTimer,x
			RTS

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

Break:			RTS

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

Final:			JSR MarioInteract
			JSR BobOmb
			
			LDA !CurrentAction,x
			CMP #$05
			BEQ Break

			LDA !GenericTimer,x
			AND #$07
			BNE .Continue

			LDA !GraphicsFrame,x
			EOR #$10
			STA !GraphicsFrame,x

			JSR RandomSmoke

			LDA !RAM_SpriteYLo,x
			CMP #$20
			BEQ .Continue

			LDA !RAM_SpriteYLo,x
			CLC
			ADC #$01
			STA !RAM_SpriteYLo,x
			LDA !RAM_SpriteYHi,x
			ADC #$00
			STA !RAM_SpriteYHi,x

.Continue		LDA !GenericTimer,x
			BEQ .TimeToSpawn
			RTS

.TimeToSpawn		LDA #$12
			STA !GenericTimer,x
			LDA #$27
			STA $1DFC

			LDY #$01

.LoopStart		PHY
			JSR FindClusterSlot
			BMI .LoopReturn

			LDA #!BulletNbr
			STA !RAM_ClusterSpriteNum,y

			LDA !RAM_SpriteXLo,x
			STA !RAM_ClusterXPosLo,y
			LDA !RAM_SpriteXHi,x
			STA !RAM_ClusterXPosHi,y

			LDA !RAM_SpriteYLo,x
			CLC
			ADC #!Gen_OffsetY
			STA !RAM_ClusterYPosLo,y
			LDA !RAM_SpriteYHi,x
			ADC #$00
			STA !RAM_ClusterYPosHi,y

			STY $00
			PLY
			PHY
			STY $01
			LDA !AttackCounter,x
			ASL
			CLC
			ADC $01
			TAY
			LDA .SpeedX,y
			PHY
			LDY $00
			STA !RAM_ClusterXSpeed,y
			PLY
			LDA .SpeedY,y
			LDY $00
			STA !RAM_ClusterYSpeed,y

			PHX
			TYX
			LDA #$00
			STA !RAM_DirectionTimer,x
			PLX

			PLY
			DEY
			BPL .LoopStart
			BRA .MainDone

.LoopReturn		PLY
		
.MainDone		LDA !AttackCounter,x
			INC A
			AND #$0F
			STA !AttackCounter,x

			LDA !AttackCounter,x
			AND #$07
			BEQ .AdditionalAttack

			RTS

.AdditionalAttack	JSL $01ACF9
			EOR !RAM_MarioXPos
			EOR !RAM_MarioYPos
			AND #$0F
			TAY
			LDA .RandomAttacks,y
			BEQ .Homing
			CMP #$01
			BEQ .Bomb

			STZ $08
			STZ $09
			LDA #$02
			STA $0A
			JSR ThrowVial
			RTS

.Bomb			JSR DropBomb
			RTS

.Homing 		JSR FindClusterSlot
			BMI .Return

			LDA #!BulletNbr
			STA !RAM_ClusterSpriteNum,y

			LDA !RAM_SpriteXLo,x
			STA !RAM_ClusterXPosLo,y
			LDA !RAM_SpriteXHi,x
			STA !RAM_ClusterXPosHi,y

			LDA !RAM_SpriteYLo,x
			CLC
			ADC #!Gen_OffsetY
			STA !RAM_ClusterYPosLo,y
			LDA !RAM_SpriteYHi,x
			ADC #$00
			STA !RAM_ClusterYPosHi,y

			LDA #$00
			STA !RAM_ClusterXSpeed,y
			LDA #$20
			STA !RAM_ClusterYSpeed,y

			PHX
			TYX
			LDA #$30
			STA !RAM_DirectionTimer,x
			PLX

			LDA #$09
			STA $1DFC

.Return			RTS


.SpeedX			db $10,$F0,$0F,$F1,$0B,$F5,$06,$FA
			db $00,$00,$FA,$06,$F5,$0B,$F1,$0F
			db $F0,$10,$F1,$0F,$F5,$0B,$FA,$06
			db $00,$00,$06,$FA,$0B,$F5,$0F,$F1

.SpeedY			db $00,$00,$FA,$06,$F5,$0B,$F1,$0F
			db $F0,$10,$F1,$0F,$F5,$0B,$FA,$06
			db $00,$00,$06,$FA,$0B,$F5,$0F,$F1
			db $10,$F0,$0F,$F1,$0B,$F5,$06,$FA

.RandomAttacks		db $00,$01,$02,$00,$01,$02,$00,$01
			db $02,$00,$01,$02,$00,$01,$02,$00

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

DetermineAttack:	LDA !SpecialFlag,x
			CMP #$01
			BEQ .Drone
			CMP #$02
			BEQ .Final
			CMP #$03
			BEQ .Mushroom

			LDA !HitCounter,x
			CMP #$04
			BCS .RandomAttack

			CLC
			ADC #$07
			RTS

.RandomAttack		JSL $01ACF9
			LDA !RAM_RandomByte1
			EOR !RAM_MarioXPos
			EOR !RAM_MarioYPos
			AND #$03
			CLC
			ADC #$07
			RTS

.Mushroom		LDA #$0E
			STZ !SpecialFlag,x
			RTS

.Drone			LDA #$0B
			STZ !SpecialFlag,x
			RTS

.Final			LDA #$0D
			STZ !SpecialFlag,x
			RTS

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

ThrowVial:		JSL $02A9DE
			BMI .Return

			LDA #$08				;\ set sprite status
			STA $14C8,y				;/

			LDA !RAM_SpriteXLo,x			;\ set sprite x position
			STA.w !RAM_SpriteXLo,y			; |
			LDA !RAM_SpriteXHi,x			; |
			STA !RAM_SpriteXHi,y			;/

			LDA !RAM_SpriteYLo,x			;\ set sprite y position
			CLC					; |
			ADC #!Gen_OffsetY			; |
			STA.w !RAM_SpriteYLo,y			; |
			LDA !RAM_SpriteYHi,x			; |
			ADC #$00				; |
			STA !RAM_SpriteYHi,y			;/

			PHX

			TYX
			LDA #!VialNbr
			STA !RAM_CustSpriteNum,x		; Sprite number for the thrown vial
			JSL $07F7D2
			JSL $0187A7
			LDA #$0C
			STA !RAM_ExtraBits,x

			LDA $0A					;\ set potion type
			STA $1528,y				;/

			PLX

			LDA $08
			STA.w !RAM_SpriteSpeedX,y
			LDA $09
			STA.w !RAM_SpriteSpeedY,y

			LDA #$09
			STA $1DFC

.Return			RTS

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

DropBomb:		JSL $02A9DE			;\ get index for empty sprite slot
			BMI .Return			;/ if no empty slots, branch

			LDA #$08			;\ set new sprite status
			STA $14C8,y			;/

			LDA !RAM_SpriteXLo,x		;\ set new sprite position
			STA.w !RAM_SpriteXLo,y		; |
			LDA !RAM_SpriteXHi,x		; |
			STA !RAM_SpriteXHi,y		; |
			LDA !RAM_SpriteYLo,x		; |
			CLC				; |
			ADC #!Gen_OffsetY		; |
			STA.w !RAM_SpriteYLo,y		; |
			LDA !RAM_SpriteYHi,x		; |
			ADC #$00			; |
			STA !RAM_SpriteYHi,y		;/

			LDA #!MiscSpriteNbr		;\ set new sprite number
			PHX				; |
			TYX				; |
			STA !RAM_CustSpriteNum,x	;/

			JSL $07F7D2			; clear out old sprite table values
			JSL $0187A7			;  get table values for custom sprite
			LDA #$08			;\ mark sprite as custom
			STA !RAM_ExtraBits,x		;/
			PLX

			LDA #$00
			STA.w !RAM_SpriteState,y

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

.Return			RTS

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

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

.FoundSlot		LDA #$01			;\ set smoke image type
			STA $17C0,y			;/

			JSL $01ACF9			;\ set smoke image x position
			LDA !RAM_RandomByte1		; |
			AND #$1F			; |
			SEC				; |
			SBC #$10			; |
			CLC				; |
			ADC !RAM_SpriteXLo,x		; |
			STA $17C8,y			;/
			LDA !RAM_RandomByte2		;\ set smoke image y position
			AND #$0F			; |
			CLC				; |
			ADC !RAM_SpriteYLo,x		; |
			STA $17C4,y			;/

			LDA #$1B			;\ set time to display smoke image
			STA $17CC,y			;/

			RTS

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

MarioInteract:		;JSR CheckContact
			;BCC .HurtMario
			LDY #$07                	; 
.Loop			LDA $14C8,y             	; \ if the sprite status is..
			BEQ .NextSprite
			LDA $009E,y
			CMP #!DropperNbr		;
			BNE .NextSprite	
			LDA $00AA,y
			CMP #$80
			BCS .ProcessSprite
.NextSprite		DEY                     	;
			BPL .Loop                	; ...otherwise, loop
.BopHead		JSR CheckContact
			BCS .Return2	
			LDA !DisableContact,x
			BNE .Return2
			LDA !RAM_MarioSpeedY		;\ if Mario is moving upwards,
			CMP #$10			; |
			BMI .HurtMario			;/  branch
			JSR SubVertPos
			CPY #$00
			BEQ .HurtMario
			JSL $01AB99			; display contact graphic
			JSL $01AA33			; boost Mario upwards
			BRA .SkipSteps	    

.HurtMario		JSL $00F5B7			; hurt Mario
.Return2		RTS				; return
   
.ProcessSprite		PHX                     	; push x
			TYX                     	; transfer x to y
			JSL $03B6E5            	 	; get sprite clipping B routine
			PLX                     	; pull x
			JSL $03B69F             	; get sprite clipping A routine
			JSL $03B72B            	 	; check for contact routine
			BCC .NextSprite			;

.DecreaseHits		LDA #$08		    	; \ sprite status:
			STA $14C8,y		   	; / normal
			LDA #$08                	; \ makes it invincible
			STA $1686,y             	; / for other exploisons
			LDA #$1A                	; \ makes it invincible
			STA $167A,y            		; / for other exploisons, too
			LDA #$01		    	; \ make it
		    	STA $1534,y		    	; / explode
		    	LDA #$40		    	; \ set time for
		    	STA $1540,y		    	; / explosion
			JSL $01AB99			; display contact graphic
			;JSL $01AA33			; boost Mario upwards
.SkipSteps		LDA #$13			;\ play sound effect
			STA $1DF9			;/
			INC !HitCounter,x		; increase hits taken
			LDA !HitCounter,x		;\ if sprite is on its last hit,
			CMP #$08			; | branch
			BEQ .Final			;/
			CMP #$09			;\ if sprite has hitpoints left,
			BNE .NotDead			;/ branch
			LDA #$05			;\ set new action (dead)
			STA !CurrentAction,x		;/
			STZ !GenericTimer,x
			JSR EraseClusterSprites
			RTS

.Final			JSR KillDrone
			LDA !GraphicsFrame,x
			AND #$F8
			ORA #$03
			STA !GraphicsFrame,x

.NotDead		LDA !GraphicsFrame,x
			AND #$03
			ORA #$08
			STA !GraphicsFrame,x
			LDA #$04			;\ set action (hurt)
			STA !CurrentAction,x		;/
			LDA #$30			;\ set time to stay in hurt state
			STA !GenericTimer,x		;/
			STZ !RAM_SpriteSpeedY,x		;
			PLA
			PLA
.Return			RTS				; return

KillDrone:		PHX
			LDX #$09			; setup loop
.LoopStart		LDA $14C8,x			;\ if sprite non-existent,
			BEQ .Next			;/ branch
			LDA !RAM_CustSpriteNum,x
			CMP #!MiscSpriteNbr
			BNE .Next
			LDA !RAM_SpriteState,x
			CMP #$04
			BNE .Next
			LDA #$04			;\ set sprite status (killed by spinjump)
			STA $14C8,x			;/
			LDA #$1F			;\ set time to show smoke cloud
			STA $1540,x			;/
.Next			DEX				; decrease sprite index
			BPL .LoopStart			; if still sprites left to check, branch

			PLX
			RTS

EraseClusterSprites:	LDY #$13
			LDA #$00
.LoopStart		STA !RAM_ClusterSpriteNum,y
			DEY
			BPL .LoopStart

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

CheckContact:		LDA !RAM_SpriteXLo,x
			STA $02
			LDA !RAM_SpriteXHi,x
			STA $03

			LDA !RAM_SpriteYLo,x
			STA $04
			LDA !RAM_SpriteYHi,x
			STA $05

			REP #$20
			LDA !RAM_MarioXPos
			SEC
			SBC $02
			CLC
			ADC #$0018
			CMP #$0030
			BCS .Return

			LDA #$002C
			LDY !RAM_IsDucking
			BNE .Continue
			LDY !RAM_MarioPowerUp
			BEQ .Continue
			LDA #$0038

.Continue		STA $00
			LDA !RAM_MarioYPos
			SEC
			SBC $04
			CLC
			ADC #$0020
			CMP $00

.Return			SEP #$20
			RTS

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

OffsetX1:		db $F0,$00,$10,$F0,$00,$10
OffsetY1:		db $00,$00,$00,$10,$10,$10
Tilemap1:		db $8A,$8C,$8A,$A2,$A4,$A2,$FF,$FF
			db $8A,$8C,$8A,$A6,$A8,$A6,$FF,$FF
			db $8A,$8C,$8A,$AA,$CE,$AA,$FF,$FF
			db $8A,$8C,$8A,$86,$88,$86,$FF,$FF
Properties1:		db $00,$00,$40,$00,$00,$40

OffsetX2:		db $F8,$08
OffsetY2:		db $F0,$F0
Tilemap2:		db $08,$0A
			db $24,$26
			db $28,$2A
			db $48,$4A
			db $68,$6A
!Properties2		= $0D

OffsetX3:		db $F8,$08
OffsetY3:		db $F0,$F0
Tilemap3:		db $00,$02
			db $00,$02
			db $20,$02
			db $20,$02
			db $20,$22
			db $20,$22
			db $04,$06
			db $04,$06
			db $40,$42
			db $40,$42

SpriteGraphics:		LDA !CurrentAction,x		; check current action
			CMP #$01			;\ if teleporting out,
			BEQ .Check			;/ go to flicker check
			CMP #$02			;\ if gone,
			BEQ .Return0			;/ return
			CMP #$03			;\ if teleporting in,
			BEQ .Check			;/ go to flicker check
			;CMP #$04			;\ if hurt,
			;BEQ .Check			;/ go to flicker check
			CMP #$0F
			BNE .Continue
			JSR DeathSequence
.Return0		RTS

.Check			LDA !GenericTimer,x
			AND #$04
			BNE .Return0

.Continue		JSR GetDrawInfo
			STZ $03

; draw main part of capsule

			LDA !CurrentAction,x		; check current action
			CMP #$05			;\ if not dead,
			BNE .mainCap			;/ branch
			LDA !RAM_FrameCounterB
			AND #$07
			LSR
			BEQ .drawCroc

.mainCap		LDA !GraphicsFrame,x		;\ get index to tilemap table
			AND #$03			; |
			ASL				; |
			ASL				; |
			ASL				; |
			STA $02				;/

			PHX
			LDX #$05			; number of tiles to draw: 6

.LoopStart1		PHX				;\ set tile number
			TXA				; |
			CLC				; |
			ADC $02				; |
			TAX				; |
			LDA Tilemap1,x			; |
			STA !OAM_Tile,y			; |
			PLX				;/

			LDA $00				;\ set tile x position
			CLC				; |
			ADC OffsetX1,x			; |
			STA !OAM_DispX,y		;/
			LDA $01				;\ set tile y position
			CLC				; |
			ADC OffsetY1,x			; |
			STA !OAM_DispY,y		;/
			PHX
			LDX $15E9			;\ set tile properties
			LDA $15F6,x			; |
			PLX				; |
			ORA Properties1,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 $03				; increase number of tiles drawn

			DEX				; decrease loop counter
			BPL .LoopStart1			; if more tiles left to draw, branch

; draw Doc

			PLX
.drawCroc		;LDA !CurrentAction,x		; check current action
			;CMP #$05			;\ if dead,
			;BEQ .SkipDoc			;/ branch

			LDA !GraphicsFrame,x		;\ get index to tilemap table
			AND #$3C			; |
			LSR				; |
			STA $02				;/

			PHX
			LDX #$01			; number of tiles to draw: 2

.LoopStart2		PHX				;\ set tile number
			TXA				; |
			CLC				; |
			ADC $02				; |
			TAX				; |
			LDA Tilemap2,x			; |
			STA !OAM_Tile,y			; |
			PLX				;/

			LDA $00				;\ set tile x position
			CLC				; |
			ADC OffsetX2,x			; |
			STA !OAM_DispX,y		;/
			LDA $01				;\ set tile y position
			CLC				; |
			ADC OffsetY2,x			; |
			STA !OAM_DispY,y		;/
			LDA #!Properties2		;\ set tile properties
			ORA $64				; |
			STA !OAM_Prop,y			;/

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

			INC $03				; increase number of tiles drawn

			DEX				; decrease loop counter
			BPL .LoopStart2			; if more tiles left to draw, branch

; draw glass bubble

			PLX
.SkipDoc		
			LDA !CurrentAction,x		; check current action
			CMP #$05			;\ if not dead,
			BNE .glassBubble		;/ branch
			LDA !RAM_FrameCounterB
			AND #$07
			LSR
			BEQ .endGraphics
			LDA !HitCounter,x		;\ get index to tilemap table
			ASL				; |
			STA $02				;/

.glassBubble		PHX
			LDX #$01			; number of tiles to draw: 2

.LoopStart3		PHX				;\ set tile number
			TXA				; |
			CLC				; |
			ADC $02				; |
			TAX				; |
			LDA Tilemap3,x			; |
			STA !OAM_Tile,y			; |
			PLX				;/

			LDA $00				;\ set tile x position
			CLC				; |
			ADC OffsetX3,x			; |
			STA !OAM_DispX,y		;/
			LDA $01				;\ set tile y position
			CLC				; |
			ADC OffsetY3,x			; |
			STA !OAM_DispY,y		;/
			PHX
			LDX $15E9			;\ set tile properties
			LDA $15F6,x			; |
			PLX				; |
			ORA $64				; |
			STA !OAM_Prop,y			;/

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

			INC $03				; increase number of tiles drawn

			DEX				; decrease loop counter
			BPL .LoopStart3			; if more tiles left to draw, branch

			PLX

.endGraphics		LDA $03				; number of tiles drawn
			LDY #$02			; the tiles drawn were 16x16
			JSL $01B7B3			; finish OAM write
			
.Return			RTS				; return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Death Sequence
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

XDISP:			db $F8,$08,$F8,$08
YDISP:			db $00,$00,$10,$10
DEATH_SEQ_UP:		db $44,$46,$64,$66
DEATH_SEQ_DOWN:		db $64,$66,$44,$46


DeathSequence:		JSR GetDrawInfo
			STZ $03
			LDA $AA,x
			STA $04
			PHX			;\ Push sprite index ..
			LDX #$03		;/ And load X with number of tiles to loop through.
.LoopDeath		LDA $00			;\
			CLC			; | Apply X displacement of the sprite.
			ADC XDISP,x		; |
			STA $0300,y		;/ 
			LDA $01			;\
			CLC			; | Y displacement is added for the Y position, so one tile is higher than the other.
			ADC YDISP,x		; | Otherwise, both tiles would have been drawn to the same position!
			STA $0301,y		; | If X is 00, i.e. first tile, then load the first value from the table and apply that
						;/ as the displacement. For the second tile, F0 is added to make it higher than the first.
			LDA $04
			CMP #$80
			BCC .DownTiles
			LDA DEATH_SEQ_UP,x
			STA $0302,y
			BRA .EndTiles
.DownTiles		LDA DEATH_SEQ_DOWN,x
			STA $0302,y
		
.EndTiles		LDA $04
			CMP #$80
			BCC .DownFall
			LDA #$0D
			STA $0303,y	
			BRA .EndDown
.DownFall		LDA #$8D		
			STA $0303,y		
.EndDown		INY			;\
			INY			; | The OAM is 8x8, but our sprite is 16x16 ..
			INY			; | So increment it 4 times.
			INY			
			DEX			

			BPL .LoopDeath		; Loop until X becomes negative (FF).
			PLX			; Pull back the sprite index! We pushed it at the beginning of the routine.
			LDY #$02		; Y ends with the tile size .. 02 means it's 16x16
			LDA #$03		; A -> number of tiles drawn - 1.
						; I drew 2 tiles, so 2-1 = 1. A = 01.

			JSL $01B7B3		; Call the routine that draws the sprite.
			RTS			; Never forget this!	

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; routine for finding a free cluster sprite slot
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

FindClusterSlot:	LDY #$13
.LoopStart		LDA !RAM_ClusterSpriteNum,y
			BEQ .Return
			DEY
			BPL .LoopStart
.Return			RTS			

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B760 - graphics routine helper - shared
; sets off screen flags and sets index to OAM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;org $03B75C

Table1:			db $0C,$1C
Table2:			db $01,$02

GetDrawInfo:		STZ $186C,x			; reset sprite offscreen flag, vertical
			STZ $15A0,x			; reset sprite offscreen flag, horizontal
			LDA $E4,x			;\
			CMP $1A				; | set horizontal offscreen if necessary
			LDA $14E0,x			; |
			SBC $1B				; |
			BEQ OnScreenX			; |
			INC $15A0,x			;/

OnScreenX:		LDA $14E0,x			;\
			XBA				; |
			LDA $E4,x			; |
			REP #$20			; |
			SEC				; |
			SBC $1A				; | mark sprite invalid if far enough off screen
			CLC				; |
			ADC #$0040			; |
			CMP #$0180			; |
			SEP #$20			; |
			ROL A				; |
			AND #$01			; |
			STA $15C4,x			;/
			BNE Invalid			;
			
			LDY #$00			;\ set up loop:
			LDA $1662,x			; |
			AND #$20			; | if not squished (1662 & 0x20), go through loop twice
			BEQ OnScreenLoop		; | else, go through loop once
			INY				;/
OnScreenLoop:		LDA $D8,x			;\
			CLC				; | set vertical offscreen if necessary
			ADC Table1,y			; |
			PHP				; |
			CMP $1C				; | (vert screen boundry)
			ROL $00				; |
			PLP				; |
			LDA $14D4,x			; |
			ADC #$00			; |
			LSR $00				; |
			SBC $1D				; |
			BEQ OnScreenY			; |
			LDA $186C,x			; | (vert offscreen)
			ORA Table2,y			; |
			STA $186C,x			; |
OnScreenY:		DEY				; |
			BPL OnScreenLoop		;/

			LDY $15EA,x			; get offset to sprite OAM
			LDA $E4,x			;\
			SEC				; | 
			SBC $1A				; | $00 = sprite x position relative to screen border
			STA $00				;/
			LDA $D8,x			;\
			SEC				; | 
			SBC $1C				; | $01 = sprite y position relative to screen border
			STA $01				;/
			RTS				; return

Invalid:		PLA				;\ return from *main gfx routine* subroutine...
			PLA				; |    ...(not just this subroutine)
			RTS				;/

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B817 - horizontal mario/sprite check - shared
; Y = 1 if mario left of sprite??
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;org $03B817        

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


SubVertPos:		LDY #$00
			LDA $96
			CLC
			ADC #$1C
			SEC
			SBC $D8,x
			STA $0F
			LDA $97
			SBC $14D4,x
			BPL .Return
			INY
.Return			RTS