;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SMWCP2 - World 3 Boss
;; made by MetalJo
;; replace the freeram defines with 
;; unused free ram
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Defines 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	!HP 		= $02	
	!SFXA		= $10
	!BankA		= $1DF9
	!SpriteNumber	= $7B ;was B1
	!SpriteNumber2	= $10
	!SpriteNumber3 	= $1A
	!FreeRam 	= $0F7F
	!FreeRam2 	= $0F7E
	!ExtraBit	= $7FAB10
	!AttackCounter	= $7F888C

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Tables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	XAcc:           db $01,$FF
	XSpd:	     	db $10,$F0	
	Speed:		db $F0,$00,$20,$00

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Init and Main Codes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

print "INIT ",pc		
	LDA #$01
	STA $157C,x
	STZ !FreeRam2 
	LDA #$00
	STA !AttackCounter
	LDA #!HP : STA $1528,x		; set hp
	RTL				; return
	
print "MAIN ",pc				
	PHB : PHK : PLB				
	JSR MainCode			; jump to the label called maincode
	PLB : RTL			
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Main Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MainCode:
	JSR HandleGFX
	LDA $9D
	BNE Return
	JSR SUB_OFF_SCREEN_X0
	JSR Hit_Detect
	JSR Pointers				; Jump to the Pointers Code
Return:
	RTS
	
