;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Electricity, by mikeyk
;;
;; Description: This sprite bounces between two surfaces and can only be killed with a
;; star.
;;
;; Uses first extra bit: YES
;; If the first extra bit is set, the sprite will bounce vertically between two surfaces.
;; Otherwise the sprite will bounce horizontally between two surfaces.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

incsrc subroutinedefs_trasm.asm

                    EXTRA_BITS = $7FAB10

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

                    dcb "INIT"
                    PHY
                    JSL SubHorizPos
                    TYA
                    STA $157C,x
                    PLY
                    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 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

RETURN              RTS
SPRITE_CODE_START   JSR SPRITE_GRAPHICS       ; graphics routine
                    LDA $14C8,x             ; \ 
                    CMP #$08                ;  | if status != 8, return
                    BNE RETURN              ; /
                    JSL SubOffscreenX0  ; handle off screen situation
                    LDA $9D                 ; \ if sprites locked, return
                    BNE RETURN              ; /

                    LDA EXTRA_BITS,x
                    AND #$04
                    BEQ HORIZ_MOVEMENT
                    
                    JSR HANDLE_VERT
                    BRA CHECK_CONTACT
                    
HORIZ_MOVEMENT      JSR HANDLE_HORIZ
   
CHECK_CONTACT       JSL $81A7DC             ; check for mario/sprite contact (carry set = contact)
                    BCC RETURN_24           ; return if no contact

SPRITE_WINS         LDA $15D0,x             ;  |   ...or sprite being eaten...
                    BNE RETURN_24           ; /   ...return
                    LDA $1490               ; \ if mario star timer > 0, goto HAS_STAR 
                    BNE HAS_STAR            ; / NOTE: branch to RETURN_24 to disable star killing                  
                    LDA $187A               ; \ if riding sprite...
                    BNE RETURN_24 
                    JSL $80F5B7             ; hurt mario
RETURN_24           RTS                     ; final return

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

HAS_STAR            LDA #$02                ; \ status = 2 (being killed by star)
                    STA $14C8,x             ; /
                    INC $18D2               ; increment number consecutive enemies killed
                    LDA $18D2               ; \
                    CMP #$08                ;  | if consecutive enemies stomped >= 8, reset to 8
                    BCC NO_RESET2           ;  |
                    LDA #$08                ;  |
                    STA $18D2               ; /   
NO_RESET2           JSL $82ACE5             ; give mario points
                    LDY $18D2               ; \ 
                    CPY #$08                ;  | if consecutive enemies stomped < 8 ...
                    BCS NO_SOUND2           ;  |
                    LDA STAR_SOUNDS,y       ;  |    ... play sound effect
                    STA $1DF9               ; /
NO_SOUND2           RTS                     ; final return


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

X_SPEED             dcb $18,$E8

HANDLE_HORIZ        LDY $157C,x             ; \ set x speed based on direction
                    LDA X_SPEED,y           ;  |
                    STA $B6,x               ; /
                    
                    STZ $AA,x
                    JSL $81802A             ; update position based on speed values
         
                    LDA $1588,x             ; \ if sprite is in contact with an object...
                    AND #$03                ;  |
                    BEQ NO_CONTACT          ;  |
                    LDA $157C,x             ;  | flip the direction status
                    EOR #$01                ;  |
                    STA $157C,x             ; /
NO_CONTACT          RTS


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

Y_SPEED             dcb $18,$E8

HANDLE_VERT         LDY $157C,x             ; \ set x speed based on direction
                    LDA Y_SPEED,y           ;  |
                    STA $AA,x               ; /
                    
                    STZ $B6,x
                    JSL $81802A             ; update position based on speed values
         
                    LDA $1588,x             ; \ if sprite is in contact with an object...
                    AND #$0C                ;  |
                    BEQ NO_CONTACT2         ;  |
                    LDA $157C,x             ;  | flip the direction status
                    EOR #$01                ;  |
                    STA $157C,x             ; /
NO_CONTACT2         RTS


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

TILEMAP             dcb $E6,$C8

SPRITE_GRAPHICS     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 #$01                ;  |
                    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)
                    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)...
                    INY                     ;  |    ...we wrote 1 16x16 tile...
                    INY                     ;  |    ...sprite OAM is 8x8...
                    INY                     ; /    ...so increment 4 times

                    PLX                     ; pull, X = sprite index
                    LDY #$02                ; \ 460 = 2 (all 16x16 tiles)
                    LDA #$00                ;  | A = (number of tiles drawn - 1)
                    JSL $81B7B3             ; / don't draw if offscreen
                    RTS                     ; return
                    


