;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; SMW Vertical Fireball (sprite 33), by imamelia
;;
;; This is a disassembly of sprite 33 in SMW, the vertical fireball (or Podoboo, if you prefer).
;;
;; Uses first extra bit: NO
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; defines and tables
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

YSpeeds:
db $F0,$DC,$D0,$C8,$C0,$B8,$B2,$AC
db $A6,$A0,$9A,$96,$92,$8C,$88,$84
db $80,$04,$08,$0C,$10,$14

!Timer2Check = $70

Tilemap:
db $06,$06,$16,$16,$07,$07,$17,$17,$16,$16,$06,$06,$17,$17,$07,$07

XDisp:
db $00,$08,$00,$08

YDisp:
db $00,$00,$08,$08

XFlip:
db $00,$40,$00,$40

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; init routine wrapper
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

print "INIT ",pc

PHB
PHK
PLB
JSR PodobooInit
PLB
RTL

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; init routine
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PodobooInit:

LDA $D8,x	; sprite Y position low byte
STA $1528,x	; save in multi-purpose table
LDA $14D4,x	; sprite Y position high byte
STA $151C,x	; same
LDA #$80
STA $190E

LiquidContactLoop:	;

LDA $D8,x	;
CLC		;
ADC #$10	;
STA $D8,x	; shift the sprite's Y position down 1 tile
LDA $14D4,x	;
ADC #$00	;
STA $14D4,x	;

JSL $019138	; make the sprite interact with objects

LDA $164A,x		; if the sprite is not in contact with water or lava...
BEQ LiquidContactLoop	; shift it down again until it is

JSR SetYSpeed		;

LDA #$20			; set the timer until it jumps
STA $1540,x		;

STZ $190E

LDA $D8,x
STA $1504,x

LDA $14D4,x
STA $1510,x
RTS			;

; Note: This explains why the Podoboo freezes the game when sprite buoyancy is not enabled.
; The init routine checks to see if the sprite is in contact with water or lava using $164A,x,
; and if it is not, the code jumps back to the beginning of the loop, shifts the sprite down a tile,
; and checks again.  BUT...if sprite buoyancy is not enabled, $164A,x will never get set.  This
; sends the init routine into an infinite loop.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; main routine wrapper
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

print "MAIN ",pc
PHB
PHK
PLB
JSR PodobooMain
PLB
RTL

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; main routine
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PodobooMain:

STZ $15D0,x	; clear the...being eaten flag??
;LDA $7F0E0E
LDA $1540,x
	; check the timer
BEQ StartMoving	; if it is zero, then make the fireball start going up
DEC		; if it is down to 01...
BNE Return0	; this is the last frame before the fireball will start moving,
;LDA #$27		; so play a fiery sound effect
;STA $1DFC	;
Return0:		;
RTS		;

StartMoving:	;

LDA $9D		; if sprites are locked...
BEQ NotLocked	;
JMP PodobooGFX	; skip the speed setting, lava trail, etc.

NotLocked:	;
JSL $01A7DC		; interact with the player
JSR SetAnimationFrame	;
;JSR SetAnimationFrame	; instead of calling this twice, I just modified the subroutine itself


LDA $15F6,x		;
AND #$7F		; clear the Y-flip bit of the sprite palette and GFX page...
LDY $AA,x		; if the sprite's Y speed is negative...
BMI NoFlip		; don't Y-flip the sprite's graphics
INC $1602,x		;
INC $1602,x		; increment the animation frame
ORA #$80			; and Y-flip the sprite's graphics
NoFlip:			;
STA $15F6,x		;


STA $7FFFFD

LDA $1510,x
XBA
LDA $1504,x
REP #$20
STA $00
SEP #$20

LDA $14D4,x
XBA
LDA $D8,x
REP #$20
STA $02

LDA $00
SEC
SBC $02
CMP #$0020
SEP #$20
BCS DontCheckForLava


LDA #$80
STA $190E
JSL $019138		; check for contact with objects
STZ $190E



DontCheckForLava:



LDA $164A,x		; if the sprite is in lava or water...
BEQ NoResetYSpeed		;
LDA $AA,x		; and the sprite's Y speed is positive...
BMI NoResetYSpeed		;

;JSL $01ACF9		;
;AND #$3F		;
;ADC #$60		; then set the jump timer to a random number
STZ $1540,x		; between 60 and 9F

SetYSpeed:
LDA $7F0E0E
CMP #$09
BCS Return0

LDA #$27		; so play a fiery sound effect
STA $1DFC
LDA $D8,x	;
SEC		;
SBC $1528,x	;
STA $00		;
LDA $14D4,x	;
SBC $151C,x	;
LSR		;
ROR $00		; uh...
LDA $00		;
LSR #3		;
TAY		;
LDA YSpeeds,y	;
BMI StoreYSpeed	;
STA $1564,x	; ...
LDA #$80		;
StoreYSpeed:	;
STA $AA,x	;
RTS		;

NoResetYSpeed:

JSL $01801A	;

