;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Platforms that go in a direction, shake, and then fall at the end.
;;   falling is a little bit iffy, as Mario tends to get stuck on it sometimes.
;;   NOTE: Do not put on Y = 0, it doesn't work.
;; Description:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

incsrc subroutinedefs_trasm.asm

LENGTH = $C1

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

dcb "INIT"	
		STZ $1540,x
		LDA #$FF
		STA $1504,x
		RTL                 

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

dcb "MAIN"
		PHB               ; \
		PHK               ;  | main sprite function, just calls local subroutine
		PLB               ;  |
		JSR SCODE_START   ;  |
		PLB               ;  |
		RTL               ; /

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite main code 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SCODE_START:	JSR SUB_GFX             ; Graphics Routine
		JSL SubOffscreenX0
		JSR CALC_DIR

		LDA $9D                 ; \ if sprites locked, return
		BNE RETURN		; /
		LDA $14C8,x
		CMP #$04
		BEQ RETURN
		LDA $1540,x
		BEQ IDLE
		CMP #$01
		BEQ DOWNWARD
		CMP #$02
		BEQ FALL
		JMP GO_UPDATE
RETURN:		RTS

CALC_DIR:	LDA $1504,x
		CMP #$FF
		BNE RETURN
		LDA $E4,x
		AND #$10
		LSR
		CLC
		ADC $D8,x
		AND #$18
		LSR
		LSR
		LSR
		STA $1504,x
		RTS
	
IDLE:		JSL $81A7DC		;interact with Mario
		BCC RETURN
		LDA $97
		CMP $14D4,x
		BEQ NEXT_STEP
		BCS RETURN
NEXT_STEP:	LDA $96
		CLC
		ADC #$18
		CMP $D8,x
		BCS RETURN
		LDA $7D
		BEQ RETURN
		CMP #$80
		BCS RETURN
		LDA #LENGTH
		STA $1540,x
		RTS
	
DOWNWARD:	INC $1540,x	
		INC $AA,x
		JSL $81A7DC		;interact with Mario
		BCC SKIP2
		JSL $81B44F             ; interact with sprites
		LDA $15
		AND #$C0
		BNE SKIP2
		LDA $AA,x
		STA $7D
		RTS
SKIP2:		JSL $81802A
		RTS

FALL:		STZ $B6,x
		STZ $AA,x
		JSL $81802A		; Apply speed.	
		JSL $81A7DC		;interact with Mario
		BCC SKIP
		JSL $81B44F             ; interact with sprites
SKIP:		RTS

UPDATE:		JSL $81802A		; Apply speed.	
		JSL $81B44F             ; interact with sprites
		LDA $1491               ; amount to move Mario                    
		STA $1528,x             ; prevent Mario from sliding horizontally
		RTS

GO_UPDATE:	STZ $AA,x
		STZ $B6,x
MOVE_UPDATE:	LDA $1504,x
		BEQ UP_DIR
		CMP #$01
		BEQ LEFT_DIR
		CMP #$02
		BEQ DOWN_DIR
		BRA RIGHT_DIR
		RTS

UP_DIR:		LDA #$F0
		STA $AA,x		; Store Sprite's Y Speed which is F0.
		JSR SHIFT_LR
		BRA UPDATE

DOWN_DIR:	LDA #$10
		STA $AA,x		; Store Sprite's Y Speed which is 10.
		JSR SHIFT_LR
		BRA UPDATE

LEFT_DIR:	LDA #$F0
		STA $B6,x		; Store Sprite's X Speed which is F0.
		JSR SHIFT_UD
		BRA UPDATE

RIGHT_DIR:	LDA #$10
		STA $B6,x		; Store Sprite's X Speed which is 10.
		JSR SHIFT_UD
		BRA UPDATE

SHIFT_LR:	LDA $1540,x
		CMP #$20
		BCS R_TS
		LDA $13
		AND #$01
		BEQ INC_L
		INC $E4,x
		INC $E4,x
		BRA UPDATE_X
