Skip to main content
added 160 characters in body
Source Link

The fix is rather easy if one wants to patch the game: at the start of the level, propagate PlayerState to PlayerSize to correct the desynchronization.

The fix is rather easy if one wants to patch the game: at the start of the level, propagate PlayerState to PlayerSize to correct the desynchronization.

added 1051 characters in body
Source Link

Without analyzing the code

Without analyzing the code, but I'd risk to say that the state of Mario consists of 2 different variables:

With analysis of the code

Note that InitChangeSize is the same routine used to make Mario bigger when he gets a mushroom, or smaller when he's hit.

When Mario is hit just when the level ends, PlayerState is updated immediately to "small", but InitChangeSize is probably not called or not called enough times to reach the state where it changes PlayerSize

Without analyzing the code, but I'd risk to say that the state of Mario consists of 2 different variables:

Note that InitChangeSize is the same routine used to make Mario bigger when he gets a mushroom, or smaller when he's hit.

Without analyzing the code

I'd risk to say that the state of Mario consists of 2 different variables:

With analysis of the code

Note that InitChangeSize is the same routine used to make Mario bigger when he gets a mushroom, or smaller when he's hit.

When Mario is hit just when the level ends, PlayerState is updated immediately to "small", but InitChangeSize is probably not called or not called enough times to reach the state where it changes PlayerSize

added 1051 characters in body
Source Link

I didn't analyzeWithout analyzing the code, but I'd risk to say that the state of Mario consists of 2 different variables:

Now why are there 2 variables/states for the same thing? probablyBecause there's a transition from big to small and reverse. When the level is completed, the transition isn't done / is aborted before it can happen, and Mario remains big.

Now you can find a comprehensive SMB 6502 disassembly on github. It seems to confirm what I suspected:

PlayerSize            = $0754
PlayerStatus          = $0756

as you see, there is one variable for speed purposessize and another one for status.

The status variable is changed here:

Shroom_Flower_PUp:
      lda PlayerStatus    ;if player status = small, branch
      beq UpToSuper
      cmp #$01            ;if player status not super, leave
      bne NoPUp
      ldx ObjectOffset    ;get enemy offset, not necessary
      lda #$02            ;set player status to fiery
      sta PlayerStatus
      jsr GetPlayerColors ;run sub to change colors of player
      ldx ObjectOffset    ;get enemy offset again, and again not necessary
      lda #$0c            ;set value to be used by subroutine tree (fiery)
      jmp UpToFiery       ;jump to set values accordingly

The size isn't changed there. It's easier to pre-computedone somewhere else.

The transition code uses a statethird variable PlayerChangeSizeFlag, and as predicted, when changingthe flag reaches a given value, an inversion of the size variable is done (using eor #$01 on it), than to recomputewhich explains that if the size is big, it each timebecomes small:

InitChangeSize:
          ldy PlayerChangeSizeFlag  ;if growing/shrinking flag already set
          bne ExitBoth              ;then branch to leave
          sty PlayerAnimCtrl        ;otherwise initialize player's animation frame control
          inc PlayerChangeSizeFlag  ;set growing/shrinking flag
          lda PlayerSize
          eor #$01                  ;invert player's size
          sta PlayerSize
ExitBoth: rts                       ;leave

Note that InitChangeSize is the same routine used to make Mario bigger when he gets a mushroom, specially on those not-that-fast processorsor smaller when he's hit.

I didn't analyze the code, but I'd risk to say that the state of Mario consists of 2 different variables:

Now why are there 2 variables/states for the same thing? probably for speed purposes. It's easier to pre-compute a state when changing it, than to recompute it each time, specially on those not-that-fast processors.

Without analyzing the code, but I'd risk to say that the state of Mario consists of 2 different variables:

Now why are there 2 variables/states for the same thing? Because there's a transition from big to small and reverse. When the level is completed, the transition isn't done / is aborted before it can happen, and Mario remains big.

Now you can find a comprehensive SMB 6502 disassembly on github. It seems to confirm what I suspected:

PlayerSize            = $0754
PlayerStatus          = $0756

as you see, there is one variable for size and another one for status.

The status variable is changed here:

Shroom_Flower_PUp:
      lda PlayerStatus    ;if player status = small, branch
      beq UpToSuper
      cmp #$01            ;if player status not super, leave
      bne NoPUp
      ldx ObjectOffset    ;get enemy offset, not necessary
      lda #$02            ;set player status to fiery
      sta PlayerStatus
      jsr GetPlayerColors ;run sub to change colors of player
      ldx ObjectOffset    ;get enemy offset again, and again not necessary
      lda #$0c            ;set value to be used by subroutine tree (fiery)
      jmp UpToFiery       ;jump to set values accordingly

The size isn't changed there. It's done somewhere else.

The transition code uses a third variable PlayerChangeSizeFlag, and as predicted, when the flag reaches a given value, an inversion of the size variable is done (using eor #$01 on it), which explains that if the size is big, it becomes small:

InitChangeSize:
          ldy PlayerChangeSizeFlag  ;if growing/shrinking flag already set
          bne ExitBoth              ;then branch to leave
          sty PlayerAnimCtrl        ;otherwise initialize player's animation frame control
          inc PlayerChangeSizeFlag  ;set growing/shrinking flag
          lda PlayerSize
          eor #$01                  ;invert player's size
          sta PlayerSize
ExitBoth: rts                       ;leave

Note that InitChangeSize is the same routine used to make Mario bigger when he gets a mushroom, or smaller when he's hit.

Source Link
Loading