Welcome to Data Crystal's new home! Data Crystal is now part of the TCRF family (sort of).
The wiki has recently moved; please report any issues in Discord. Pardon the dust.

Super Mario Bros. 3/Notes

From Data Crystal
Jump to navigation Jump to search

Chip tiny.png The following article is a Notes Page for Super Mario Bros. 3.

Disassembly/reverse engineering notes

  • NN: all values are hexadecimal and at least two digits (e.g. 0F, not F) unless noted otherwise.
  • $NN or $NNNN: a memory address.
  • Countdown timer: a byte in memory set to some value, decremented every frame and when it reaches 0 something is usually set up to happen. Many timers are cyclic, meaning that they are being re-set and reused immediately after reaching 0.

Player physics/movement

Horizontal movement

  • If the player holds L/R the horizontal velocity $BD will start to increase (to-do: what's the exact increment?) at around 1 per frame. The same acceleration is always used when walking/running/dashing.
  • abs($BD) can at most reach a limit that varies depending on things below.
  • If WALKING, the limit is 18.
  • If player holds B,
    • The limit is raised to 28 and $BD is allowed to increase again. This is RUNNING.
    • When abs($BD) is >= 28, you are DASHING and the P-timer $515 cycles from 7. Every time it elapses an arrow is added to the P-meter.
    • When the P starts blinking, the player is in "flight mode":
      • 1) The limit is raised to 38 and $BD is allowed to increase again.
      • 2) The P-timer is LOCKED to the value 0F (don't know if the exact value has significance).
      • 3) Pressing A at this point launches the player into flight/super-jump, indicated by $57B being set to 1.
      • 4) The flight duration timer $56E is set to 80 and decrements every other frame.
    • Player exits "flight-mode" ($57B = 0) when one of the following happens: (to-do: incomplete)
      • 1) Player touches ground.
      • 2) Flight-limit timer $56E elapses.
      • 3) Player lets go of the A button.
    • Once no longer in "flight-mode", the P-timer $515 cycles from 23. Every time it elapses an arrow is removed from the P-meter.
    • You can only refill the P-meter again by accelerating to abs($BD) >= 28 as above. (If $515 hasn't had time to elapse, i.e. the P-meter hasn't decreased, you can stay "eligible" for $57B flight-mode by doing short hops of flight and staying at >= 28.)

$AC5A Jump power

$AC5A:A5 BD     LDA $00BD			; Load player horz velocity
$AC5C:10 03     BPL $AC61			; If negative,
$AC5E:20 0F DD  JSR $DD0F			; 	take absolute value
$AC61:4A        LSR				; Divide by 16
$AC62:4A        LSR
$AC63:4A        LSR
$AC64:4A        LSR
$AC65:AA        TAX				; X = A, going to use it as an index
$AC66:AD 47 A6  LDA $A647			; Load default jump velocity
$AC69:38        SEC				
$AC6A:FD 48 A6  SBC $A648,X			; Subtract from the jump velocity (remember lower means more power) using the table 00,02,04,08.
						; Thus a higher horizontal speed means a more powerful jump.
$AC6D:85 CF     STA $00CF			; Store as new vertical velocity.

$ACA1 Application of gravity

$ACA1:A0 05     LDY #$05		; Y = default falling gravity
$ACA3:A5 CF     LDA $00CF		; Load current vertical velocity
$ACA5:C9 E0     CMP #$E0		; 
$ACA7:10 0D     BPL $ACB6		; If currently rising and v vel is still faster than E0,
$ACA9:AD 79 05  LDA $0579		; 	Don't know what 0579 is... unused? Debugger never sees a nonzero value.
$ACAE:A5 17     LDA $0017		; 	Read gamepad. 80 is jump key, so value will appear negative!
$ACB0:10 04     BPL $ACB6		; 	If jump pressed,
$ACB2:A0 01     LDY #$01		; 		Y = jump gravity (lower than normal)
$ACB4:D0 05     BNE $ACBB		; 
$ACB6:A9 00     LDA #$00		; This is run if jump key is NOT pressed
$ACB8:8D 79 05  STA $0579		; 	So what does it do? 
$ACBB:98        TYA			; A=Y
$ACBC:18        CLC			;
$ACBD:65 CF     ADC $00CF		; Add gravity to current vertical velocity
$ACBF:85 CF     STA $00CF		; And store back

So, jumps are aborted either by the user releasing the button (bit 7 in 0017 is zero) or the 00CF is more positive than E0. Since SOME gravity is always applied, this ensures jumps are aborted.

$BFCC (Subroutine) Clamp Y velocity to the maximum

$BFCC:A5 CF     LDA $00CF			; Load current vertical velocity
$BFCE:30 08     BMI $BFD8			; Negative? Then skip clamping.
$BFD0:C9 40     CMP #$40			; #$40 is the maximum fall vel (note: gravity is added afterwards so the effective value is 45) 
$BFD2:30 04     BMI $BFD8			; Less than this? Then skip clamping.
$BFD4:A9 40     LDA #$40			; Replace $00CF with the maximum fall vel.
$BFD6:85 CF     STA $00CF
$BFD8:A2 12     LDX #$12			; UNKNOWN
$BFDA:20 93 BF  JSR $BF93			; UNKNOWN	
$BFDD:60        RTS