INC_L:		DEC $E4,x
		DEC $E4,x
UPDATE_X:	JSL $818022
R_TS:		RTS


SHIFT_UD:	LDA $1540,x
		CMP #$20
		BCS R_TS
		LDA $13
		AND #$01
		BEQ INC_U
		INC $D8,x
		INC $D8,x
		BRA UPDATE_Y
INC_U:		DEC $D8,x
		DEC $D8,x
UPDATE_Y:	JSL $81801A
		RTS

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

TILE:		db $27,$29,$2B,$04,$02,$00,$27,$06,$2B,$00,$02,$04

TILE_D:		db $00,$03,$06,$09

XDISP:  	db $F0,$00,$10
	
YDISP:  	db $FC,$FC,$FC

PROPERTY:	db $0F,$4F,$0F,$0F

SUB_GFX:
	JSL GetDrawInfo
	LDA $1504,x
	STA $03
	PHX			
SINGLE:	LDX #$02
Loop:	LDA $00
	CLC
	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
	
	STX $13C8
	PHX			;/ as the displacement. For the second tile, F0 is added to make it higher than the first.
	LDX $03
	LDA TILE_D,x
	CLC
	ADC $13C8
	TAX
	LDA TILE,x
	STA $0302,y
	PLX
E_TILE:	PHX
	LDA $64
	AND #$30
	LDX $03
	ORA PROPERTY,x
	STA $0303,y		
	PLX

	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 Loop		; 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 #$02		; A -> number of tiles drawn - 1.
				; I drew 2 tiles, so 2-1 = 1. A = 01.
	JSL $81B7B3		; Call the routine that draws the sprite.
	RTS			; Never forget this!

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ROUTINES FROM THE LIBRARY ARE PASTED BELOW
; You should never have to modify this code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


SUB_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               ; \ 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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; hammer routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NEW_SPRITE_NUM = $7FAB9E
EXTRA_BITS = $7FAB10
X_OFFSET            dcb $06,$FA
X_OFFSET2           dcb $00,$FF
                    
SUB_HAMMER_THROW    LDA $15A0,x             ; \ no egg if off screen
                    ORA $186C,x             ;  |
                    ORA $15D0,x
                    BNE RETURN67
                    
                    JSL $82A9DE             ; \ get an index to an unused sprite slot, return if all slots full
                    BMI RETURN67            ; / after: Y has index of sprite being generated

                    lda #$10
		    sta $1df9 
                    
                    LDA #$08                ; \ set sprite status for new sprite
                    STA $14C8,y             ; /

                    PHX
                    LDA NEW_SPRITE_NUM,x
                    INC A
                    TYX
                    STA NEW_SPRITE_NUM,x
                    PLX

                    PHY
                    LDA $157C,x
                    TAY
                    LDA $E4,x               ; \ set x position for new sprite
                    CLC
                    ADC X_OFFSET,y
                    PLY
                    STA $00E4,y

                    PHY
                    LDA $157C,x
                    TAY
                    LDA $14E0,x             ;  |
                    ADC X_OFFSET2,y
                    PLY
                    STA $14E0,y             ; /

                    LDA $D8,x               ; \ set y position for new sprite
                    ;SEC                     ;  | (y position of generator - 1)
                    SBC #$00                ;  |
                    STA $00D8,y             ;  |
                    LDA $14D4,x             ;  |
                    SBC #$00                ;  |
                    STA $14D4,y             ; /

                    PHX                     ; \ before: X must have index of sprite being generated
                    TYX                     ;  | routine clears *all* old sprite values...
                    JSL $87F7D2             ;  | ...and loads in new values for the 6 main sprite tables
                    JSL $8187A7             ;  get table values for custom sprite
                    LDA #$88
                    STA EXTRA_BITS,x
                    PLX                       ; / 

                    LDA $157C,x
                    STA $157C,y
                
                    
                    
RETURN67            RTS                     ; return

