;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Ice Brother's Iceball, by NamelessProtagonist
;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Uses first extra bit: NO
;;
;; Extra Property Byte 1
;;    bit 0 - enable spin killing
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

incsrc subroutinedefs_trasm.asm

                    EXTRA_PROP_1 = $7FAB28

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

                    dcb "INIT"
                    JSL SubHorizPos
                    TYA
                    STA $157C,x

                    LDA #$C0
                    STA $AA,x
                    LDA $157C,x             ; \ set x speed based on direction
                    BEQ RIGHT 
LEFT:
                    LDA #$E0          ;  |
                    BRA SET
RIGHT:
                    LDA #$20
SET:
                    STA $B6,x               ; /
                    JSL $81802A
                    RTL                 

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

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


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

X_SPEED             dcb $20,$E0
Y_SPEED             dcb $C0,$C0,$C0,$C0
KILLED_X_SPEED      dcb $F0,$10

RETURN              RTS
SPRITE_CODE_START   JSR SUB_GFX             ; graphics routine
                    LDA $14C8,x             ; \ 
                    CMP #$08                ;  | if status != 8, return
                    BNE RETURN              ; /
                    LDA $9D                 ; \ if sprites locked, return
                    BNE RETURN              ; /

                    JSL SubOffscreenX3   ; handle off screen situation
                    
                    LDA $1588,x             ; \ if sprite is in contact with an object...
                    AND #$07                ;  |
                    BEQ NO_OBJ_CONTACT      ;  |
                    LDA $157C,x             ;  | flip the direction status
                    EOR #$01                ;  |
                    STA $157C,x             ; /
                    LDA #$01                ; \ sound effect
                    STA $1DFC               ; /
                    JSR SUB_SMOKE
                    LDA $B6,x 
                    EOR #$FF
                    INC A
                    STA $B6,x
		    STZ $14C8,x 
		    
NO_OBJ_CONTACT
                    LDA $1588,x             ; if on the ground, reset the turn counter
                    AND #$04
                    BEQ IN_AIR

                    LDA $1528,x
                    INC A
                    AND #$03
                    STA $1528,x
                    TAY
                    LDA Y_SPEED,y           
                    STA $AA,x               
                    
                    LDY $157C,x             ; \ set x speed based on direction
                    LDA X_SPEED,y           ;  |
                    STA $B6,x               ; /
                                        
IN_AIR              JSL $81802A             ; update position based on speed values
 
DONE_WITH_SPEED     JSL $818032             ; interact with sprites
                    JSL $81A7DC             ; check for mario/sprite contact (carry set = contact)
                    BCC RETURN_24           ; return if no contact

                    LDA $1490               ; \ if mario star timer > 0, goto HAS_STAR 
                    BNE HAS_STAR            ; / NOTE: branch to RETURN_24 to disable star killing
                    LDA #$40                ; \ Freeze Mario
                    STA $18BD               ; /
                    LDA #$01                ; \ sound effect
                    STA $1DFC               ; /
                    STZ $14C8,x             ; Kill iceball
                    JSR SUB_SMOKE
                    LDA $187A               ; \ if not riding Yoshi
		    BNE LOSEYOSHI           ; / skip over routine
                    ;JSL $80F5B7             ; Hurt Mario.  Delete this line if you want the iceball to just freeze him.
RETURN_24           RTS                     ; final return

LOSEYOSHI           PHX                     ; back up X (sprite index)
                    PHY                     ; back up Y
                    LDX $18E2               ; Yoshi sprite index +1, would be zero if no Yoshi
                    LDA #$10                ;
                    STA $163D,x             ;
                    LDA #$03                ; \ turn off
                    STA $1DFA               ; / Yoshi drums
                    LDA #$13                ; \ play lose-Yoshi
                    STA $1DFC               ; / sound effect
                    LDA #$02                ; \ set Yoshi to
                    STA $C1,x               ; / running-away state
                    STZ $187A               ; reset riding Yoshi flag
                    STZ $0DC1               ;
                    LDA #$C0                ; \ make Mario
                    STA $7D                 ; / jump upwards
                    STZ $7B                 ; no X movement
                    LDY $157B,x             ; \
                    PHX                     ;  | set Yoshi's
                    TYX                     ;  | running-away
                    LDA $02A4B3,x           ;  | X speed
                    PLX                     ;  |
                    STA $B5,x               ; /
                    STZ $1593,x             ;
                    STZ $151B,x             ;
                    STZ $18AE               ;
                    LDA #$30                ; \ Mario invincible
                    STA $1497               ; / timer
                    PLY                     ; restore Y
                    PLX                     ; restore X (sprite index)
                    RTS

HAS_STAR            LDA #$02                ; \ status = 2 (being killed by star)
                    STA $14C8,x             ; /
                    LDA #$D0                ; \ set y speed
                    STA $AA,x               ; /
                    JSL SubHorizPos        ; get new direction
                    LDA KILLED_X_SPEED,y    ; \ set x speed based on direction
                    STA $B6,x               ; /
                    ;INC $18D2               ; increment number consecutive enemies killed
                    LDA $18D2               ; \
                    CMP #$07
                    BCC NO_RESET2           ;  |
                    LDA #$07                ;  |
                    STA $18D2               ; /   
NO_RESET2           TAY
                    LDA STAR_SOUNDS,y       ;  |    ... play sound effect
                    STA $1DF9               ; /
NO_SOUND2           RTS                     ; final return

STAR_SOUNDS:        dcb $13,$13,$14,$15,$16,$17,$18,$19

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite graphics routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

TILEMAP             dcb $3D,$3E,$3D,$3E

SUB_GFX             JSL GetDrawInfo      ; 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)
                    STA $0300,y             ; /

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

                    LDA $15F6,x             ; tile properties xyppccct, format
                    LDX $02                 ; \ if direction == 0...
                    BNE NO_FLIP             ;  |
                    ORA #$40                ; /    ...flip tile
NO_FLIP             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 $81B7B3             ; / don't draw if offscreen
                    RTS                     ; return
                    

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_CHANGE_DIR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                    ;org $019098

SUB_CHANGE_DIR      ;LDA $15AC,x
                    ;BNE LABEL41
                    ;LDA #$08   
                    ;STA $15AC,x
                    LDA $B6,x  
                    EOR #$FF   
                    INC A      
                    STA $B6,x  
                    LDA $157C,x
                    EOR #$01   
                    JSR SUB_SMOKE
		    STA $157C,x
LABEL41             RTS        

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; display smoke effect for bullet bill shooter
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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

X_OFFSET            dcb $F4,$0C

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

