; ElectricLove.asm
;			by Maddy, allegedly

; Created for 'Daddy's Castle' in Super "Sonic Saves the World" World
; Draws a tile at the top of the screen which follows the player's x-position exactly and spawns a sprite on an interval

; Feel free to reuse this code however you want. HammerBrother should be credited. Crediting me is appreciated too :)

; Usage: This is intended to be used as an UberASM library file, called from many level files

; ------------------------------ 
; CONFIG OPTIONS
; ------------------------------ 

; the ID of the sprite to spawn
!sprite = $2B

; whether the spawned sprite is custom
!is_custom = 0

; the x-position of the sprite relative to the aimer
!sprite_x_offset = -$0008

; the amount of frames after the level starts before the first sprite spawn
!first_cooldown = $60

; the amount of frames between sprite spawns
!cooldown = $90

; this array of values is used to modify the cooldown 
; based on the player's powerup state at the moment that it starts
; vanilla powerup states are: 0 - small, 1 - big, 2 - cape, 3 - fire
; the corresponding amount will be added to the cooldown amount configured above
; if you do not wish to use this, you can set all of these values to $00
Cooldown_Bonus:
	db $20, $10, $00, $00
	
; the y-position relative to the camera where the aimer rests, and where it spawns sprites from
!aimer_y_rest = $08

; whether to draw the aimer
!draw_aimer = 1

; the OAM tile ID of the aimer
!aimer_tile = $CE

; the OAM properties bits of the aimer
!aimer_props = %00111001

; ------------------------------
; FreeRAM ADDRESSES
; make sure these don't overlap with RAM already in use by other ASM in these levels
; ------------------------------

; the aimer's current x-position in the level
; -> 2 bytes
!RAM_aimer = $0F5E

; the aimer's current y-position relative to the camera's y-position
; -> 1 byte
!RAM_aimer_y = $0F60

; the cooldown timer for sprite spawning
; -> 1 byte
!RAM_cooldown = $0F61

; ------------------------------ 
; GAME LOGIC CODE
; ------------------------------ 

macro nexttile()
	?loop:
	LDA $0201|!addr,y
	CMP #$F0
	BEQ ?end
	INY #$4
	CPY #$00
	BNE ?loop
    RTS
	?end:
endmacro

init:
	REP #$20
	LDA $94
	CLC : ADC #$0008
	STA !RAM_aimer
	SEP #$20
	LDA #!aimer_y_rest
	STA !RAM_aimer_y
	LDA #!first_cooldown
	STA !RAM_cooldown
	RTL

main:
	; pause check
	LDA $13D4
	BEQ +
	RTL
	+

	; set position
	REP #$20
	LDA $94
	CLC : ADC #$0008
	STA !RAM_aimer
	SEP #$20
	
	; lerp y
	LDA $14
	AND #%00000011
	BNE +
	LDA !RAM_aimer_y
	CMP #!aimer_y_rest
	BCS +
	INC	!RAM_aimer_y
	+
	
	; spawn lightning
	LDA $9D
	BNE +
	DEC !RAM_cooldown
	BNE +	
	; reset cooldown
	LDA #!cooldown
	LDX $19
	CLC : ADC Cooldown_Bonus,X
	STA !RAM_cooldown
	; spawn sprite
	LDA #!sprite
	if !is_custom
		SEC	
	else
		CLC
	endif
	JSL SpawnSprite	
	; sfx
	LDA #$25
	STA $1DF9
	; set heart y
	LDA #$02
	STA !RAM_aimer_y
	; set lightning position
	REP #$20
	LDA !RAM_aimer	
	CLC : ADC #!sprite_x_offset
	SEP #$20
	STA $E4,Y
	XBA
	STA $14E0,Y	
	LDA #$C0
	STA $D8,Y
	LDA #$00
	STA $14D4,Y	
	+
	
	; draw
	just_draw:	
	if !draw_aimer
		LDY #$30
		%nexttile()
		
		REP #$20
		LDA !RAM_aimer
		SEC : SBC #$0004
		SEC : SBC $1462
		SEP #$20
		
		XBA
		CMP #$00
		BNE skip_draw
		XBA
		
		STA $0200,Y	; X
		LDA !RAM_aimer_y
		STA $0201,Y	; Y
		LDA #!aimer_tile
		STA $0202,Y ; tile
		LDA #!aimer_props
		STA $0203,Y ; props	

		; extra bits
		PHY
		TYA
		LSR #2
		TAY
		LDA #$00
		STA $0420,Y
		PLY
	endif
	
	skip_draw:
	
	RTL
	
;Routine that spawns a normal or custom sprite with initial speed at the position (+offset)
;of the calling sprite and returns the sprite index in Y

;Input:  A   = number of sprite to spawn
;        C   = Carry/Custom (CLC = CLear Custom, SEC = SEt Custom :P)
;Output: Y   = index to spawned sprite (#$FF means no sprite spawned)
;        C   = Carry Set = spawn failed, Carry Clear = spawn successful.

SpawnSprite:
	PHX
	XBA
	LDX #$0B
	-
		LDA !14C8,x
		BEQ +
			DEX
		BPL -
		SEC
		BRA .no_slot
	+
	XBA
	STA !9E,x
	JSL $07F7D2
	
	BCC +
		LDA !9E,x
		STA !7FAB9E,x
		
		JSL $0187A7			; this sucker kills $00-$02
		
		LDA #$08
		STA !7FAB10,x
	+
	
	LDA #$01
	STA !14C8,x
	
	TXY
	PLX	
	CLC
	RTL	
	
.no_slot:
	TXY
	PLX
	RTL