Timer   = $15	; how long until the sprite pops while mario stands on it
HowSlow = $03	; how slow the timer will increase, only these values apply;
;; (Fastest) $00 $01 $03 $07 $0F $1F $3F $7F $FF (slowest)
;rideable_balloon
;by smkdan

;DOESN'T USE EXTRA BIT

;balloon that you can step on for a ride

;Tilemaps for SP4

DIR = $03
PROPRAM = $04
PROPINDEX = $05
XDISPINDEX = $06
YDISPINDEX = $07
FRAMEINDEX = $08
TEMP = $09

XSPD	dcb $00,$02,$04,$03,$00,$FE,$FC,$FD
XMAR1	dcb $00,$00,$01,$01,$00,$00,$FF,$FF
XMAR2	dcb $00,$00,$00,$00,$00,$00,$FF,$FF

COUNT	dcb $40,$10,$40,$10
PAL	dcb $04,$06,$08,$0A

SPDCMP	dcb $FA,$FD
INCDEC	dcb $FF,$01

;C2: riding bit


HeightTbl dcw $FFE6,$FFD6,$FFD6
ClipTbl	dcw $0016,$0026,$0026

dcb "INIT"
	LDA $E4,x	; save
	STA $1510,x	; initial
	LDA $14E0,x	; positions
	STA $151C,x	; to
	LDA $D8,x	; some
	STA $1570,x	; sprite
	LDA $14D4,x	; ram so it
	STA $157C,x	; can respawn


	LDA $7FAB10,x		;only use custom color if made from generator
	AND #$04
	BEQ NormPal

	JSL $01ACF9		;get random
	AND #$03		;only low 2 bits
	TAY			;to be used as index

	LDA $15F6,x		;load properties
	AND #$F1		;all but pal bits

	PHB
	PHK
	PLB
	ORA PAL,y		;set palette bits
	PLB

	STA $15F6,x		;new palette

NormPal
	LDA #$FA		;fixed Yspd
	STA $AA,x		;initial Yspd

	RTL

dcb "MAIN"
	PHB
	PHK
	PLB
	JSR Run
	PLB
	RTL
Respawn
	STZ $1540,x
	LDA $1510,x
	STA $E4,x
	LDA $151C,x
	STA $14E0,x
	LDA $1570,x
	STA $D8,x
	LDA $157C,x
	STA $14D4,x
	STZ $187B,x
	STZ $1528,x

	JSR SUB_IS_OFF_SCREEN
	BNE Return_l
	JSR SUB_SMOKE
	LDA #$1E
	STA $1DF9
Return_l
	RTS
Run	JSR SUB_OFF_SCREEN_X0
	LDA $1540,x
	BEQ Normal
	CMP #$02
	BCC Respawn
	RTS
Normal	JSR GFX			;draw sprite
	STZ $15EA,x
	LDA $14C8,x
	CMP #$08          	 
	BNE Return_l           
	LDA $9D			;locked sprites?
	BNE Return_l
	LDA $15D0,x		;yoshi eating?
	BNE Return_l
	JSL $018022
	JSL $01801A

	LDA $7FAB10,x
	AND #$04
	BEQ nocon
	LDA #$09
	STA $1686,x
	JSL $019138
	LDA $18A7
	CMP #$30		;;;;;;;;;; this is the type of type it checks for!!
	BEQ pop
nocon	LDA $1528,x
	CMP #Timer
	BCC NoPop
	JSR NoPop
pop	LDA #$19
	STA $1DFC
spop	STZ $18A7
	JSR SUB_SMOKE
	LDA #$20
	STA $1540,x
	RTS
NoPop
	STZ $C2,x		;reset riding sprite, may get set later

	JSL $01A7DC		;mario interact
	BCC NoInteraction	;do nothing if there's no contact
	LDA $1558,x
	BNE NoInteraction

	JSR SUB_VERT_POS
	LDA $0F
	CMP #$E8
	BMI NoInteraction
        LDA $7D			;don't interact on rising speed
        BMI NoInteraction