Pointers:
	LDA $C2,x : JSL	$0086DF		; handle the state thingy
	dw S0_Appear			; 00 - Appears on the left of the Screen
	dw S1_Idle			; 01 - Ideling (between Attacks)
	dw S2_Leaf			; 02 - Throwing a leaves at Mario
	dw S3_StatueA			; 03 - Teleports to an upper part of the screen
	dw S4_StatueB			; 04 - crashes down to the bottem (stays like this for a moment
	dw S5_StatueC
	dw S6_StatueD			; 06 - Statue breaks a little bit
	dw S7_BreakStatue		; 07 - Statue breaks with the crumbling effect and a piece of the statue is spawn 
	dw S8_Trans_HB			; 08 - Transforms into a hammerbrolike sprite
	dw S9_Stones			; 09 - Transforms into a sprite that acts like Mario
	dw SA_Transform_K		; 0A - Transforms into a Koopa
	dw SB_KillKoopa			; 0B - Kill the koopa and spawn a shell
	dw SC_DashAtMario		; 0C - Creates the rotoleaf that acts like a little bit like a roto disc 
	dw SD_Hurt			; 0D - 
	dw SE_Die			; 0E - dies and ends the level
	dw SF_Stunned			; 0F - After beating transformation
	dw S10_Hurt_Stun
	dw ReturnState
	dw S12_Prepare
	dw S13_PrepareB
	dw S14_SpinRight
	dw S15_Wait
	dw S16_Down
	dw S17_ShockWave
	dw S18_End
	dw S19_Important
	dw S1A_Imp2
	dw S1B_Thwomp
	dw S1C_SmashUp
	dw S1D_FallDown	
	dw S1E_IdleGround
	dw S1F_DashAtMario2
	dw S20_Walk
	dw s21_Reappear
	RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Appear
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

S0_Appear:
	JSR WavyMotion
	LDA #$08
	STA $AA,x
	STZ $B6,x
	JSL $01802A            
	LDA $1588,x
	AND #$04
	BEQ .Return
	LDA #$10
	STA $1DF9
	JSR Smoke
	INC $C2,x
.Return
	RTS
WavyMotion:
	PHY ; Push Y in case something messes it up.
	LDA $14 ; Get the sprite frame counter ..
	LSR A ; 7F
	LSR A ; 3F ; Tip: LSR #3.
	LSR A ; 1F
	AND #$07 ; Loop through these bytes during H-Blank. (WHAT?)
	TAY ; Into Y.
	LDA WavySpd,y ; Load Y speeds ..
	STA $B6,x
	JSL $01801A ; Update, with no gravity.
	PLY ; Pull Y.
	RTS

WavySpd: db $00,$F8,$F2,$F8,$00,$08,$0E,$08	

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Set Shell Hit Detection
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Hit_Detect:	LDA $C2,x
		CMP #$21
		BEQ .return
		CMP #$11
		BEQ .return
		CMP #$10
		BEQ .return
		CMP #$0F
		BEQ .return
		CMP #$1A
		BEQ .return
		CMP #$01
		BNE Destroy_Shell
		JSR Con
		JSR ThrowBlockContact
.return		RTS

Destroy_Shell:	LDY #$0B                ; 
DS_Loop:	LDA $14C8,y             ; \ if the sprite status is..
		BEQ DN_Sprite
		LDA $009E,y
		CMP #$04		;
		BNE DN_Sprite	
		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 DN_Sprite		;
		LDA #$02
		STA $14C8,y
		LDA #$08
		STA $1DF9
		RTS
DN_Sprite:	DEY                     ;
		BPL DS_Loop		; ...otherwise, loop
		RTS                     ; return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Idle
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

s21_Reappear:	STZ $151C,x
		LDA $163E,x
		BEQ s21_setTimer
		CMP #$01
		BEQ s21_regIdle
		RTS
s21_setTimer:	LDA #$60
		STA $163E,x
		LDA #$D0 : STA $E4,x
		LDA #$70 : STA $D8,x
		LDA #$01 : STA $14D4,x 
		RTS
s21_regIdle:	LDA #$01
		STA $C2,x
		RTS

NEXT_STATE:	db $02,$12,$06,$20,$02,$12,$06,$0A
S1_Idle:	STZ $151C,x
		LDA $163E,x
		BEQ S1_SetTimer
		CMP #$01
		BEQ S1_Random
		RTS
S1_SetTimer:	LDA #$51
		STA $163E,x
		LDA #$D0 : STA $E4,x
		LDA #$70 : STA $D8,x
		LDA #$01 : STA $14D4,x 
		RTS
S1_Random:	LDA !AttackCounter
		AND #$07
		TAY
		LDA NEXT_STATE,y	; \ set sprite number for new sprite\
		STA $C2,x
		JSR S1_IncAtt
		RTS

S1_IncAtt:	LDA !AttackCounter
		CLC
		ADC #$01
		STA !AttackCounter
		RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Leaf
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

S2_Leaf:
	LDA $151C,x
	CMP #$04
	BEQ NE
	JSR Con
	LDA $163E,x
	BNE .t
	LDA #$21
	STA $163E,x
	RTS
.t
	LDA $163E,x
	CMP #$01
	BNE .ret
	LDA #$30
	STA $1DFC
	JSR S2_Spawn
	INC $151C,x
.ret
	RTS
NE:
	STZ $151C,x
	LDA #$01
	STA $C2,x
	RTS
S2_Spawn:
	LDA $186C,x
	BNE EndSpawn
	JSL $02A9DE
	BMI EndSpawn
	LDA #$01				; Sprite state ($14C8,x).
	STA $14C8,y
	PHX
	TYX
	LDA #!SpriteNumber	; This the sprite number to spawn.
	STA $7FAB9E,x
	PLX
	LDA #$D0
	STA $00E4,y
	LDA $14E0,x
	STA $14E0,y
	LDA $D8,x
	SEC
	SBC #$10
	STA $00D8,y
	LDA $14D4,x
	STA $14D4,y
	PHX
	TYX
	JSL $07F7D2
	JSL $0187A7
	LDA #$08
	STA $7FAB10,x
	PLX
	LDA #$30
	JSR CODE_01BF6A
	LDX $15E9
	LDA $00
	STA $00AA,y
	LDA $01
	STA $00B6,y
EndSpawn:
	RTS
Spd_Leaf:
	db $00,$FF,$F9,$FC,$EF

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Statue Codes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LookAtMario:
	LDA $76
	BEQ LookLeft
	STZ $157C,x
	RTS
LookLeft:
	LDA #$01
	STA $157C,x
	RTS
; 1st Part 
S3_StatueA:
	JSR Con
	LDA $E4,x
	STA $1504,x
	LDA $D8,x
	STA $1510,x
	LDA #$03
	STA $AA,x
	JSL $01802A
	JSR ThrowBlockContact
	LDA #$10
	STA $1DF9
	LDA $94
	CMP #$D0
	BCS St
	CMP #$10
	BCC St
	LDA $94
	STA $E4,x
	BRA AX
St:
	LDA $1504,x
	STA $E4,x
	LDA $1510,x
	STA $D8,x
AX:
	LDA $163E,x
	BNE S3_Timer
	LDA #$4B
	STA $163E,x
	RTS
S3_Timer:
	LDA $163E,x
	CMP #$21 : BEQ .SFX
	CMP #$11 : BEQ .SFX
	CMP #$01 : BEQ S3_Next
	JSR LookAtMario
	RTS
.SFX
	LDA #$01
	STA $1DFC
	RTS
S3_Next:
	LDA #$01
	STA $157C,x
	LDA #$10
	STA $1DF9
	JSR Smoke
	PHX
	LDA #$01
	JSL RANDOM
	TAX
	LDA RandomAttacksB,x	; \ set sprite number for new sprite
	PLX
	STA $C2,x
	RTS
	
; 2nd Part 

S4_StatueB:
	LDA #$01
	STA $157C,x
	JSR Con
	LDA #$23
	STA $1DF9
	JSR ThrowBlockContact
	STZ $00B6,x
	LDA #$34
	STA $00AA,x
	JSL $01802A 
	LDA $1588,x
	AND #$04
	BNE Earthquake
	RTS
Earthquake:
	LDA #$09
	STA $1DFC
	INC $C2,x
	RTS

; 3rd part

S5_StatueC:
	LDA $14
	AND #$3F
	BNE .return
	JSR ROCKSPAWN
.return
	JSR StatueCon
	JSR ThrowBlockContact
	RTS
	
; 4th part

S6_StatueD:
	JSR Con
	LDA $94
	STA $E4,x
	LDA #$10
	STA $D8,x
	LDA #$01
	STA $14D4,x
	LDA #$03 
	STA $C2,x
	RTS

; 5th Part

S7_BreakStatue:
	LDA $14
	AND #$3F
	BNE .return
	JSR ROCKSPAWN
.return
	JSR StatueCon
	LDA !FreeRam
	CMP #$02
	BEQ S7_Next
	RTS
S7_Next:
	STZ $1887
	STZ !FreeRam
	LDA #$10
	STA $1DF9
	JSR Smoke
	LDA #$21 : STA $C2,x
	RTS
RandomAttacksB:
db $1B,$04

S1B_Thwomp:
	JSR ThwompCon
	LDA #$01
	STA $157C,x
	JSR ThrowBlockContact
	STZ $00B6,x
	LDA #$34
	STA $00AA,x
	JSL $01802A 
	LDA $1588,x
	AND #$04
	BNE .Ground
	RTS
.Ground
	LDA $163E,x
	BNE .Timer
	LDA #$41
	STA $163E,x
	RTS
.Timer
	LDA $163E,x
	CMP #$40 : BEQ SFX
	CMP #$01 : BEQ .Next
	RTS
.Next
	INC $C2,x
	RTS
SFX:
	LDA #$09
	STA $1DFC
	RTS
S1C_SmashUp:
	JSR ThwompCon
	LDA #$CB
	STA $00AA,x
	JSL $01802A 
	LDA $14D4,x
	BNE .Return
	LDA $D8,x
	CMP #$F0
	BCS .Return
	;JSR Quake
	LDA #$09
	STA $1DFC
	INC $C2,x
.Return
	RTS
S1D_FallDown:
	JSR ThwompCon
	LDA #$01
	STA $157C,x
	JSR ThrowBlockContact
	STZ $00B6,x
	LDA #$34
	STA $00AA,x
	JSL $01802A 
	LDA $1588,x
	AND #$04
	BNE .Ground
	RTS
.Ground
	LDA #$16
	STA $1DFC
   	LDA #$18
    	STA $1887 
	LDA $77
    	AND #$04
    	BEQ NoLockM2
    	LDA #$20      ; set timer to freeze mario
    	STA $18BD
NoLockM2:
    	LDA #$A0     ;set time to stay on ground
    	STA $1540,x
	JSR Shoot
	JSR ShootB
	INC $C2,x
	RTS

S1E_IdleGround:
	JSR ThwompCon
	LDA $163E,x
	BNE .timer
	LDA #$81
	STA $163E,x
	RTS
.timer
	LDA $163E,x
	CMP #$01
	BNE .return
	LDA #$0F
	STA $C2,x
.return
	RTS

ShootB:
	LDA $186C,x
	BNE EndSpawn32
	JSL $02A9DE
	BMI EndSpawn32
	LDA #$01				; Sprite state ($14C8,x).
	STA $14C8,y
	PHX
	TYX
	LDA #!SpriteNumber	; This the sprite number to spawn.
	STA $7FAB9E,x
	PLX
	LDA $E4,x
	STA $00E4,y
	LDA $14E0,x
	STA $14E0,y
	LDA $D8,x
	STA $00D8,y
	LDA $14D4,x
	STA $14D4,y
	PHX
	TYX
	JSL $07F7D2
	JSL $0187A7
	LDA #$08
	STA $7FAB10,x
	PLX
	LDA #$02
	STA $1594,y
EndSpawn32:
	RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Hammerbrother Transformation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
S20_Walk:	LDA $E4,x
		CMP #$78
		BCC S20_Trans
		LDA #$F0
		STA $B6,x
		JSL $01802A
		RTS
S20_Trans:	LDA #$08 : STA $C2,x
		RTS

S8_Trans_HB:	JSR Check_HB
		INC $163E,x
		LDA $163E,x
		CMP #$01
		BEQ Spawn_HB
.No_Trans	RTS

Check_HB:	PHX
		LDX #$0B
HB_Loop:	CPX #$FF
		BEQ End_Check
		LDA $7FAB9E,x
		CMP #!SpriteNumber2
		BNE Dec_Check
		LDA $14C8,x
		;BEQ Dec_Check
		CMP #$08
		BEQ Check_Shell
		PLX
		INC !FreeRam
		LDA #$11
		STA $C2,x
		RTS
Dec_Check:	DEX
		BRA HB_Loop 
End_Check:	PLX
		RTS		
Check_Shell:	PLX
		JSR Stop_Shell
		RTS

Stop_Shell:	LDY #$0B                ; 
SS_Loop:	LDA $14C8,y             ; \ if the sprite status is..
		BEQ N_Sprite
		LDA $009E,y
		CMP #$04		;
		BNE N_Sprite	
		LDA $00B6,y
		BEQ N_Sprite
		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 N_Sprite		;
		INC !FreeRam
		LDA #$11
		STA $C2,x
		RTS
N_Sprite:	DEY                     ;
		BPL SS_Loop		; ...otherwise, loop
		RTS                     ; return

Spawn_HB:	STZ !FreeRam
		INC $163E,x
		JSL $02A9DE
		BMI .EndSpawn
		LDA #$01		; Sprite state ($14C8,x).
		STA $14C8,y
		PHX
		TYX
		LDA #!SpriteNumber2	; This the sprite number to spawn.
		STA $7FAB9E,x
		PLX
		LDA #$78
		STA $00E4,y
		LDA $14E0,x
		STA $14E0,y
		LDA #$70
		STA $00D8,y
		LDA $14D4,x
		STA $14D4,y
		PHX
		TYX
		JSL $07F7D2
		JSL $0187A7
		LDA #$08
		STA $7FAB10,x
		PLX
.EndSpawn	RTS

S1A_Imp2:
	LDA #$D0 : STA $E4,x
	LDA #$70 : STA $D8,x
	LDA $163E,x
	BNE .Timer
	LDA #$07
	STA $163E,x
	RTS
.Timer
	LDA $163E,x
	CMP #$01
	BNE .Return
	LDA #$21	;#$01
	STA $C2,x
.Return
	RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Stones
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

S9_Stones:
	JSR Con
	LDA $163E,x
	BNE .Timer
	LDA #$F1
	STA $163E,x
	RTS
.Timer
	LDA $163E,x
	CMP #$D1
	BEQ ROCK
	CMP #$A1
	BEQ ROCK
	CMP #$71
	BEQ ROCK
	CMP #$41
	BEQ ROCK
	CMP #$21
	BEQ ROCK
	CMP #$01
	BEQ .Next
	RTS
.Next
	LDA #$10
	STA $1DF9
	JSR Smoke
	LDA #$1A
	STA $C2,x
	RTS
ROCK:
	JSR ROCKSPAWN
	RTS
ROCKSPAWN:
	LDA $1887
	BNE .noquake
	LDA #$FF
	STA $1887
.noquake
	LDA #$23
	STA $1DF9
	LDA $186C,x
	BNE EndSpawn34
	JSL $02A9DE
	BMI EndSpawn34
	LDA #$01				; Sprite state ($14C8,x).
	STA $14C8,y
	PHX
	TYX
	LDA #!SpriteNumber	; This the sprite number to spawn.
	STA $7FAB9E,x
	PLX
	LDA $94
	STA $00E4,y
	LDA $95
	STA $14E0,y
	LDA #$C0
	STA $00D8,y
	LDA #$00
	STA $14D4,y
	PHX
	TYX
	JSL $07F7D2
	JSL $0187A7
	LDA #$08
	STA $7FAB10,x
	PLX
	LDA #$03
	STA $1594,y
EndSpawn34:
	RTS
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Koopa Transform
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

XSpeedKoopa:
db $08,$F8		

SA_Transform_K:
	JSR KoopaCon
	LDA $1588,x             
	AND #$03                
	BEQ NoObjKoopa
Flip:
	LDA $157C,x             
	EOR #$01                
	STA $157C,x             
NoObjKoopa:
	LDY $157C,x             
	LDA XSpeedKoopa,y           
	STA $B6,x 
	JSR KoopaJump
	JSL $01802A
	LDA $E4,x
	CMP #$15
	BCC Flip
	CMP #$E8
	BCS Flip
	RTS	
	
ShellSpd: db $18,$E8
SB_KillKoopa:
	LDA #$10
	STA $1DF9
	JSR Smoke
	JSR Shell
	LDA #$0F : STA $C2,x
	RTS
Shell:
	LDA $186C,x
	BNE .EndSpawn
	JSL $02A9DE
	BMI .EndSpawn
	LDA #$09
	STA $14C8,y
	LDA #$04
	STA $009E,y
	LDA $E4,x
	STA $00E4,y
	LDA $14E0,x
	STA $14E0,y
	LDA $D8,x
	STA $00D8,y
	LDA $14D4,x
	STA $14D4,y
	PHX
	TYX
	JSL $07F7D2
	PLX
    PHY                   
    LDA $157C,x
    TAY
    LDA ShellSpd,y
    PLY
    STA $00B6,y
    LDA #$C0
    STA $00AA,y  
.EndSpawn
	RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dash at Mario
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SC_DashAtMario:
	LDA #$1F
	STA $C2,x
	RTS
S1F_DashAtMario2:
	LDA $1588,x
	CMP #$04
	BNE BLA
	
	LDA $1510,x
	STA $AA,x
	LDA $1504,x
	STA $B6,x
	BRA BLABLA
	
BLA:
	JSR Con
	STZ $AA,x
	LDA #$A8	;#$C0
	STA $B6,x
BLABLA:
	JSL $01802A
	
	LDA $1588,x
	AND #$02
	BEQ .Return
	LDA #$09
	STA $1DFC
	STA $C2,x
.Return
	RTS


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Jumping upwards
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SD_Hurt:	STZ $B6
		LDA $163E,x
		BNE .Timer
		LDA #$40
		STA $163E,x
		RTS
.Timer		LDA $163E,x
		CMP #$01
		BNE .Return
		LDA #$21 : STA $C2,x
.Return		RTS
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dieing
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SE_Die:		STZ $151C,x
		LDA $163E,x
		BEQ .setTimer
		CMP #$01
		BEQ .setEndFlag
 		JSR RandomSmoke
		RTS
.setTimer	LDA #$80
		STA $163E,x
		RTS
.setEndFlag	LDA #$18
		STA $C2,x
		RTS

XTable:		db $30,$E0,$20,$40,$B0,$60,$A0,$78
YTable:		db $30,$60,$70,$28,$68,$55,$20,$00
RandomSmoke:	LDY #$03		; \ find a free slot to display effect
FINDFREE2:	LDA $17C0,y		;  |
		BEQ FOUNDONE2		;  |
		DEY                     ;  |
		BPL FINDFREE2		;  |
		RTS			; / return if no slots open
FOUNDONE2:	PHX
		JSR $01ACF9
		LDA $148D
		AND #$07
		TAX
		;LDA $1594,x
		;TAX
		LDA #$01                ; \ set effect graphic to smoke graphic
		STA $17C0,y             ; /
		LDA #$1B                ; \ set time to show smoke
		STA $17CC,y             ; /
		LDA YTable,x             
		STA $17C4,y             ; /
		LDA XTable,x             			; \ load generator x position and store it for later
		STA $17C8,y             ; /
		PLX
		RTS

S18_End:	LDA #$30
		STA $1DFC
		LDA #$80
		STA $1DFB
		LDA #$FF
		STA $1493 ; activate "end level" flag
		LDA #$00
		STA $141C ; normal path
		LDA #$0B
		STA $71
		RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Stun Codes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
SF_Stunned:	LDA #$10
		STA $1DF9
		LDA $163E,x
		BEQ SF_Timer
		CMP #$01
		BEQ SF_Next
		RTS
SF_Timer:	LDA #$41
		STA $163E,x
		RTS
SF_Next:	LDA #$10
		STA $1DF9
		STZ $163E,x
		LDA #$1A : STA $C2,x
		RTS
	
S10_Hurt_Stun:	JSR NewCon
		LDA $1558,x
		BEQ S10_T
		CMP #$01
		BEQ S10_N
		RTS
S10_T:		LDA #$81
		STA $1558,x	
		RTS
S10_N:		STZ $163E,x
		LDA #$21
		STA $C2,x
		RTS
NewCon:
	JSL $03B664					; check for contact
   	JSR GetSpriteClipping		; jump to clipping routine
   	JSL $03B72B					; clipping subroutine					
	BCC .Return    
	LDA $154C,x             
	BNE .Return        
	LDA #$08                
	STA $154C,x             
	LDA $7D                 
	CMP #$10               
	BMI .SprWins            
	JSL $01AA33             
	JSL $01AB99
	LDA #$28               
    STA $1DFC
	LDA #$02
	STA $1DF9
	DEC $1528,x 
	LDA #$0D
	STA $C2,x
	LDA $1528,x
	BEQ Die
.Return
	RTS
.SprWins
	LDA $1497               
	ORA $187A               
	BNE .Return        
	JSR SUB_HORZ_POS        
	TYA                    
	STA $157C,x             
	JSL $00F5B7             
	RTS
Die:
	LDA #$0E : STA $C2,x
	RTS

ThwompCon:
	JSL $03B664					; check for contact
   	JSR GetSpriteClippingThwomp		; jump to clipping routine
   	JSL $03B72B	
	BCC .Return
	LDA $154C,x             
	BNE .Return     
	LDA #$08                
	STA $154C,x             
	LDA $7D                 
	CMP #$10               
	BMI SprWins    
	JSR Check
.Return
	RTS
Check:
	LDA $140D
	BEQ Hurt
	LDA #$AF
	STA $7D
	JSL $01AA33             
	JSL $01AB99  
	LDA #$02
	STA $1DF9
	RTS
SprWins:
	LDA $1497               
	ORA $187A               
	BNE ReturnC      
	JSR SUB_HORZ_POS        
	TYA                    
	STA $157C,x   
Hurt:	
	JSL $00F5B7 
ReturnC:	
	RTS	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Return State
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
ReturnState:	
	LDA !FreeRam			; compare freeram 
	CMP #$01 : BEQ Normal		; with 1, if it is 1 jump to the label "normal"
	RTS				; otherwise return
Normal:
	JSR Smoke			; Jump to Smoke
	STZ $163E,x
	LDA #$10			; Play Magikoopa shoot 
	STA $1DF9			; sfx
	STZ !FreeRam			; set freeram to zero
	LDA #$78			
	STA $E4,x
	LDA #$0F : STA $C2,x		; set sprite state to 0F
	RTS				; return
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; NINJA ATTACK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

S12_Prepare:
	JSR Con
	LDA #$D8
	STA $B6,x
	JSL $01802A
	LDA $E4,x
	CMP #$11
	BCC .Next
	RTS
.Next
	LDA #$08
	STA $1DFC
	INC $C2,x
	RTS
S13_PrepareB:
	JSR Con
	STZ $B6,x
	LDA #$D0	;#$E0
	STA $AA,x
	JSL $01802A
	LDA $D8,x
	CMP #$40 
	BNE .Return
	LDA #$08
	STA $1DFC
	INC $C2,x
.Return
	RTS
S14_SpinRight:
	JSR Con
	LDA #$E8	; #$F0
	STA $AA,x
	LDA #$60	; #$40
	STA $B6,x	
	JSL $01802A
	LDA $E4,x
	CMP #$D0 : BCS .NextS14
	;CMP #$D3 : BEQ .NextS14
	;CMP #$D0 : BEQ .NextS14
	RTS
.NextS14
	INC $C2,x
	RTS
S15_Wait:
	JSR Con
	LDA $163E,x
	BNE .Time
	LDA #$41
	STA $163E,x
	RTS
.Time
	LDA $163E,x
	CMP #$01 : BEQ .NextS15
	RTS
.NextS15
	PHX
	LDA #$01
	JSL RANDOM
	TAX
	LDA RandomAttacksC,x	; \ set sprite number for new sprite
	PLX
	STA $C2,x
	RTS
RandomAttacksC:
db $0C,$19 ;$0C,$19
S16_Down:
	STZ $B6,x
	JSL $01802A
	JSR Con
	LDA #$1A
	STA $AA,x	
	JSL $01802A
	LDA $1588,x
	AND #$04
	BNE Quake
	RTS
Quake:
   	LDA #$18
    	STA $1887 
	LDA $77
    	AND #$04
    	BEQ NoLockM
    	LDA #$20      ; set timer to freeze mario
    	STA $18BD
NoLockM:
    	LDA #$A0     ;set time to stay on ground
    	STA $1540,x  
	LDA #$16
	STA $1DFC
	INC $C2,x
	RTS
	
S17_ShockWave: 
	LDA #$D0
	STA $E4,x
	LDA #$01 : STA $157C,x
	JSR Shoot
	LDA #$01 : STA $C2,x 
	RTS
Shoot:
	LDA $186C,x
	BNE EndSpawn3
	JSL $02A9DE
	BMI EndSpawn3
	LDA #$01				; Sprite state ($14C8,x).
	STA $14C8,y
	PHX
	TYX
	LDA #!SpriteNumber	; This the sprite number to spawn.
	STA $7FAB9E,x
	PLX
	LDA $E4,x
	STA $00E4,y
	LDA $14E0,x
	STA $14E0,y
	LDA $D8,x
	STA $00D8,y
	LDA $14D4,x
	STA $14D4,y
	PHX
	TYX
	JSL $07F7D2
	JSL $0187A7
	LDA #$08
	STA $7FAB10,x
	PLX
	LDA #$01
	STA $1594,y
EndSpawn3:
	RTS
S19_Important:
	LDA #$D0
	STA $E4,x
	LDA #$16
	STA $C2,x
	RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Contact Codes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Con:
	JSL $03B664					; check for contact
   	JSR GetSpriteClipping		; jump to clipping routine
   	JSL $03B72B	 
	BCC .Return
	LDA $154C,x             
	BNE .Return     
	LDA #$08                
	STA $154C,x             
	LDA $7D                 
	CMP #$10               
	BMI SprWinsb 
	LDA #$AF
	STA $7D
	JSL $01AA33             
	JSL $01AB99 
	LDA #$02
	STA $1DF9	
.Return
	RTS
	
StatueCon:
	JSL $03B664					; check for contact
   	JSR GetSpriteClipping		; jump to clipping routine
   	JSL $03B72B					; clipping subroutine	
	BCC .Return       
	LDA $154C,x             
	BNE .Return     
	LDA #$08                
	STA $154C,x             
	LDA $7D                 
	CMP #$10               
	BMI SprWinsb    	
	LDA $140D
	BNE Break  
	LDA #$AF
	STA $7D
	JSL $01AA33             
	JSL $01AB99 
	LDA #$02
	STA $1DF9
.Return
	RTS   
Break:  
	JSL $01AA33         
	JSL $01AB99
	INC !FreeRam
	LDA #$07 : STA $1DFC
	LDA #$07 : STA $C2,x
	RTS
SprWinsb:
	LDA $1497               
	ORA $187A               
	BNE ReturnCb      
	JSR SUB_HORZ_POS        
	TYA                    
	STA $157C,x   
Hurtb:	
	JSL $00F5B7 
ReturnCb:	
	RTS		
KoopaCon:
	JSL $018032
	JSL $01A7DC					
	BCC .Return    
	LDA $154C,x             
	BNE .Return        
	LDA #$08                
	STA $154C,x             
	LDA $7D                 
	CMP #$10               
	BMI .SprWins            
	JSL $01AA33             
	JSL $01AB99             
	LDA #$13                
	STA $1DF9    
	INC $C2,x
.Return
	RTS
.SprWins
	LDA $1497               
	ORA $187A               
	BNE .Return        
	JSR SUB_HORZ_POS        
	TYA                    
	STA $157C,x             
	JSL $00F5B7             
	RTS	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Important Stuff
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

HandleGFX:
	LDA $C2,x 
	JSL	$0086DF	
dw LeafGFX ;S0 No gfx
dw Graphics ;S1 normal
dw Graphics ;S2 normal
dw SkyGFX ;S3 normal
dw Graphics ;S4 normal
dw Graphics ;S5 normal
dw NoGFX	 ;S6 normal
dw Graphics ;S7 normal
dw NoGFX   ;S8
dw GraphicsB   ;S9
dw GraphicsE; SA koopa
dw Graphics ; Sb normal
dw GraphicsB ; sc normal
dw Graphics ; sd normal
dw Graphicsx ; se
dw Graphics ;sf normal
dw Graphics ;s10 normal
dw NoGFX ;s11 normal
dw Graphics							; s12 jump gfx here soon
dw GraphicsA						; s13 flip wall gfx here soon
dw Graphics3 ; s14 spin gfx
dw GraphicsB							; s15 wall gfx here soon
dw Graphics2;16
dw Graphics2;17
dw Graphicsx;18
dw NoGFX;19
dw Graphics;1A
dw SUB_GFX;1b
dw SUB_GFX
dw SUB_GFX
dw SUB_GFX
dw SkyGFX
dw Graphics
dw Graphics
	RTS
NoGFX:
	RTS

Smoke:
    LDY #$03                ; \ find a free slot to display effect
FINDFREE:           
	LDA $17C0,y             ;  |
    BEQ FOUNDONE            ;  |
    DEY                     ;  |
    BPL FINDFREE            ;  |
    RTS                     ; / return if no slots open
FOUNDONE:          
	LDA #$01                ; \ set effect graphic to smoke graphic
    STA $17C0,y             ; /
    LDA #$1B                ; \ set time to show smoke
    STA $17CC,y             ; /
    LDA $D8,x              
	SEC
	SBC #$10				; \ smoke y position = generator y position
    STA $17C4,y             ; /
    LDA $E4,x               
	CLC
	ADC #$08				; \ load generator x position and store it for later
    STA $17C8,y             ; /
    RTS

; Follow Code made by Iceguy

Follow:
	JSR Proximity		;\
	BNE +			;/ NOTE: This is done to avoid glitchfest.
	JSR SUB_HORZ_POS	; Get sprite's direction relative to Mario's.
	TYA
	STA $157C,x		; And store it.
+
	RTS
Proximity:		; If sprite is TOO close to Mario, return.
	LDA $14E0,x
	XBA
	LDA $E4,x
	REP #$20 ; Get sprite's X position.
	SEC
	SBC $94	; Subtract Mario's to get the difference range.
	SEP #$20
	PHA
	JSR SUB_HORZ_POS ; Determine sprite range.
	PLA
	EOR InvertAbility,y ; Apply inversion based on direction.
	CMP #$09 ; Range.
	BCS OutofRange
	LDA #$01
	RTS
OutofRange:
	LDA $E4,x
	CMP $94
	BNE RangeOut
	LDA #$01
	RTS
RangeOut:
	LDA #$00
ThisIsTheBiggestEverNameThatYouWillHaveEverSeenInASpritesASMFileInsertedThroughRomisSpriteToolAlsoThisIsTheBiggestEpicLolRofl:
	RTS
InvertAbility:
	db $FF,$00
	
SPR_T1:             db $0C,$1C
SPR_T2:             db $01,$02

GET_DRAW_INFO:       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 ON_SCREEN_X         ;  |
	INC $15A0,x             ; /

ON_SCREEN_X:         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            ;  | IF YOU READ THIS, YOU WIN A COOKIE! PM ME AND I'LL GIVE YOU A FREE ASM HACK WOOHOO!
	SEP #$20                ;  |
	ROL A                   ;  |
	AND #$01                ;  |
	STA $15C4,x             ; / 
	BNE INVALID             ; 
	
	LDY #$00                ; \ set up loop:
	LDA $1662,x             ;  | 
	AND #$20                ;  | if not smushed (1662 & 0x20), go through loop twice
	BEQ ON_SCREEN_LOOP      ;  | else, go through loop once
	INY	 ; / 
ON_SCREEN_LOOP:      LDA $D8,x               ; \ 
	CLC	 ;  | set vertical offscreen if necessary
	ADC SPR_T1,y            ;  |
	PHP	 ;  |
	CMP $1C                 ;  | (vert screen boundry)
	ROL $00                 ;  |
	PLP	 ;  |
	LDA $14D4,x             ;  | 
	ADC #$00                ;  |
	LSR $00                 ;  |
	SBC $1D                 ;  |
	BEQ ON_SCREEN_Y         ;  |
	LDA $186C,x             ;  | (vert offscreen)
	ORA SPR_T2,y            ;  |
	STA $186C,x             ;  |
ON_SCREEN_Y:         DEY	 ;  |
	BPL ON_SCREEN_LOOP      ; /

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

INVALID:             PLA	 ; \ return from *main gfx routine* subroutine...
	PLA	 ;  |    ...(not just this subroutine)
	RTS	 ; /	
	    
SUB_HORZ_POS:
    LDY #$00                
    LDA $94             
    SEC                    
    SBC $E4,x           
    STA $0F                
    LDA $95                
    SBC $14E0,x             
    BPL LABEL16       
    INY                     
LABEL16:        
	RTS 	

CODE_01BF6A:		STA $01
	PHX					;\ preserve sprite indexes of Magikoopa and magic
	PHY					;/
	JSR SUB_VERT_POS				; $0E = vertical distance to Mario
	STY $02					; $02 = vertical direction to Mario
	LDA $0E					;\ $0C = vertical distance to Mario, positive
	BPL CODE_01BF7C				; |
	EOR #$FF				; |
	CLC					; |
	ADC #$01				; |
CODE_01BF7C:		
	STA $0C					;/
	JSR SUB_HORZ_POS			; $0F = horizontal distance to Mario
	STY $03					; $03 = horizontal direction to Mario
	LDA $0F					;\ $0D = horizontal distance to Mario, positive
	BPL CODE_01BF8C				; |
	EOR #$FF				; |
	CLC					; |
	ADC #$01				; |
CODE_01BF8C:		STA $0D					;/
			LDY #$00
			LDA $0D					;\ if vertical distance less than horizontal distance,
			CMP $0C					; |
			BCS CODE_01BF9F				;/ branch
			INY					; set y register
			PHA					;\ switch $0C and $0D
			LDA $0C					; |
			STA $0D					; |
			PLA					; |
			STA $0C					;/
CODE_01BF9F:		LDA #$00				;\ zero out $00 and $0B
			STA $0B					; | ...what's wrong with STZ?
			STA $00					;/
			LDX $01					;\ divide $0C by $0D?
CODE_01BFA7:		LDA $0B					; |\ if $0C + loop counter is less than $0D,
			CLC					; | |
			ADC $0C					; | |
			CMP $0D					; | |
			BCC CODE_01BFB4				; |/ branch
			SBC $0D					; | else, subtract $0D
			INC $00					; | and increase $00
CODE_01BFB4:		STA $0B					; |
			DEX					; |\ if still cycles left to run,
			BNE CODE_01BFA7				;/ / go to start of loop
			TYA					;\ if $0C and $0D was not switched,
			BEQ CODE_01BFC6				;/ branch
			LDA $00					;\ else, switch $00 and $01
			PHA					; |
			LDA $01					; |
			STA $00					; |
			PLA					; |
			STA $01					;/
CODE_01BFC6:		LDA $00					;\ if horizontal distance was inverted,
			LDY $02					; | invert $00
			BEQ CODE_01BFD3				; |
			EOR #$FF				; |
			CLC					; |
			ADC #$01				; |
			STA $00					;/
CODE_01BFD3:		LDA $01					;\ if vertical distance was inverted,
			LDY $03					; | invert $01
			BEQ CODE_01BFE0				; |
			EOR #$FF				; |
			CLC					; |
			ADC #$01				; |
			STA $01					;/
CODE_01BFE0:		PLY					;\ retrieve Magikoopa and magic sprite indexes
			PLX					;/
			RTS					; return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_VERT_POS
; This routine determines if Mario is above or below the sprite.  It sets the Y register
; to the direction such that the sprite would face Mario
; It is ripped from $03B829
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SUB_VERT_POS:		LDY #$00               ;A:25A1 X:0007 Y:0001 D:0000 DB:03 S:01EA P:envMXdizCHC:0130 VC:085 00 FL:924
					LDA $96                ;A:25A1 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdiZCHC:0146 VC:085 00 FL:924
					CLC
					ADC #$18
					SEC                    ;A:2546 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdizCHC:0170 VC:085 00 FL:924
					SBC $D8,x              ;A:2546 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdizCHC:0184 VC:085 00 FL:924
					STA $0E                ;A:25D6 X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0214 VC:085 00 FL:924
					LDA $97                ;A:25D6 X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0238 VC:085 00 FL:924
					SBC $14D4,x            ;A:2501 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdizcHC:0262 VC:085 00 FL:924
					BPL SPR_L11            ;A:25FF X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0294 VC:085 00 FL:924
					INY                    ;A:25FF X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0310 VC:085 00 FL:924
SPR_L11:				RTS                


RANDOM:			PHX
			PHP
			SEP #$30
			PHA
			JSL $01ACF9		; Random number generation routine
			PLX
			CPX #$FF		;\ Handle glitch if max is FF
			BNE NORMALRT		;|
			LDA $148B		;|
			BRA ENDRANDOM		;/
NORMALRT:		INX			; Amount in plus 1
			LDA $148B		;\
			STA $4202		;| Multiply with hardware regsisters
			STX $4203		;|
			NOP			;|
			NOP			;|
			NOP			;|
			NOP			;/
			LDA $4217
ENDRANDOM:		PLP
			PLX
			RTL
			
KILLED_X_SPEED:     db $F0,$10		
ThrowBlockContact:
SPRITE_INTERACT:     LDY #$0B                ; sprite is being kicked
INTERACT_LOOP:       LDA $14C8,y             ; \ if the sprite status is..
	            CMP #$09                ;  | ...shell-like
	            BCS PROCESS_SPRITE      ; /
NEXT_SPRITE:         DEY
	            BPL INTERACT_LOOP
	            RTS

PROCESS_SPRITE:    
CPY $15E9
BEQ NEXT_SPRITE
  PHX                       
                    TYX                       
                    JSL $03B6E5             ; get sprite clipping B routine   
                    PLX                       
                    JSL $03B69F             ; get sprite clipping A routine  
                    JSL $03B72B             ; check for contact routine
	            BCC NEXT_SPRITE

	            PHX
	            TYX
	
	            JSL $01AB72             ; show sprite contact gfx routine

	            LDA #$02		    ; \ Kill thrown sprite
	            STA $14C8,x             ; /
	
	            LDA #$D0                ; \ Set killed Y speed
                    STA $AA,x               ; /
	
	            LDY #$00		    ; Set killed X speed
	            LDA $B6,x
	            BPL SET_SPEED
	            INY 

SET_SPEED:	    LDA KILLED_X_SPEED,y
	            STA $B6,x

NO_KILL:	            PLX

HANDLE_HIT:	   
	LDA $C2,x
	CMP #$01
	BNE Nope
	LDA #$10 : STA $C2,x
	LDA #$13
	STA $1DF9
	RTS
Nope:
	LDA #$02
	STA $1DF9
	RTS
	

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                 ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0756 VC:176 00 FL:205
                    AND #$01                ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0780 VC:176 00 FL:205
                    ORA $03                 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0796 VC:176 00 FL:205
                    STA $01                 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0820 VC:176 00 FL:205
                    TAY                     ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0844 VC:176 00 FL:205
                    LDA $1A                 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0858 VC:176 00 FL:205
                    CLC                     ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0882 VC:176 00 FL:205
                    ADC SPR_T14,y           ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0896 VC:176 00 FL:205
                    ROL $00                 ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizcHC:0928 VC:176 00 FL:205
                    CMP $E4,x               ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:0966 VC:176 00 FL:205
                    PHP                     ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:0996 VC:176 00 FL:205
                    LDA $1B                 ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdizCHC:1018 VC:176 00 FL:205
                    LSR $00                 ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdiZCHC:1042 VC:176 00 FL:205
                    ADC SPR_T15,y           ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdizcHC:1080 VC:176 00 FL:205
                    PLP                     ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F0 P:eNvMXdizcHC:1112 VC:176 00 FL:205
                    SBC $14E0,x             ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1140 VC:176 00 FL:205
                    STA $00                 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:1172 VC:176 00 FL:205
                    LSR $01                 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:1196 VC:176 00 FL:205
                    BCC SPR_L31             ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZCHC:1234 VC:176 00 FL:205
                    EOR #$80                ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZCHC:1250 VC:176 00 FL:205
                    STA $00                 ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1266 VC:176 00 FL:205
SPR_L31:             LDA $00                 ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1290 VC:176 00 FL:205
                    BPL RETURN_35           ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1314 VC:176 00 FL:205
ERASE_SPRITE:        LDA $14C8,x             ; \ if sprite status < 8, permanently erase sprite
                    CMP #$08                ; |
                    BCC KILL_SPRITE         ; /    
                    LDY $161A,x             ;A:FF08 X:0007 Y:0001 D:0000 DB:01 S:01F3 P:envMXdiZCHC:1108 VC:059 00 FL:2878
                    CPY #$FF                ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdiZCHC:1140 VC:059 00 FL:2878
                    BEQ KILL_SPRITE         ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdizcHC:1156 VC:059 00 FL:2878
                    LDA #$00                ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdizcHC:1172 VC:059 00 FL:2878
                    STA $1938,y             ;A:FF00 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdiZcHC:1188 VC:059 00 FL:2878
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                 ;A:0000 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:1218 VC:250 00 FL:5379
                    LSR A                   ;A:0016 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1242 VC:250 00 FL:5379
                    AND #$01                ;A:000B X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1256 VC:250 00 FL:5379
                    STA $01                 ;A:0001 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1272 VC:250 00 FL:5379
                    TAY                     ;A:0001 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1296 VC:250 00 FL:5379
                    LDA $1C                 ;A:001A X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0052 VC:251 00 FL:5379
                    CLC                     ;A:00BD X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0076 VC:251 00 FL:5379
                    ADC SPR_T12,y           ;A:00BD X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0090 VC:251 00 FL:5379
                    ROL $00                 ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:enVMXdizCHC:0122 VC:251 00 FL:5379
                    CMP $D8,x               ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0160 VC:251 00 FL:5379
                    PHP                     ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0190 VC:251 00 FL:5379
                    LDA $001D             ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F2 P:eNVMXdizcHC:0212 VC:251 00 FL:5379
                    LSR $00                 ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:enVMXdiZcHC:0244 VC:251 00 FL:5379
                    ADC SPR_T13,y           ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:enVMXdizCHC:0282 VC:251 00 FL:5379
                    PLP                     ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:envMXdiZCHC:0314 VC:251 00 FL:5379
                    SBC $14D4,x             ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0342 VC:251 00 FL:5379
                    STA $00                 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0374 VC:251 00 FL:5379
                    LDY $01                 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0398 VC:251 00 FL:5379
                    BEQ SPR_L38             ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0422 VC:251 00 FL:5379
                    EOR #$80                ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0438 VC:251 00 FL:5379
                    STA $00                 ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0454 VC:251 00 FL:5379
SPR_L38:             LDA $00                 ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0478 VC:251 00 FL:5379
                    BPL RETURN_35           ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0502 VC:251 00 FL:5379
                    BMI ERASE_SPRITE        ;A:8AFF X:0002 Y:0000 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0704 VC:184 00 FL:5490

SUB_IS_OFF_SCREEN:   LDA $15A0,x             ; \ if sprite is on screen, accumulator = 0 
                    ORA $186C,x             ; |  
                    RTS                     ; / return
					
GetSpriteClipping:
PHY
PHX
TXY
LDA $00E4,y		; Starting X pos of sprite clipping = sprite center position - $0C ($0C pixels to the left)
STA $04
LDA $14E0,y
ADC #$00
STA $0A
LDA #$18                ; Width of sprite clipping
STA $06
LDA $00D8,y
SEC
SBC #$10                ; Starting Y pos of sprite clipping = sprite center position - $2C ($2C pixels above)
STA $05
LDA $14D4,y
SBC #$00
STA $0B
LDA #$20                ; Height of sprite clipping
STA $07
PLX
PLY
RTS

Prop: 
db $0F,$0F

YDisp:
db $F0,$F0
db $00,$00
   
XDisp:  
db $00,$08
db $00,$08

I:
db $00,$01
db $20,$21

db $03,$04
db $23,$24

S:
db $06,$07
db $26,$27

B:
db $EE,$CE
db $26,$27

W:
db $80,$81
db $A0,$A1

db $83,$84
db $A3,$A4

db $8A,$8B
db $AA,$AB

db $8D,$8E
db $AD,$AE

F:
db $C6,$C7
db $E6,$E7

db $C9,$CA
db $E9,$EA

db $CC,$CD
db $EC,$ED

ThrowPose:
db $C0,$C1
db $E0,$E1

db $C3,$C4
db $E3,$E4

ST:
db $C8,$C9
db $E8,$E9

Frame:
db $00,$04,$00,$04

FrameStun:
db $00,$04,$08,$04

FrameB:
db $00,$04,$08,$0C	
	
Graphics:
    PHX
    LDX $15E9	
    LDA $C2,x
    PLX
    CMP #$0F
    BEQ End_CG
    CMP #$20
    BEQ End_CG
    CMP #$21
    BNE Cont_Graphics
End_CG:
    LDA $14
    AND #$01
    BEQ Cont_Graphics
    RTS    

Cont_Graphics:
    JSR GET_DRAW_INFO
    LDA $157C,x
    STA $02
    PHX
    LDX #$03
LOOP_START:         
    LDA XDisp,x
    CLC
    ADC $00
    STA $0300,y
	
    LDA YDisp,x 
    CLC
    ADC $01               
    STA $0301,y             

	PHX
	LDX $15E9	
	LDA $C2,x
	PLX
	CMP #$02 : BEQ ThrowGFX
	CMP #$20 : BEQ WalkGFX
	CMP #$03 : BEQ WalkGFX
	CMP #$04 : BEQ StatueGFX
	CMP #$05 : BEQ StatueGFX
	CMP #$06 : BEQ StatueGFX
	CMP #$07 : BEQ BrokenGFX
	CMP #$0C : BEQ WalkGFX
	CMP #$12 : BEQ WalkGFX
	CMP #$10 : BEQ StunGFX
	CMP #$0B : BEQ FlashGFX
	;CMP #$0F : BEQ FlashGFX
	CMP #$0D : BEQ HurtGFX
	CMP #$1A : BEQ FlashGFX
	JSR IdleMap
	BRA SetA
StatueGFX:
	JSR StatueMap
	BRA SetA
BrokenGFX:
	JSR BrokenMap
	BRA SetA
WalkGFX:
	JSR WalkMap
	BRA SetA
StunGFX:
	JSR StunMap
	LDA #$0E	; | Set properties based on direction.
    	STA $0303,y	;/
	BRA IncA
FlashGFX:
	JSR FlashMap
SetA:	
	JSR P
IncA:	
    INY                     ; \ increase index to sprite tile map ($300)...
    INY                     ;  |    ...we wrote 1 16x16 tile...
    INY                     ;  |    ...sprite OAM is 8x8...
    INY                     ; /    ...so increment 4 times
	DEX
    BPL LOOP_START

    PLX
    LDY #$02                ; \ 460 = 2 (all 16x16 tiles)
    LDA #$03            ;  | A = (number of tiles drawn - 1)
    JSL $01B7B3             ; / don't draw if offscreen
    RTS 
P:
    PHX   ; Push number of times to go through loop + "left" displacement if necessary.
    LDX $02   ;\
    LDA Prop,x ; | Set properties based on direction.
    STA $0303,y  ;/
    PLX 	
	RTS

ThrowGFX:
	JSR ThrowMap
	LDA #$0E	; | Set properties based on direction.
    	STA $0303,y	;/
	BRA IncA
ThrowMap:   
    	STX $03
    	PHX    
   	LDA $14
    	LSR
    	LSR
    	LSR
    	LSR
    	AND #$03
    	TAX
    	LDA Frame,x
    	CLC
    	ADC $03
    	TAX
    	LDA ThrowPose,x
    	STA $0302,y
   	PLX
	RTS
HurtGFX: 
	JSR HurtMap
	BRA SetA 
HurtMap:  
   	LDA ST,x
    	STA $0302,y
	RTS
IdleMap:   
    STX $03
    PHX    
    LDA $14
    LSR
    LSR
    LSR
    LSR
    AND #$03
    TAX
    LDA Frame,x
    CLC
    ADC $03
    TAX
    LDA I,x
    STA $0302,y
    PLX
	RTS
StatueMap:
    LDA S,x
    STA $0302,y
	RTS
BrokenMap:
    LDA B,x
    STA $0302,y
	RTS
StunMap:
    STX $03
    PHX
    LDA $14
    LSR
    LSR
    LSR
    LSR
    AND #$03
    TAX
    LDA FrameStun,x
    CLC
    ADC $03
    TAX
    LDA F,x
    STA $0302,y
	PLX
	RTS
FlashMap:
    STX $03
    PHX
    LDA $14
    LSR
    LSR
    LSR
    LSR
    AND #$03
    TAX
    LDA Frame,x
    CLC
    ADC $03
    TAX
    LDA I,x
    STA $0302,y
    PLX
	RTS
WalkMap:
    STX $03
    PHX
    LDA $14
    LSR
    LSR
    ;LSR
    ;LSR
    AND #$03
    TAX
    LDA FrameB,x
    CLC
    ADC $03
    TAX
    LDA W,x
    STA $0302,y
    PLX
	RTS
	
PROPERTIESE: db $4A,$0A
TILEMAPE: db $82,$A2,$82,$A0
YDISPE: db $10,$00
GraphicsE:
	JSR GET_DRAW_INFO 	; Before actually coding the graphics, we need a routine that will get the current sprite's value 
		 	 	; into the OAM.
		  		; The OAM being a place where the tile data for the current sprite will be stored.
   
                    LDA $14
                    LSR A
                    LSR A
                    LSR A
                    AND #$01
                    ASL A
                    STA $03
	LDA $157C,x
	STA $02			; Store direction to $02 for use with property routine later.

	PHX			;\ Push the sprite index, since we're using it for a loop.	
	LDX #$01		;/ X = number of times to loop through. Since we only draw one MORE tile, loop one more time.
LoopE:
	LDA $00			;\
	STA $0300,y		;/ Draw the X position of the sprite

	LDA $01			;\
	SEC			; | Y displacement is added for the Y position, so one tile is higher than the other.
	SBC YDISPE,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.

                    PHX
                    TXA
                    CLC
                    ADC $03
                    TAX
                    LDA TILEMAPE,x
                    STA $0302,y 
                    PLX


	PHX			; Push number of times to go through loop (01), because we're using it for a table here.
	LDX $02			;\ 
	LDA PROPERTIESE,x	; | Set properties based on direction.
	ORA $64
	STA $0303,y		;/
	PLX			; Pull number of times to go through loop.

	INY			;\
	INY			; | The OAM is 8x8, but our sprite is 16x16 ..
	INY			; | So increment it 4 times.
	INY			;/
	
	DEX			; After drawing this tile, decrease number of tiles to go through loop. If the second tile
				; is drawn, then loop again to draw the first tile.

	BPL LoopE		; 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 #$01		; 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!

Prop2:
db $0F,$0F
SpinMap:
db $DB,$DC,$EB,$EC	;$5C,$5D,$6C,$6D
db $DB,$DC,$EB,$EC
db $DB,$DC,$EB,$EC	;$5C,$5D,$6C,$6D
db $DB,$DC,$EB,$EC

XDisp3:
db $00,$08,$00,$08

XDisp2:
db $00,$08
db $00,$08
db $00,$08
YDisp3:
db $F8,$F8,$00,$00
YDisp2:
db $E8,$E8
db $F8,$F8
db $00,$00

PoundMap:
db $0D,$0E
db $2C,$2D
db $62,$63

Graphics2:
    JSR GET_DRAW_INFO
    LDA $157C,x
    STA $02
    PHX
    LDX #$05
LOOP_START2:         
	PHX
    LDA XDisp2,x
    CLC
    ADC $00
    STA $0300,y
	
    LDA YDisp2,x 
    CLC
    ADC $01               
    STA $0301,y             

	PHX
	LDX $15E9	
	PLX
	LDA PoundMap,x
	STA $0302,y
	BRA Set2
Set2:
    PHX   ; Push number of times to go through loop + "left" displacement if necessary.
    LDA $14
    LSR
    AND #$01
    TAX	
    LDA Prop2,x ; | Set properties based on direction.
   ; LDX $02   ;\
    ;LDA Prop,x ; | Set properties based on direction.
    STA $0303,y  ;/
    PLX 
    PLX
    INY                     ; \ increase index to sprite tile map ($300)...
    INY                     ;  |    ...we wrote 1 16x16 tile...
    INY                     ;  |    ...sprite OAM is 8x8...
    INY                     ; /    ...so increment 4 times
	DEX
    BPL LOOP_START2

    PLX
    LDY #$02                ; \ 460 = 2 (all 16x16 tiles)
    LDA #$05            ;  | A = (number of tiles drawn - 1)
    JSL $01B7B3             ; / don't draw if offscreen
    RTS 
	
    PHX   ; Push number of times to go through loop + "left" displacement if necessary.
    LDA $14
    LSR
    AND #$01
    TAX	
    LDA Prop2,x ; | Set properties based on direction.
    ;LDX $02   ;\
    ;LDA Prop,x ; | Set properties based on direction.
    STA $0303,y  ;/
    PLX 
    PLX
    INY                     ; \ increase index to sprite tile map ($300)...
    INY                     ;  |    ...we wrote 1 16x16 tile...
    INY                     ;  |    ...sprite OAM is 8x8...
    INY                     ; /    ...so increment 4 times
	DEX
    BPL LOOP_START2

    PLX
    LDY #$02                ; \ 460 = 2 (all 16x16 tiles)
    LDA #$05            ;  | A = (number of tiles drawn - 1)
    JSL $01B7B3             ; / don't draw if offscreen
    RTS 


Graphics3:	
    JSR GET_DRAW_INFO
    LDA $157C,x
    STA $02
    PHX
    LDX #$03
LOOP_START3:         
	PHX
    LDA XDisp3,x
    CLC
    ADC $00
    STA $0300,y
	
    LDA YDisp3,x 
    CLC
    ADC $01               
    STA $0301,y       
	
	PHX
	LDX $15E9	
	
	PLX
	PHX			;/ as the displacement. For the second tile, F0 is added to make it higher than the first.
	STX $03
	LDA $14
	;LSR A
	AND #$0C
	CLC
	ADC $03
	TAX
    LDA SpinMap,x
    STA $0302,y
    PLX

    PHX   ; Push number of times to go through loop + "left" displacement if necessary.
    LDX $02   ;\
    LDA Prop,x ; | Set properties based on direction.
    STA $0303,y  ;/
    PLX 
    PLX
    INY                     ; \ increase index to sprite tile map ($300)...
    INY                     ;  |    ...we wrote 1 16x16 tile...
    INY                     ;  |    ...sprite OAM is 8x8...
    INY                     ; /    ...so increment 4 times
	DEX
    BPL LOOP_START3

    PLX
    LDY #$02                ; \ 460 = 2 (all 16x16 tiles)
    LDA #$05            ;  | A = (number of tiles drawn - 1)
    JSL $01B7B3             ; / don't draw if offscreen
    RTS 
	
YDispA:
db $F0,$F0
db $00,$00
   
XDispA:  
db $00,$08
db $00,$08

J:
db $09,$0A
db $29,$2A

GraphicsA:
	JSR GET_DRAW_INFO
    LDA $157C,x
    STA $02
    PHX
    LDX #$03
LOOP_STARTA:         
	PHX
    LDA XDispA,x
    CLC
    ADC $00
    STA $0300,y
	
    LDA YDispA,x 
    CLC
    ADC $01               
    STA $0301,y   

	PHX
	LDX $15E9
	
	PLX
	LDA J,x
	STA $0302,y

    PHX   					; Push number of times to go through loop + "left" displacement if necessary.
    LDX $02   				;\
    LDA Prop,x 				; | Set properties based on direction.
    STA $0303,y  			;/
    PLX 
	
    PLX
    INY                     ; \ increase index to sprite tile map ($300)...
    INY                     ;  |    ...we wrote 1 16x16 tile...
    INY                     ;  |    ...sprite OAM is 8x8...
    INY                     ; /    ...so increment 4 times
	DEX
    BPL LOOP_STARTA

    PLX
    LDY #$02                ; \ 460 = 2 (all 16x16 tiles)
    LDA #$03            	;  | A = (number of tiles drawn - 1)
    JSL $01B7B3             ; / don't draw if offscreen
    RTS 

PropX:
db $4F,$4F
	
WallMap:
db $86,$88
db $A6,$A8

WallMapX:
db $88,$86
db $A8,$A6
GraphicsB:
	JSR GET_DRAW_INFO
    LDA $157C,x
    STA $02
    PHX
    LDX #$03
LOOP_STARTB:         
	PHX
	
    LDA SkyY,x 
    CLC
    ADC $01               
    STA $0301,y   

	PHX
	LDX $15E9
	LDA $C2,x
	CMP #$09
	BEQ M
	PLX
	LDA WallMap,x
	STA $0302,y

    PHX   					; Push number of times to go through loop + "left" displacement if necessary.
    LDX $02   				;\
    LDA Prop,x 				; | Set properties based on direction.
    STA $0303,y  			;/
    PLX 

	LDA SkyX,x
    CLC
    ADC $00
    STA $0300,y
	BRA Ss
M:
	PLX
	LDA WallMapX,x
	STA $0302,y

	LDA SkyXB,x
    CLC
    ADC $00
    STA $0300,y
	
    PHX   					; Push number of times to go through loop + "left" displacement if necessary.
    LDX $02   				;\
    LDA PropX,x 				; | Set properties based on direction.
    STA $0303,y  			;/
    PLX 
	
Ss:
    PLX
    INY                     ; \ increase index to sprite tile map ($300)...
    INY                     ;  |    ...we wrote 1 16x16 tile...
    INY                     ;  |    ...sprite OAM is 8x8...
    INY                     ; /    ...so increment 4 times
	DEX
    BPL LOOP_STARTB

    PLX
    LDY #$02                ; \ 460 = 2 (all 16x16 tiles)
    LDA #$03            	;  | A = (number of tiles drawn - 1)
    JSL $01B7B3             ; / don't draw if offscreen
    RTS 

X_OFFSET:		db $FC,$04,$FC,$04,$00 
Y_OFFSET:		db $F0,$F0,$00,$00,$F8 
TILE_MAP:		db $65,$65,$67,$67,$69
PROPERTIE_S:		db $03,$43,$03,$43,$03

SUB_GFX:			JSR GET_DRAW_INFO
			LDA #$FF
			STA $02
			PHX			 
			LDX #$03                
			CMP #$00			    
			BEQ LOOP_STARTT
			INX			 
LOOP_STARTT:		LDA $00    
			CLC			 
			ADC X_OFFSET,x
			STA $0300,y

			LDA $01    
			CLC			 
			ADC Y_OFFSET,x
			STA $0301,y

			LDA PROPERTIE_S,x
			ORA $64    
			STA $0303,y

			LDA TILE_MAP,x		 
			STA $0302,y

			INY			 
			INY			 
			INY			 
			INY			 
			DEX			 
			BPL LOOP_STARTT

			PLX			 
			               
			LDY #$02		; \ 460 = 2 (all 16x16 tiles)
			LDA #$04		;  | A = (number of tiles drawn - 1)
			JSL $01B7B3		; / don't draw if offscreen
			RTS			; return

GetSpriteClippingThwomp:
PHY
PHX
TXY
LDA $00E4,y
CLC
ADC #$00 ; Starting X pos of sprite clipping = sprite center position - $0C ($0C pixels to the left)
STA $04
LDA $14E0,y
ADC #$00
STA $0A
LDA #$10 ; Width of sprite clipping
STA $06
LDA $00D8,y
SEC
SBC #$08 ; Starting Y pos of sprite clipping = sprite center position - $2C ($2C pixels above)
STA $05
LDA $14D4,y
SBC #$00
STA $0B
LDA #$20 ; Height of sprite clipping
STA $07
PLX
PLY
RTS

LOL:
db $C4,$C6
db $E4,$E6

SkyX:
db $00,$10
db $00,$10

SkyXB:
db $02,$12
db $02,$12

SkyY:
db $F0,$F0
db $00,$00

FrameC:
db $00,$05,$00,$05

SkyMap:
db $C2,$C0
db $E2,$E0

db $0B,$09	;$8C,$8A
db $2B,$29	;$AC,$AA

PropB:
db $4F,$0F

SkyGFX:
    JSR GET_DRAW_INFO
    LDA $157C,x
    STA $02
    PHX
    LDX #$03
LOOP_STARTS:         
	PHX
    LDA SkyX,x
    CLC
    ADC $00
    STA $0300,y
	
    LDA SkyY,x 
    CLC
    ADC $01               
    STA $0301,y             

	PHX
	LDX $15E9	
	LDA $C2,x
	CMP #$1F
	BEQ Different
	PLX
	
	STX $03
    PHX
    LDA $02
    BEQ DontFlipS
    LDA $03
    EOR #$01
    STA $03
DontFlipS:  
    LDA $14
    LSR
    LSR
    LSR
    LSR
    AND #$03
    TAX
    LDA Frame,x
    CLC
    ADC $03
    TAX
    LDA SkyMap,x
    STA $0302,y
    PLX
	BRA LULZLULZ
Different:
	PLX
	LDA LOL,x
	STA $0302,y
	LDA #$01
	STA $02
	
LULZLULZ:
    PHX   ; Push number of times to go through loop + "left" displacement if necessary.
    LDX $02   ;\
    LDA PropB,x ; | Set properties based on direction.
    STA $0303,y  ;/
    PLX 
	
    PLX
    INY                     ; \ increase index to sprite tile map ($300)...
    INY                     ;  |    ...we wrote 1 16x16 tile...
    INY                     ;  |    ...sprite OAM is 8x8...
    INY                     ; /    ...so increment 4 times
	DEX
    BPL LOOP_STARTS

    PLX
    LDY #$02                ; \ 460 = 2 (all 16x16 tiles)
    LDA #$03            ;  | A = (number of tiles drawn - 1)
    JSL $01B7B3             ; / don't draw if offscreen
    RTS 
	
	
KoopaJump:
					LDA $1588,x             ;A:0100 X:0007 Y:0001 D:0000 DB:03 S:01EF P:envMXdiZCHC:0276 VC:077 00 FL:623
                    AND #$04                ;A:0100 X:0007 Y:0001 D:0000 DB:03 S:01EF P:envMXdiZCHC:0308 VC:077 00 FL:623
                    PHA                     ;A:0100 X:0007 Y:0001 D:0000 DB:03 S:01EF P:envMXdiZCHC:0324 VC:077 00 FL:623
                    JSL $01802A             ; update position based on speed values
                    JSL $018032             ; interact with other sprites
					LDA $163E,x
					BNE TURN_CONT
					JSR SUB_HORZ_POS
					PHY
					PLA
					STA $157C,x
					LDA #$25
					STA $163E,x

TURN_CONT:				
				
                    LDA $1588,x             ;A:254B X:0007 Y:0007 D:0000 DB:03 S:01EE P:envMXdizcHC:0684 VC:085 00 FL:623
                    AND #$04                ;A:2504 X:0007 Y:0007 D:0000 DB:03 S:01EE P:envMXdizcHC:0716 VC:085 00 FL:623
                    BEQ IN_AIR              ;A:2504 X:0007 Y:0007 D:0000 DB:03 S:01EE P:envMXdizcHC:0732 VC:085 00 FL:623
                    STZ $AA,x               ;A:2504 X:0007 Y:0007 D:0000 DB:03 S:01EE P:envMXdizcHC:0748 VC:085 00 FL:623
                    PLA                     ;A:2504 X:0007 Y:0007 D:0000 DB:03 S:01EE P:envMXdizcHC:0778 VC:085 00 FL:623
                    BRA ON_GROUND           ;A:2500 X:0007 Y:0007 D:0000 DB:03 S:01EF P:envMXdiZcHC:0806 VC:085 00 FL:623
IN_AIR:              PLA                     ;A:2500 X:0007 Y:0006 D:0000 DB:03 S:01EB P:envMXdiZcHC:0316 VC:085 00 FL:4955
                    BEQ WAS_IN_AIR          ;A:2504 X:0007 Y:0006 D:0000 DB:03 S:01EC P:envMXdizcHC:0344 VC:085 00 FL:4955
                    LDA #$0A                ;A:2504 X:0007 Y:0006 D:0000 DB:03 S:01EC P:envMXdizcHC:0360 VC:085 00 FL:4955
                    STA $1540,x             ;A:25FF X:0007 Y:0006 D:0000 DB:03 S:01EC P:eNvMXdizcHC:0376 VC:085 00 FL:4955
WAS_IN_AIR:          LDA $1540,x             ;A:25FF X:0007 Y:0006 D:0000 DB:03 S:01EC P:eNvMXdizcHC:0408 VC:085 00 FL:4955
                    BEQ ON_GROUND           ;A:25FF X:0007 Y:0006 D:0000 DB:03 S:01EC P:eNvMXdizcHC:0440 VC:085 00 FL:4955
;                    STZ $AA,x               ;A:25FF X:0007 Y:0006 D:0000 DB:03 S:01EC P:eNvMXdizcHC:0456 VC:085 00 FL:4955
NO_GROUND:			LDA #$05
					STA $163E,x
					LDA $1588,x
					AND #$08
					BEQ HEAD_BONK
					LDA #$B8
					EOR #$FF
					STA $AA,x
HEAD_BONK:
					BRA NO_TOUCH
					
ON_GROUND:           LDA $77
					AND #$04
					BEQ NO_TOUCH
					LDA $1588,x
					AND #$04
					BEQ NO_GROUND
					LDA $15		;$16
					AND #$80
					BEQ NO_TOUCH
					LDA #$20
					STA $1DF9
					LDA #$B4
					STA $AA,x
NO_TOUCH:
					LDY $15AC,x             ; \
                    LDA $1588,x             ; | if sprite is in contact with an object...
                    AND #$03                ; |
    BEQ DONT_UPDATE         ; |
    LDA $157C,x             ; | flip the direction status
    EOR #$01                ; |
    STA $157C,x             ; /
DONT_UPDATE:
	RTS
	
TILEMAP:
	db $2F,$3F,$6F,$7F	;$4F,$5F,$6F,$7F

LeafGFX:           JSR GET_DRAW_INFO       ; sets y = OAM offset
                    LDA $157C,x             ; \ $02 = direction
                    STA $02                 ; / 
                    LDA $14                 ; \ 
                    LSR A                   ;  |
                    LSR A                   ;  |
                    ;LSR A                   ;  |
                    CLC                     ;  |
                    ADC $15E9               ;  |
                    AND #$03                ;  |
                    STA $03                 ;  | $03 = index to frame start (0 or 1)
                    PHX                     ; /
                    
                    LDA $14C8,x
                    CMP #$02
                    BNE LOOP_START_2
                    STZ $03
                    LDA $15F6,x
                    ORA #$80
                    STA $15F6,x

LOOP_START_2:        LDA $00                 ; \ tile x position = sprite x location ($00)
					CLC 
					ADC #$08
                    STA $0300,y             ; /

                    LDA $01                 ; \ tile y position = sprite y location ($01)
                    CLC
                    ADC #$08
                    STA $0301,y             ; /

				LDA #$0F
				ORA $64                 ; add in tile priority of level
                    STA $0303,y             ; store tile properties

                    LDX $03                 ; \ store tile
                    LDA TILEMAP,x           ;  |
                    STA $0302,y             ; /

                    INY                     ; \ increase index to sprite tile map ($300)...

                    PLX                     ; pull, X = sprite index
                    LDY #$00                ; This means the tile drawn is 8x8.
                    LDA #$00                ;  | A = (number of tiles drawn - 1)
                    JSL $01B7B3             ; / don't 
                    RTS                     ; return
					
YDispAx:
db $00,$00,$00

XDispAx: 
db $10,$10,$00

Jx:
db $AA,$AA,$A8

Graphicsx:
	JSR GET_DRAW_INFO
    LDA $157C,x
    STA $02
    PHX
    LDX #$02
LOOP_STARTAx:         
	PHX
    LDA XDispAx,x
    CLC
    ADC $00
    STA $0300,y
	
    LDA YDispAx,x 
    CLC
    ADC $01               
    STA $0301,y   

	PHX
	LDX $15E9
	
	PLX
	LDA Jx,x
	STA $0302,y

    PHX   					; Push number of times to go through loop + "left" displacement if necessary.
    LDX $02   				;\
    LDA #$0E 				; | Set properties based on direction.
    STA $0303,y  			;/
    PLX 
	
    PLX
    INY                     ; \ increase index to sprite tile map ($300)...
    INY                     ;  |    ...we wrote 1 16x16 tile...
    INY                     ;  |    ...sprite OAM is 8x8...
    INY                     ; /    ...so increment 4 times
	DEX
    BPL LOOP_STARTAx

    PLX
    LDY #$02                ; \ 460 = 2 (all 16x16 tiles)
    LDA #$02            	;  | A = (number of tiles drawn - 1)
    JSL $01B7B3             ; / don't draw if offscreen
    RTS 