;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; SMW Dolphin (sprites 41-43), by imamelia
;;
;; This is a disassembly of sprites 41-43 in SMW, the dolphins.
;;
;; Uses first extra bit: NO
;; Uses extra property bytes: YES
;;
;; The first extra property byte determines which dolphin this sprite will act like.
;; (Add 41 to it to get the equivalent sprite number.)
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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

XSpeedInc:
db $FF,$01,$FF,$01,$00,$00

XSpeedMax:
db $E8,$18,$F8,$08,$00,$00

DolphinTiles1:
db $E2,$88

DolphinTiles2:
db $E7,$A8

DolphinTiles3:
db $E8,$A9

!DolphinTile4 = $CE
!DolphinTile5 = $EE

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

print "INIT ",pc
RTL

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

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

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

DolphinMain:

JSR DolphinGFX	;

LDA $9D		; if sprites are locked...
BNE Return0	; return

JSR SubOffscreenX0	;
JSL $01801A	;
JSL $018022	;
STA $1528,x	; prevent the player from sliding horizontally

LDA $AA,x	; sprite Y speed
BMI MovingUp	; if the sprite is moving down...
CMP #$3F		; and its Y speed has not reached 3F...
BCS MaxYSpeed	;
MovingUp:	;
INC $AA,x	; increment its Y speed
MaxYSpeed:	;

TXA		; sprite index -> A
EOR $13		;
LSR		; every other frame depending on the sprite index...
BCC NoObjInteract	; don't interact with objects
JSL $019138	;
NoObjInteract:	;
LDA $AA,x	; if the sprite Y speed is negative...
BMI FinishMain	;
LDA $164A,x	; or the sprite isn't touching any water...
BEQ FinishMain	; skip down to the interaction
LDA $AA,x	;
SEC		;
SBC #$08		; diminish the sprite Y speed by 8
STA $AA,x	;
BPL NoZeroYSpeed	; and if the result was negative...
STZ $AA,x	; just reset it to 0
NoZeroYSpeed:	;

LDA $151C,x	; if the unidirectional flag is set (the generator sets this)...
BNE SetYSpeed	; don't change direction

LDA $C2,x	;
LSR		; sprite state into carry flag
PHP		;
LDA $7FAB28,x	;
PLP		;
ROL		; sprite type + state
TAY		; into Y
LDA $B6,x	;
CLC		;
ADC XSpeedInc,y	; increment or decrement the sprite's X speed
STA $B6,x		;
CMP XSpeedMax,y	; if it has reached maximum...
BNE FinishMain	;
INC $C2,x	; change the sprite state

SetYSpeed:

LDA #$D0		; and set the sprite Y speed
STA $AA,x	;

FinishMain:

JSL $01B44F	; make the sprite solid

Return0:
RTS		;

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

DolphinGFX:

LDA $7FAB28,x	;
CMP #$02		; if this is a vertical dolphin...
BNE HorizontalGFX	;
JMP VerticalGFX	; use a different graphics routine

HorizontalGFX:	;

JSL $20CA4F	;

LDA $B6,x	;
STA $02		;
LDA $00		;
ASL $02		; if the sprite X speed is negative...
PHP		;
BCC RightOffsets	; switch the X offsets for the tiles

LeftOffsets:	;

STA $0300,y	; X offset for the first tile
CLC		;
ADC #$10	;
STA $0304,y	; X offset for the second tile
CLC		;
ADC #$08	;
STA $0308,y	; X offset for the third tile
BRA SetYOffsets	;

RightOffsets:	;

CLC		;
ADC #$18	;
STA $0300,y	; X offset for the first tile
SEC		;
SBC #$10		;
STA $0304,y	; X offset for the second tile
SEC		;
SBC #$08		;
STA $0308,y	; X offset for the third tile

SetYOffsets:	;

LDA $01		; Y offsets of zero
STA $0301,y	;
STA $0305,y	;
STA $0309,y	;

PHX			;
LDA $14			;
AND #$08		; animation rate
LSR #3			;
TAX			;
LDA DolphinTiles1,x	;
STA $0302,y		; first tile
LDA DolphinTiles2,x	;
STA $0306,y		; second tile
LDA DolphinTiles3,x	;
STA $030A,y		; third tile

PLX			;
LDA $15F6,x		; sprite palette and GFX page
ORA $64			; plus priority settings
PLP			; pull back the processor flags from before
BCS NoFlip		; if the sprite is facing right...
ORA #$40			; flip the tiles
NoFlip:			;
STA $0303,y		; tile properties
STA $0307,y		;
STA $030B,y		;

LDA #$02			; 3 tiles
LDY #$02			; 16x16
JSL $81B7B3		;
RTS

VerticalGFX:	; ripped from SubSprGfx1 at $019D67

LDA $14		;
AND #$04	;
LSR #2		;
STA $157C,x	;

JSL $20CA4F	;

LDA #!DolphinTile4	;
STA $0302,y	;
LDA #!DolphinTile5	;
STA $0306,y	;

LDX $15E9	;
LDA $01		;
STA $0301,y	;
CLC		;
ADC #$10	;
STA $0305,y	;

LDA $00		;
STA $0300,y	;
STA $0304,y	;

LDA $157C,x	;
LSR		;
LDA $15F6,x	;
BCS NoFlip2	;
ORA #$40		;
NoFlip2:		;
ORA $64		;
STA $0303,y	;
STA $0307,y	;

LDY #$02		;
LDA #$01		;
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