;interacting, set positions
	LDA $187B,x
	AND #HowSlow
	BNE NoInc
	INC $1528,x
NoInc
	LDA #$01
	STA $C2,x		;set riding sprite for GFX routine

	LDA #$01
	STA $1471		;'riding sprite'
	STZ $7D			;no Y speed for mario

	LDA $77
	AND #$08
	BEQ NormInt
	LDA #$10
	STA $1558,x

NormInt	LDA #$E8
	LDY $187A
	BEQ NOYOSHI
	LDA #$E8-$10
NOYOSHI	CLC
	ADC $D8,x
	STA $96
	LDA $14D4,x
	ADC #$FF
	STA $97
NoInteraction
;apply speed
	INC $187B,x

NoCnt	LDA $187B,x
	LSR : LSR : LSR : LSR
	AND #$07
	TAY
	LDA XSPD,y
	STA $B6,x
	LDA $C2,x
	BEQ NoMarMov
	LDA $187B,x
	AND #$03
	BNE NoMarMov
	LDA $94
	CLC
	ADC XMAR1,y
	STA $94
	LDA $95
	ADC XMAR2,y
	STA $95
NoMarMov
	LDY $C2,x		;load ride bit as index
	LDA SPDCMP,y
	STA $AA,x

Return
	RTS        

SUB_SMOKE
	JSR SUB_IS_OFF_SCREEN
	BNE NoSmoke
	LDY #$03
LoopSmk	LDA $17C0,y
	BEQ Found
	DEY
	BPL LoopSmk
	RTS
Found	LDA #$01
	STA $17C0,y
	LDA $E4,x
	CLC
	ADC #$08
	STA $17C8,y
	LDA $D8,x
	STA $17C4,y
	LDA #$1B
	STA $17CC,y
NoSmoke	RTS
			
;=====

TILEMAP	dcb $E0,$E2,$C4,$C6

XDISP	dcb $00,$10,$00,$10

YDISP	dcb $FE,$FE,$0E,$0E
	dcb $00,$00,$0E,$0E

GFX	JSL $20CA4F
	LDA $C2,x	;stepped on?
	ASL A		;x4
	ASL A
	STA FRAMEINDEX

	LDA $157C,x	;direction...
	STA DIR

	LDA $15F6,x	;properties...
	STA PROPRAM

	LDX #$00	;loop index

OAM_Loop
	LDA $00
	CLC
	ADC XDISP,x
	STA $0300,y	;xpos

	TXA	
	CLC
	ADC FRAMEINDEX	;variable YDISP
	PHX
	TAX
	LDA $01
	CLC
	ADC YDISP,x
	STA $0301,y	;ypos
	PLX

	LDA TILEMAP,x
	STA $0302,y	;chr

	LDA PROPRAM
	ORA $64
	STA $0303,y	;properties

	INY
	INY
	INY
	INY
	INX
	CPX #$04	;4 tiles
	BNE OAM_Loop

	LDX $15E9		;restore sprite index

	LDY #$02		;16x16 tiles
	LDA #$03		;4 tiles
	JSL $01B7B3

	RTS			;return
	
;=================
;BORROWED ROUTINES
;=================


	

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_OFF_SCREEN
; This subroutine deals with sprites that have moved off screen
; It is adapted from the subroutine at $01AC0D
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                    
SPR_T12             dcb $40,$B0
SPR_T13             dcb $01,$FF
SPR_T14             dcb $30,$C0,$A0,$C0,$A0,$F0,$60,$90		;bank 1 sizes
		            dcb $30,$C0,$A0,$80,$A0,$40,$60,$B0		;bank 3 sizes
SPR_T15             dcb $01,$FF,$01,$FF,$01,$FF,$01,$FF		;bank 1 sizes
					dcb $01,$FF,$01,$FF,$01,$00,$01,$FF		;bank 3 sizes

SUB_OFF_SCREEN_X1   LDA #$02                ; \ entry point of routine determines value of $03
                    BRA STORE_03            ;  | (table entry to use on horizontal levels)
SUB_OFF_SCREEN_X2   LDA #$04                ;  | 
                    BRA STORE_03            ;  |
