freeyumps

by tjb0607

Game: SMW

Description: gives p-switches to do free yumps with

; Yump assist by tjb0607
; Makes p-switch jumps easier.
; Works similar to the "reduce input lag patch", but only on p-switches.
; (doesn't affect switch palace yumps, sorry)

; + Sprite spawner by Kaizoman to give p-switches.

!leniency = $10		; extra leniency to add on each end of the yump input.
			; $02 will result in a total 5 frame window.

!earlytimer = $7FB3B0
!spin = $7FB3B1		; backwards! $00 if spin
!latetimer = $7FB3B2
!emptyslot = $7FB3B3	; empty sprite slot to spawn p-switch into
!pswitchspawned = $7FB3B3 ; if there's a p-switch already spawned, don't spawn a new one.

main:
lda $100	; \ only run in gamemode 14
CMP #$14	; |
BEQ +		; |
RTL		; |
+		; /
LDA $9D		; \ and when the game isn't paused
BEQ +		; |
RTL		; |
+		; /

	LDA !earlytimer	; \ because there's no init function with CARL
	CMP #$20	; | if it's out of usual bounds
	BCC +		; | initialize it at #$00
	LDA #$00	; |
	STA !earlytimer	; |
	STA !latetimer	; |
	+		; /

	LDA #$FF
	STA !emptyslot
	LDA #$00
	STA !pswitchspawned

	LDX #$0B
	.loop
	LDA $14C8,x		; \ check if sprite slot is used
	BNE +			; / 
	TXA			; \ if there's an empty sprite slot, save that for later
	STA !emptyslot		; /
	BRA .next
	+
	
	LDA $9E,x		; \ check if p-switch (or act as p-switch for custom sprites)
	CMP #$3E		; |
	BNE .next		; /

	LDA #$01		; \ remember for later that there's already a p-switch spawned.
	STA !pswitchspawned	; / 
	
	LDA $163E,x		; \ check if p-switch was *just* activated
	CMP #$20		; |
	BNE .next		; /

	LDA $16			; \ if you got a vanilla yump, 
	ORA $18			; | 
	BMI .done_reset		; / reset the timers and rtl
	
	LDA !earlytimer		; \ check if we should give early yump
	BEQ ++			; /

	LDA $15			; \ and only give an early yump if you're
	BPL ++			; / still holding jump.
	
	BRA .giveyump

	++
	LDA #!leniency		; \ set timer for late yumps
	STA !latetimer		; /
	JMP .done
.next
	DEX
	BPL .loop
	
	LDA $16			; \ check for newly pressed jump inputs
	ORA $18			; |
	BPL .done_dec		; /
	
	LDA $18			; \ store whether that was a spin
	AND #$80		; |
	EOR #$80		; |
	ORA $148F		; |
	STA !spin		; /
	
	LDA #!leniency		; \ set timer for early yumps
	STA !earlytimer		; /

	LDA !latetimer		; \ check if we should give late yump
	BEQ .done		; /
	
.giveyump
	LDA !spin
	BNE +
	LDA #$04		; \ play spin jump sound
	STA $1DFC		; /
	STA $140D		; and set spin flag
	BRA ++
	+
	LDA #$01		; \ play jump sound
	STA $1DFA		; /
	STZ $140D		; reset spin flag
	++
	
	LDA $7B			; \ https://smwc.me/m/smw/rom/00D2BD/
	BPL +			; | algorithm to give jump speed.
	EOR #$FF		; |
	INC A			; |
	+			; |
	LSR #2			; |
	AND #$FE		; |
	TAX			; |
	LDA $140D		; |
	BEQ +			; |
	INX			; |
	+			; |
	LDA $00D2BD,x		; |
	STA $7D			; /

	LDA #$0B		; \ set player as in the air
	STA $72			; /

.done_reset
	LDA #$00		; reset timers
	STA !latetimer
	STA !earlytimer
.done
	BRA spawnpswitch

.done_dec
	LDA !latetimer		; decrement timers
	BEQ +
	DEC
	STA !latetimer
	+
	LDA !earlytimer
	BEQ +
	DEC
	STA !earlytimer
	+

spawnpswitch:
	LDA !pswitchspawned	; \ p-switches should only be spawned:
	ORA $14			; | - if there's not a p-switch already on-screen
	AND #$0F		; | - only try to spawn once every 16 frames
	ORA $1470		; | - only if mario's not carrying something
	BEQ +			; |
	RTL			; |
	+			; | 
	LDA !emptyslot		; | - and if there's an available sprite slot to spawn it in
	CMP #$FF		; | 
	BNE +			; | 
	RTL			; |
	+			; /

	; spawn p-switch
	TAX

    LDA #$3E : STA $9E,x
    LDA #$0B        : STA $14C8,x
    JSL $07F7D2
    
    LDA #$00
    STA $C2,x
    
    PHB					; \ make sure we read from right data bank
    PHK					; |
    PLB					; /
    LDA $76 : EOR #$01 : TAY
    LDA $94 : CLC : ADC .xOffsL,y : STA $E4,x
    LDA $95 :       ADC .xOffsH,y : STA $14E0,x
    
    LDA #$0D
    LDY $73
    BNE +
    LDY $19
    BNE ++
  + LDA #$0F
 ++ CLC     : ADC $96  : STA $D8,x
    LDA $97 : ADC #$00 : STA $14D4,x

    PLB					; set data bank back to normal
    RTL
    
  .xOffsL: db $0B,$F5
  .xOffsH: db $00,$FF
back to listings