Super Mario Bros. 3/Notes: Difference between revisions

From Data Crystal
Jump to navigation Jump to search
No edit summary
(Modified stuff on h movement)
Line 9: Line 9:


===Horizontal movement===
===Horizontal movement===
* If the player holds L/R the horizontal velocity $BD will start to increase (todo: what's the exact increment?) at around 1 per frame. This continues until a set limit.
* If the player holds L/R the horizontal velocity $BD will start to increase (todo: what's the exact increment?) at around 1 per frame.  
* abs($BD) can at most reach a limit that varies depending on things below.
* If walking, the limit is 18 (24 dec).
* If walking, the limit is 18 (24 dec).
* If player holds B,  
* If player holds B,  
** The limit is raised to 28 (40 dec) and velocity is allowed to increase again (same acceleration).
** The limit is raised to 28 (40 dec) and velocity is allowed to increase again (same acceleration).
** As long as h vel is >= 28, the P-meter timer $515 cycles from 7 and every 0 an arrow is added to the P-meter.
** As long as abs($BD) stays >= 28, the P-timer $515 cycles from 7, and every time it elapses an arrow is added to the P-meter.
** After the final arrow is lit and the P starts blinking, the player is in "flight mode":
** When the P starts blinking, the player is in "flight mode":
*** The limit is raised to 38 (56 dec) and velocity is allowed to increase again (same acceleration).
*** 1) The limit is raised to 38 (56 dec) and $BD is allowed to increase again (same acceleration).
*** The P-meter timer is LOCKED to the value 15 (why that value? could be anything but 0).
*** 2) The P-timer is LOCKED to the value 15 (why that value? could be anything but 0).
*** Jumping now launches into flight, (if player has a suitable powerup, otherwise just jumping high).
*** 3) Jumping now launches into flight, (if player has a suitable powerup, otherwise just jumping high).
*** The countdown timer $056E is set to XX (todo: fix value).   
*** 4) The flight-limit countdown timer $056E is set to XX (todo: fix value).   
** Player exits "flight-mode" by one of (NOT COMPLETE):
** Player exits "flight-mode" when one of the following happens: (NOT COMPLETE)
*** Touching ground.
*** Touches ground.
*** $056E reaching 0.
*** Flight-limit timer $056E elapses.
** Once not in "flight-mode", the P-meter timer cycles from 23. Every 0, an arrow is removed from the P-meter.
** Once no longer in "flight-mode", the P-meter timer cycles from 23. Every time it elapses an arrow is removed from the P-meter.
 
** You only begin to fill up the P-meter again if you accelerate to abs($BD) >= 28.


===$AC5A Jump power===
===$AC5A Jump power===

Revision as of 16:09, 13 January 2010

Back to Super Mario Bros. 3 page.

Disassembly/reverse engineering notes

All values given are hexadecimal unless noted otherwise. Various important bits of code follow below. Unless marked as "subroutine" you can NOT jump directly to these addresses, and even then there might be side effects.

Wording on countdown timers: "cycles from xx" means the timer is repeatedly set to xx, allowed to reach 0, gets set to xx again etc.

Player physics/movement

Horizontal movement

  • If the player holds L/R the horizontal velocity $BD will start to increase (todo: what's the exact increment?) at around 1 per frame.
  • abs($BD) can at most reach a limit that varies depending on things below.
  • If walking, the limit is 18 (24 dec).
  • If player holds B,
    • The limit is raised to 28 (40 dec) and velocity is allowed to increase again (same acceleration).
    • As long as abs($BD) stays >= 28, the P-timer $515 cycles from 7, and 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 (56 dec) and $BD is allowed to increase again (same acceleration).
      • 2) The P-timer is LOCKED to the value 15 (why that value? could be anything but 0).
      • 3) Jumping now launches into flight, (if player has a suitable powerup, otherwise just jumping high).
      • 4) The flight-limit countdown timer $056E is set to XX (todo: fix value).
    • Player exits "flight-mode" when one of the following happens: (NOT COMPLETE)
      • Touches ground.
      • Flight-limit timer $056E elapses.
    • Once no longer in "flight-mode", the P-meter timer cycles from 23. Every time it elapses an arrow is removed from the P-meter.
    • You only begin to fill up the P-meter again if you accelerate to abs($BD) >= 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.
$ACAC:D0 0D     BNE $ACBB
$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