;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Reverse Gravity
;
; TODO:
;
; (not SMWCP2) fix yoshi
; (not SMWCP2) fix swimming
; (not SMWCP2) fix note blocks
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

!RAM = $1487					; Free RAM (was $58)

org $00CEBF
		autoclean JML fix_00CEBF	;
		
org $00CF1E
		autoclean JSL fix_00CF1E
		
org $00CF2A
		autoclean JML fix_00CF2A	;
		
org $00D111
		autoclean JSL fix_00D111
		NOP
		
org $00D5F9
		autoclean JML fix_00D5F9	;
		NOP
		
org $00F606
		autoclean JSL fix_00F606
		
org $00FE7E
		autoclean JML fix_00FE7E
		
org $00FEF0
		autoclean JSL fix_00FEF0
		NOP #2
		
org $02912B
		autoclean JSL fix_02912B
		BRA +
		NOP
		+

org $029163
		autoclean JSL fix_029163
		BRA +
		NOP
		+

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		
org $00E46D
		autoclean JML graphics_00E46D	;
		
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		
org $00D7E4			
		autoclean JML gravity_00D7E4	;
		NOP
		
org $00D91B
		autoclean JML gravity_00D91B	;
		NOP
		
org $00D948
		autoclean JSL gravity_00D948	;
		RTS				;

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

org $00CD28
		autoclean JSL physics_00CD28

org $00D666
		autoclean JSL physics_00D666	;
		
org $00DBA3
		autoclean JSL physics_00DBA3	;

org $00ED37
                autoclean JSL physics_00ED37	;
		autoclean JSL physics_00ED3A	;
		BRA +				;
		NOP #9
		+

org $00EF68
                autoclean JML physics_00EF68	;
		NOP #13
		
org $00F187
		autoclean JML physics_00F187	;

freecode

reset bytes

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Fixes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

fix_00CEBF:	LDA $7D
		LDY !RAM		; If reversed gravity,
		BEQ .not_ud

		EOR #$FF		; flip y speed check.
		INC
		
	.not_ud	CMP #$00
		PHP			; Return without affecting
		LDY #$04		; the z flag.
		LDA $72
		PLP
		BPL +
		JML $00CEC3
	+	JML $00CECD

fix_00CF1E:	JSR fix_duck		; Fix ducking,
		LDA $14			; and return.
		RTL
	
fix_00CF2A:	LDA $7D
		PHY
		LDY !RAM		; If reversed gravity,
		BEQ .not_ud
		
		EOR #$FF		; then reverse y speed check
		INC
		
	.not_ud	PLY
		CMP #$00		; and compare to 0.
		BMI +
		JML $00CF2E
	+	JML $00CF2F

fix_00D111:	LDA !RAM		; If reversed gravity,
		BEQ .not_ud
		
		LDA $7D			; then flip y speed
		EOR #$FF
		INC
		STA $7D
		
	.not_ud	PHK
		PEA.w .jsl_return-1
		PEA $84CE
		JML $00D92E		; and run gravity code
	.jsl_return
		LDA $13
		RTL
	
fix_00D5F9:	LDA $19			; If big, reversed gravity,
		BEQ .not_big
		LDA !RAM
		BNE .ud
		
	.not_big
		STZ $73
		LDA $13ED
		JML $00D5FE
		
	.ud	LDA $13ED		; and not sliding,
		BNE .return
		
		LDA $15			; Check if player is ducking.
		AND #$04
		BEQ .no_duck
		
		LDA $73			; If ducking now and previously not,
		BNE .return
		
		REP #$20
		LDA $96
		SEC
		SBC #$0008		; then shift y position up 8,
		STA $96
		SEP #$20
		
		LDA #$04
		STA $73
		STZ $13E8
		BRA .return
		
	.no_duck
		JSR fix_duck		; else, fix not-ducking.
		
	.return	JML $00D60B
	
fix_00F606:	LDA #$90
		LDY !RAM		; If reversed gravity,
		BEQ .not_ud
		LDA #$70		; flip y speed.
		
	.not_ud	STA $7D
		RTL
	
smoke_y_offsets:
		db $0C,$05
	
fix_00FE7E:	LDA !RAM		; If reversed gravity,
		BNE .ud
		
		LDA $96
		ADC #$1A
		JML $00FE82
		
	.ud	PHX
		LDX #$00		; then x = 0 if small and
		LDA $73
		BNE +
		LDA $19
		BEQ +
		INX			; x = 1 if big and not ducking,
	+	LDA $96
		ADC.l smoke_y_offsets,x	; and add disposition.
		JML $00FE8A
		
fix_00FEF0:	LDA !RAM		; If not reversed gravity,
		BNE .ud
		
		LDA $96			; then fireball y = y
		CLC
		ADC #$08		; + 8;
		RTL
		
	.ud	LDA $96			; else, fireball y = y
		CLC
		ADC #$10		; + 16.
		RTL
		
fix_02912B:
fix_029163:	LDA $16C9,x
		AND #$7F		; Get direction of bounce sprite.
		LDY !RAM		; If reversed gravity,
		BNE .ud
		CMP #$03		; check if going up;
		BRA .skip
		
	.ud	CMP #$00		; else, check if going down,
	.skip	PHP
		PLA
		AND #$02		; retrieve z flag for equality,
		CMP $1699,x		; and check if it is a note block.
		RTL

fix_duck:	LDA $73			; If previously ducking,
		BEQ .return
		LDA $19
		BEQ .return
		LDA !RAM
		BEQ .return
		
		REP #$20
		LDA $96
		CLC
		ADC #$0008		; then shift y position down 8.
		STA $96
		SEP #$20
		
	.return	STZ $73
		RTS
		
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Graphics hijacks
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