LDA $14		;
AND #$07	;
;ORA $C2,x	;
BNE NoLavaTrail	;

JSL $0285DF	; show lava trail subroutine

NoLavaTrail:	;

LDA $1564,x		;
BNE NoAccelerate		;
LDA $AA,x		;
BMI StartAccelerating	;
;LDY $C2,x		;
;CMP Timer2Checks,y	;
CMP #!Timer2Check		;
BCS NoAccelerate		;
StartAccelerating:		;
CLC			;
ADC #$02		;
STA $AA,x		;

NoAccelerate:



PodobooGFX:		; Most of this routine is just for setting up pointers to the Podoboo's tiles.
JSR SubOffscreenX0
JSR PodobooGFXMainRt	;
REP #$20			;
;LDA.w #$0008		;
;ASL #5			; Okay, what is the point of this?
;CLC			;
;ADC #$8500		; Why not just...
LDA #$8600		; do this instead?
STA $0D8B		;
CLC			; set up some pointers
ADC #$0200		;
STA $0D95		;
SEP #$20			;
RTS			;

SetAnimationFrame:

INC $1570,x	;
LDA $1570,x	;
LSR		;
LSR		;
;LSR		;
AND #$01	;
STA $1602,x	;
RTS		;

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

PodobooGFXMainRt:	; most of this was ripped from the shared GFX routine at $019CF3

JSL $20CA4F

LDA $15F6,x	;
ORA $64		;
STA $03		;

LDA #$03		;
STA $04		;

LDA $1602,x	; these three lines weren't in the original;
ASL #2		; I just added them for the sake of simplicity
STA $05		; (besides, as I said, this was originally a shared GFX routine, so it won't be verbatim anyway)

PHX		;

GFXLoop:		;

LDX $04		;

LDA $00		;
CLC		;
ADC XDisp,x	;
STA $0300,y	;

LDA $01		;
CLC		;
ADC YDisp,x	;
STA $0301,y	;

TXA		;
ORA $05		;
TAX		;

LDA Tilemap,x	;
STA $0302,y	;

LDX $04		;

LDA XFlip,x	;
ORA $03		;
STA $0303,y	;

INY #4		;
DEC $04		;
BPL GFXLoop	;

PLX		;
LDA #$03		;
LDY #$00		;
JSL $81B7B3	;
RTS		;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; subroutines
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Table1:              db $0C,$1C
Table2:              db $01,$02
Table3:              db $40,$B0
Table6:              db $01,$FF
Table4:              db $30,$C0,$A0,$C0,$A0,$F0,$60,$90,$30,$C0,$A0,$80,$A0,$40,$60,$B0
Table5:              db $01,$FF,$01,$FF,$01,$FF,$01,$FF,$01,$FF,$01,$FF,$01,$00,$01,$FF

SubOffscreenX0:
LDA #$00
;BRA SubOffscreenMain
;SubOffscreenX1:
;LDA #$02
;BRA SubOffscreenMain
;SubOffscreenX2:
;LDA #$04
;BRA SubOffscreenMain
;SubOffscreenX3:
;LDA #$06
;BRA SubOffscreenMain
;SubOffscreenX4:
;LDA #$08
;BRA SubOffscreenMain
;SubOffscreenX5:
;LDA #$0A
;BRA SubOffscreenMain
;SubOffscreenX6:
;LDA #$0C
;BRA SubOffscreenMain
;SubOffscreenX7:
;LDA #$0E

SubOffscreenMain:

STA $03

JSR SubIsOffscreen
BEQ Return2

LDA $5B
LSR
BCS VerticalLevel
LDA $D8,x
CLC
ADC #$50
LDA $14D4,x
ADC #$00
CMP #$02
BPL EraseSprite
LDA $167A,x
AND #$04
BNE Return2
LDA $13
AND #$01
ORA $03
STA $01
TAY
LDA $1A
CLC
ADC Table4,y
ROL $00
CMP $E4,x
PHP
LDA $1B
LSR $00
ADC Table5,y
PLP
SBC $14E0,x
STA $00
LSR $01
BCC Label20
EOR #$80
STA $00
Label20:
LDA $00
BPL Return2

EraseSprite:
LDA $14C8,x
CMP #$08
BCC KillSprite
LDY $161A,x
CPY #$FF
BEQ KillSprite
LDA #$00
STA $1938,y
KillSprite:
STZ $14C8,x
Return2:
RTS

VerticalLevel:

LDA $167A,x
AND #$04
BNE Return2
LDA $13
LSR
BCS Return2
AND #$01
STA $01
TAY
LDA $1C
CLC
ADC Table3,y
ROL $00
CMP $D8,x
PHP
LDA $1D
LSR $00
ADC Table6,y
PLP
SBC $14D4,x
STA $00
LDY $02
BEQ Label22
EOR #$80
STA $00
Label22:
LDA $00
BPL Return2
BMI EraseSprite

SubIsOffscreen:
LDA $15A0,x
ORA $186C,x
RTS

