;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; No More Sprite Tile Limits - SMWCP2 custom version
;; **REQUIRES STZ !RAM_SpriteTilesReservedDyn in SMWCP2's hijacks/level.asm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

		!SpriteTilesReservedEnabled	= 1
		!RAM_SpriteTilesReserved	= $13E6
		!SpriteTilesReservedEnabledDyn	= 1
		!RAM_SpriteTilesReservedDyn	= $13F2

header
lorom

macro speedup(offset)
		CMP.w $02FD+<offset>		; Compare Y position of PREVIOUS tile in OAM to A=0xF0
		BEQ ?notFound			; \  if last isn't free
		LDA.b #<offset>			;  | (and this is), then
		JMP .foundSlot			; /  this is the index
?notFound:
endmacro

macro bulkSpeedup(arg)
		%speedup(<arg>+12)
		%speedup(<arg>+8)
		%speedup(<arg>+4)
		%speedup(<arg>)
endmacro

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

org $0180D2

SpriteOAMHook:      
autoclean	JML PickOAMSlot


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

freecode

reset bytes

PickOAMSlot:
		LDA.w $1692			; \  if sprite header
		CMP.b #$10			;  | setting is not 10,
		BNE .default			; /  use the old code
.notLastSpr	LDA.w $14C8,x			; \ it's not necessary to get an index
		BEQ .return			; / if this sprite doesn't exist
		LDA.b $9E,x			; \  give yoshi
		CMP.b #$35			;  | the first
		BEQ .yoshi			; /  two tiles

if !SpriteTilesReservedEnabled || !SpriteTilesReservedEnabledDyn

if !SpriteTilesReservedEnabled && !SpriteTilesReservedEnabledDyn
		LDA.w !RAM_SpriteTilesReserved
		CLC
		ADC.w !RAM_SpriteTilesReservedDyn
elseif !SpriteTilesReservedEnabled
		LDA.w !RAM_SpriteTilesReserved
else
		LDA.w !RAM_SpriteTilesReservedDyn
endif
		BEQ SearchAlgorithm		; If none reserved, then search normally
		REP.b #%00100000		; 16-bit A
		AND.w #$00FF			; Wipe A high byte
		STA $00				; \
		ASL #2				;  | x10
		CLC : ADC $00			;  |
		ASL				; /
		CLC				; \ Add SearchAlgorithm
		ADC #SearchAlgorithm_s		; / offset (past LDA #$F0)
		STA.w $00			; Store address to $00 (where in SearchAlgorithm to start)
		SEP.b #%00100000		; 8-bit A
		LDA #$F0			; Free Slot Y
		JMP ($0000)			; jump to address at $00

else

		BRA SearchAlgorithm		; Just go to the search algorithm

endif

.yoshi		LDA.b #$28			; \ Yoshi always gets
		STA.w $15EA,x			; / first 2 tiles (28,2C)
.return		JML $0180E5

.default	PHX				; \
		TXA				;  | for when not using
		LDX.w $1692			;  | custom OAM pointer
		CLC				;  | routine, this is
		ADC $07F0B4,x			;  | the original SMW
		TAX				;  | code.
		LDA $07F000,x			;  |
		PLX				;  |
		STA.w $15EA,x			; /
		JML $0180E5
    
SearchAlgorithm:
		LDA #$F0			; Y offset that means available
.s		%bulkSpeedup($F0)		; \
		%bulkSpeedup($E0)		;  | pre-defined
		%bulkSpeedup($D0)		;  | macros with
		%bulkSpeedup($B0)		;  | code for each
		%bulkSpeedup($A0)		;  | individual
		%bulkSpeedup($90)		;  | slot check
		%bulkSpeedup($80)		;  |
		%bulkSpeedup($70)		;  |
		%bulkSpeedup($60)		;  |
		%bulkSpeedup($50)		;  |
		%bulkSpeedup($40)		;  |
		%speedup($3C)			;  |
		%speedup($38)			;  |
		%speedup($34)			; /
		LDA.w $18E2			; \ Yoshi?
		BNE .yoshiExists		; /
		%speedup($30)			; \ More slot
		%speedup($2C)			; / checks
		LDA.b #$28			; \ if none of the above yield which slot
.foundSlot	STA.w $15EA,x			; / then use the slot at the beginning
.return		JML $0180E5
		
.yoshiExists	LDA.b #$30			; \ if none of the above are the first free slot
		STA.w $15EA,x			; / then use the slot at the beginning (after Yoshi)
		JML $0180E5

print bytes