y_offsets:
		db $31,$27,$2F		

graphics_00E46D:
		LDA !RAM		; If reversed gravity,
		BNE .ud
		
		REP #$20
		LDA $80
		JML $00E471
		
	.ud	LDA $04			; then take OAM size encoding,
		AND #$80		; take bit 7,
		LSR
		LSR			; shift to #$08 or #$00,
		LSR
		LSR
		CLC			; add #$08,
		ADC #$08
		STA $00			; and store as tile size for later use;
		STZ $01			; zero out for 16-bit use.

		PHX
		LDX #$00		; x = 0 if small,
		LDA $19
		BEQ +
		INX			; x = 1 if big, and
		LDA $73
		BEQ +
		INX			; x = 2 if big & ducking.
	+	LDA.l y_offsets,x	; Get disposition based on x
		STA $02
		STZ $03			; and zero out for 16-bit use.
		PLX
		
		REP #$20		; y' =
		LDA $80			; y
		SEC
		SBC $DE32,x		; - tile based disposition
		SBC $00			; - tile size
		CLC
		ADC $02			; + state based disposition.
		PHA
		CLC
		ADC #$0010
		CMP #$0100		; If #$FFF0 <= y' <= #$00F0,
		PLA			; then mark the tile as unseen;
		SEP #$20
		BCS .unseen
		STA $0301,y		; else, set the new OAM y
		
		LDA $0303,y		; and flip vertically.
		ORA #$80
		STA $0303,y
		JML $00E485
		
	.unseen	JML $00E49F
		
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Gravity hijacks
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

gravity_00D7E4: LDA !RAM		; If reversed gravity,
		BEQ .not_ud
		
		LDA $7D			; then flip y speed.
		EOR #$FF
		INC
		STA $7D
	
	.not_ud	LDY $1407
		BNE +
		JML $00D7E9
	+	JML $00D824

gravity_00D91B:	LDA $D7B9,y		; If Mario is at the max y (cape) speed
		CMP $7D			; or below it,
		BEQ + 
		BMI +			; then set that as y speed.
		JML $00D924
		
	+	LDY !RAM		; If reversed gravity,
		BEQ .not_ud
		
		EOR #$FF		; then flip y speed back,
		INC
		
	.not_ud	STA $7D
		JML $00D94E		; and return.
	
gravity_00D948:	CLC			; Add acceleration to y speed.
		ADC $D7A5,y
		
		LDY !RAM		; If reversed gravity,
		BEQ .not_ud

		EOR #$FF		; then flip y speed back.
		INC

	.not_ud	STA $7D
		RTL

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

physics_00CD28:	LDA $77
		LDY !RAM		; If not reversed gravity,
		BNE .ud
		
		AND #$08		; then check if on ceiling;
		RTL
		
	.ud	AND #$04		; else, check if on ground.
		RTL

physics_00D666:	LDY !RAM		; If reversed gravity,
		BEQ .not_ud

		EOR #$FF		; then flip y speed.
		INC
		
	.not_ud	STA $7D
		LDA #$0B
		RTL
		
physics_00DBA3:	LDY !RAM		; If reversed gravity,
		BEQ .not_ud
		
		EOR #$FF		; then flip y speed.
		INC
		
	.not_ud	STA $7D
		LDA #$35
		RTL
		
physics_00ED37:	LDA #$08		; Originally set on-ceiling;
		LDY !RAM		; if reversed gravity,
		BEQ .not_ud
		
		STZ $72			; then disable air image,
		STZ $74			; climbing,
		STZ $1406		; screen scrolling,
		STZ $140D		; and spin jumping.
		
		LDA $7B			; If no x speed,
		BNE .not_still
		
		STZ $13ED		; then stop sliding.
		
	.not_still
		PHK			; Run on-ground code,
		PEA.w .jsl_return-1
		PEA $84CE
		JML $00EF79
		
	.jsl_return
		LDA #$04		; and set on-ground instead.
	.not_ud	TSB $77
		RTL
		
physics_00ED3A:	LDA !RAM		; If not reversed gravity,
		BNE .ud
		LDA $7D			; \Added by Alcaro to fix the 
		BPL .ud			; /floating on upsidedown cieling glitch
		STZ $7D			; stop y speed and
		LDA #$01		; play hit-ceiling sound.
		STA $1DF9
		
	.ud	RTL

physics_00EF68:	LDA !RAM		; If not reversed gravity,
		BNE .ud

		LDA #$04		; then set on-ground,
		TSB $77
	
		STZ $72			; disable air image,
		STZ $74			; climbing,
		STZ $1406		; screen scrolling,
		STZ $140D		; and disable spin jump;
		JML $00EF79
		
	.ud	LDA #$08		; else, set on-ceiling,
		TSB $77
		
		STZ $7D			; stop y speed, and
		LDA #$01		; play hit-ceiling sound.
		STA $1DF9
		
	.return	JML $00EF98
	
physics_00F187:	PHY
		LDY $13E8		; If not cape spinning,
		BNE .return
		LDY !RAM		; reversed gravity, and
		BEQ .return

		BIT #$0C		; bits 2 or 3 are set,
		BEQ .return
		EOR #$0C		; then exchange them both, and
		
	.return	PLY
		AND.l $00F0A4,x		; check the block interaction table.
		BEQ +
		JML $00F18D
	+	JML $00F1F6
	
print bytes