SUB_OFF_SCREEN_X3   LDA #$06                ;  |
                    BRA STORE_03            ;  |
SUB_OFF_SCREEN_X4   LDA #$08                ;  |
                    BRA STORE_03            ;  |
SUB_OFF_SCREEN_X5   LDA #$0A                ;  |
                    BRA STORE_03            ;  |
SUB_OFF_SCREEN_X6   LDA #$0C                ;  |
                    BRA STORE_03            ;  |
SUB_OFF_SCREEN_X7   LDA #$0E                ;  |
STORE_03			STA $03					;  |            
					BRA START_SUB			;  |
SUB_OFF_SCREEN_X0   STZ $03					; /

START_SUB           JSR SUB_IS_OFF_SCREEN   ; \ if sprite is not off screen, return
                    BEQ RETURN_35           ; /
                    LDA $5B                 ; \  goto VERTICAL_LEVEL if vertical level
                    AND #$01                ; |
                    BNE VERTICAL_LEVEL      ; /     
LDA $14D4,x
CLC
ADC $1D
CMP #$00
BEQ ERASE_SPRITE
                    LDA $14D4,x             ; | (if adding 0x50 to the sprite y position would make the high byte underflow...              ; | 
                    CMP #$FF                ; | ;underflowed?
                    BEQ ERASE_SPRITE        ; /    ...erase the sprite
                    LDA $167A,x             ; \ if "process offscreen" flag is set, return
                    AND #$04                ; |
                    BNE RETURN_35           ; /
                    LDA $13                 ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0756 VC:176 00 FL:205
                    AND #$01                ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0780 VC:176 00 FL:205
                    ORA $03                 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0796 VC:176 00 FL:205
                    STA $01                 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0820 VC:176 00 FL:205
                    TAY                     ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0844 VC:176 00 FL:205
                    LDA $1A                 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0858 VC:176 00 FL:205
                    CLC                     ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0882 VC:176 00 FL:205
                    ADC SPR_T14,y           ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0896 VC:176 00 FL:205
                    ROL $00                 ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizcHC:0928 VC:176 00 FL:205
                    CMP $E4,x               ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:0966 VC:176 00 FL:205
                    PHP                     ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:0996 VC:176 00 FL:205
                    LDA $1B                 ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdizCHC:1018 VC:176 00 FL:205
                    LSR $00                 ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdiZCHC:1042 VC:176 00 FL:205
                    ADC SPR_T15,y           ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdizcHC:1080 VC:176 00 FL:205
                    PLP                     ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F0 P:eNvMXdizcHC:1112 VC:176 00 FL:205
                    SBC $14E0,x             ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1140 VC:176 00 FL:205
                    STA $00                 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:1172 VC:176 00 FL:205
                    LSR $01                 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:1196 VC:176 00 FL:205
                    BCC SPR_L31             ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZCHC:1234 VC:176 00 FL:205
                    EOR #$80                ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZCHC:1250 VC:176 00 FL:205
                    STA $00                 ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1266 VC:176 00 FL:205
SPR_L31             LDA $00                 ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1290 VC:176 00 FL:205
                    BPL RETURN_35           ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1314 VC:176 00 FL:205
ERASE_SPRITE        LDA $14C8,x             ; \ if sprite status < 8, permanently erase sprite
                    CMP #$08                ; |
                    BCC KILL_SPRITE         ; /    
                    LDY $161A,x             ;A:FF08 X:0007 Y:0001 D:0000 DB:01 S:01F3 P:envMXdiZCHC:1108 VC:059 00 FL:2878
                    CPY #$FF                ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdiZCHC:1140 VC:059 00 FL:2878
                    BEQ KILL_SPRITE         ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdizcHC:1156 VC:059 00 FL:2878
                    LDA #$00                ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdizcHC:1172 VC:059 00 FL:2878
                    STA $1938,y             ;A:FF00 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdiZcHC:1188 VC:059 00 FL:2878
KILL_SPRITE         LDA $186C,x
                    BEQ KILL
                    JSR Respawn
                    LDA #$07
                    STA $1540,x
                    STZ $186C,x
RETURN_35           RTS                     ; return
KILL                STZ $14C8,x
                    RTS
VERTICAL_LEVEL      LDA $167A,x             ; \ if "process offscreen" flag is set, return
                    AND #$04                ; |
                    BNE RETURN_35           ; /
                    LDA $13                 ; \
                    LSR A                   ; | 
                    BCS RETURN_35           ; /
                    LDA $E4,x               ; \ 
                    CMP #$00                ;  | if the sprite has gone off the side of the level...
                    LDA $14E0,x             ;  |
                    SBC #$00                ;  |
                    CMP #$02                ;  |
                    BCS ERASE_SPRITE        ; /  ...erase the sprite
                    LDA $13                 ;A:0000 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:1218 VC:250 00 FL:5379
                    LSR A                   ;A:0016 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1242 VC:250 00 FL:5379
                    AND #$01                ;A:000B X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1256 VC:250 00 FL:5379
                    STA $01                 ;A:0001 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1272 VC:250 00 FL:5379
                    TAY                     ;A:0001 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1296 VC:250 00 FL:5379
                    LDA $1C                 ;A:001A X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0052 VC:251 00 FL:5379
                    CLC                     ;A:00BD X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0076 VC:251 00 FL:5379
                    ADC SPR_T12,y           ;A:00BD X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0090 VC:251 00 FL:5379
                    ROL $00                 ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:enVMXdizCHC:0122 VC:251 00 FL:5379
                    CMP $D8,x               ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0160 VC:251 00 FL:5379
                    PHP                     ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0190 VC:251 00 FL:5379
                    LDA.W $001D             ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F2 P:eNVMXdizcHC:0212 VC:251 00 FL:5379
                    LSR $00                 ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:enVMXdiZcHC:0244 VC:251 00 FL:5379
                    ADC SPR_T13,y           ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:enVMXdizCHC:0282 VC:251 00 FL:5379
                    PLP                     ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:envMXdiZCHC:0314 VC:251 00 FL:5379
                    SBC $14D4,x             ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0342 VC:251 00 FL:5379
                    STA $00                 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0374 VC:251 00 FL:5379
                    LDY $01                 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0398 VC:251 00 FL:5379
                    BEQ SPR_L38             ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0422 VC:251 00 FL:5379
                    EOR #$80                ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0438 VC:251 00 FL:5379
                    STA $00                 ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0454 VC:251 00 FL:5379
SPR_L38             LDA $00                 ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0478 VC:251 00 FL:5379
                    BPL RETURN_35           ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0502 VC:251 00 FL:5379
                    BMI ERASE_SPRITE        ;A:8AFF X:0002 Y:0000 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0704 VC:184 00 FL:5490

SUB_IS_OFF_SCREEN   LDA $15A0,x             ; \ if sprite is on screen, accumulator = 0 
                    ORA $186C,x             ; |  
                    RTS                     ; / return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_VERT_POS
; This routine determines if Mario is above or below the sprite.  It sets the Y register
; to the direction such that the sprite would face Mario
; It is ripped from $03B829
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SUB_VERT_POS		LDY #$00               ;A:25A1 X:0007 Y:0001 D:0000 DB:03 S:01EA P:envMXdizCHC:0130 VC:085 00 FL:924
					LDA $96                ;A:25A1 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdiZCHC:0146 VC:085 00 FL:924
					SEC                    ;A:2546 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdizCHC:0170 VC:085 00 FL:924
					SBC $D8,x              ;A:2546 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdizCHC:0184 VC:085 00 FL:924
					STA $0F                ;A:25D6 X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0214 VC:085 00 FL:924
					LDA $97                ;A:25D6 X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0238 VC:085 00 FL:924
					SBC $14D4,x            ;A:2501 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdizcHC:0262 VC:085 00 FL:924
					BPL SPR_L11            ;A:25FF X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0294 VC:085 00 FL:924
					INY                    ;A:25FF X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0310 VC:085 00 FL:924
SPR_L11				RTS                    ;A:25FF X:0007 Y:0001 D:0000 DB:03 S:01EA P:envMXdizcHC:0324 VC:085 00 FL:924


