News
Welcome to NeoRHDN! This place is still a work-in-progress, so pardon the construction...

Chat on Discord
Views: 880,509
Sections: Documents | Utilities | ROM Hacks | Games | Translations | Homebrew | Fonts | Community
Site: Main | Rules/FAQ | Discord | Memberlist | Latest posts | Stats | Ranks | Online users
12-22-24 05:23 PM
Guest: Register | Login

Main - Posts by SMB2J-2Q

Pages: 1 2

SMB2J-2Q
Posted on 08-22-24 01:51 AM, in SNES Music Hacking (rev. 4 of 08-22-24 03:11 AM by SMB2J-2Q) Link | ID: 347

Red Goomba

Level: 9

Posts: 1/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
I have just recently joined this board, and I would like to know how to hack music for Super Mario All-Stars.

For example, unlike the original NES SMB, in SMAS, in both SMB and SMB2J (or SMBLL for U.S. parlance) in world 8-4 the music does not reset between scene changes when going down pipes, a la SMB3 in some fortresses.

What I would like to know exactly is how SMAS fixes the castle stage music in SMB and SMBLL so that during world 8-4 it does not reset between scene changes, in case there is anyone who wants to fix it to the old NES way (so that the music does reset between scene changes, and the return of the water music in the underwater portion in both games).

~Ben (SMB2J-2Q)

SMB2J-2Q
Posted on 08-22-24 03:12 AM, in SNES Music Hacking (rev. 2 of 08-22-24 03:14 AM by SMB2J-2Q) Link | ID: 350

Red Goomba

Level: 9

Posts: 2/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Posted by Rexius55
Posted by SMB2J-2Q
I have just recently joined this board, and I would like to know how to hack music for Super Mario All-Stars.

For example, unlike the original NES SMB, in SMAS, in both SMB and SMB2J (or SMBLL for U.S. parlance) in world 8-4 the music does not reset between scene changes when going down pipes, a la SMB3 in some fortresses.

What I would like to know exactly is how SMAS fixes the castle stage music in SMB and SMBLL so that it does not reset between scene changes, in case there is anyone who wants to fix it to the old NES way (so that the music does reset between scene changes, and the return of the water music in the underwater portion in both games).

~Ben (SMB2J-2Q)


Link to the music addresses in the ROM Map on SMW Central

Try lookin' through this! The game likely has code to simply continue the song currently playing if the next loaded sector after a transition uses the same music, so if you play around with the game and use this as reference, you could probably inject some ASM or hex edit in a way to make the game simply load the song from the beginning.

Can't go too in-depth with how to do that and where it's located in the game since I'm not involved with SMAS hacking, but I hope this helps!

Edit: I also recommend using Mesen (Multi)'s debugging features to look at the code while the game is running to help you figure this out as well, it's a great emulator for debugging!

FYI, I have been studying these three SMAS disassembly pages:
Part 1 (bank 3):
https://github.com/Maseya/SMAS-Disassembly/blob/master/Assembly/SMB1/code/b03/_b03.asm

Part 2 (bank 4):
https://github.com/Maseya/SMAS-Disassembly/blob/master/Assembly/SMB1/code/b04/_b04.asm

Part 3 (bank 5):
https://github.com/Maseya/SMAS-Disassembly/blob/master/Assembly/SMB1/code/b05/_b05.asm

~Ben (SMB2J-2Q)

SMB2J-2Q
Posted on 08-23-24 11:01 PM, in Super Mario Bros. Fixes (rev. 2 of 08-23-24 11:21 PM by SMB2J-2Q) Link | ID: 429

Red Goomba

Level: 9

Posts: 3/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Continuing from where we left off in the old RHDN website, I present to you a thread that documents all the various code changes for SMB, SMB2J (or SMBLL) and ANNSMB.

Here's the old thread at RHDN that inspired this one here.
https://www.romhacking.net/forum/index.php?topic=32473.0

And here are the two threads that inspired my original RHDN thread in the first place:
https://forums.nesdev.org/viewtopic.php?t=11576&hilit=sram+mario (ShaneM's bugfixed SMB1 and SMB2J)
https://tcrf.net/Super_Mario_Bros. (SMB entry at The Cutting Room Floor)

In Super Mario All-Stars (SMAS) for the SNES, in the AreaPointer code there appears to be another new chunk of code related to blocking out invalid worlds.

LoadAreaPointer:
jsr FindWorldNumber ;find it and store it here
sta AreaPointer
GetAreaType: and #%01100000 ;mask out all but d6 and d5
asl a
rol a
rol a
rol a ;make %0xx00000 into %000000xx
sta AreaType ;save 2 MSB as area type
rts

FindWorldNumber:
ldy WorldNumber ;load offset from world variable
cpy #World8+1 ;check against max world value + 1
bcc FindAreaPointer ;if world number < 8, branch to do area pointer logic normally
lda #$00
sta AreaNumber ;otherwise clear area and level number variables
sta LevelNumber
tay
sty WorldNumber ;then do same for world variable
FindAreaPointer:
lda WorldAddrOffsets,y
clc ;add area number used to find data
adc AreaNumber
tay
lda AreaAddrOffsets,y ;from there we have our area pointer
rts


~Ben (SMB2J-2Q)

SMB2J-2Q
Posted on 08-24-24 01:47 AM, in Super Mario Bros. Fixes (rev. 3 of 08-24-24 02:46 AM by SMB2J-2Q) Link | ID: 442

Red Goomba

Level: 9

Posts: 4/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Posted by ShaneM
Cool find, SMB2J-2Q!

Is that limited to SMB1 or The Lost Levels as well? I know the FDS SMB2J has a check for that under "CheckInvalidWorldNum:". On that version, it cannot be done after "FindAreaPointer:" because sm2data4.asm is loaded over that old code be it identical.

Hi Shane,

Yes, this new code is in the SMAS remake of SMB2J (SMBLL) as well:
https://github.com/Maseya/SMAS-Disassembly/blob/master/Assembly/SMB2J/code/b0E/_b0E.asm

The area data code is also saved to the alternate AreaType address that stores the current BG palette and music ($BA).

It is true about the separate data banks for the FDS original (and ANNSMB), so for SMAS the world number check has been revised to include up to World D. In addition, under 'GetAreaType' for SMBLL a check to see if the player is in world 8-4 or not has been added. Perhaps this last chunk of code might be why the music in World 8-4 doesn't reset during scene changes whenever the player enters a pipe?

LoadAreaPointer:
jsr FindWorldNumber ;find it and store it here
sta AreaPointer
GetAreaType: and #%01100000 ;mask out all but d6 and d5
asl a
rol a
rol a
rol a ;make %0xx00000 into %000000xx
sta AreaType ;save 2 MSB as area type
sta AreaType_Alt ;also save as BG palette and music type
lda WorldNumber ;if not on world 8, skip the rest of this code
cmp #World8
bne NotWorld8
lda AreaNumber ;otherwise check if player is on world 8-4, branch to exit if not
cmp #Level4
bne NotWorld8
lda #$03 ;if so, load BG and music type for castle level
sta AreaType_Alt ;and store to alternate AreaType variable
NotWorld8: rts

FindWorldNumber:
ldy WorldNumber ;load offset from world variable
cpy #WorldD+1 ;check against max world value + 1
bcc FindAreaPointer ;if world < D, branch to do area pointer logic normally
lda #$00
sta AreaNumber ;otherwise clear area and level number variables
sta LevelNumber
tay
sty WorldNumber ;then do same for world variable
FindAreaPointer:
lda WorldAddrOffsets,y
clc ;add area number used to find data
adc AreaNumber
tay
lda AreaAddrOffsets,y
rts

~Ben

SMB2J-2Q
Posted on 08-25-24 10:16 AM, in Hack Ideas And Requests (rev. 5 of 08-26-24 05:47 AM by SMB2J-2Q) Link | ID: 481

Red Goomba

Level: 9

Posts: 5/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Game: Donkey Kong
Platform: ColecoVision
Requests: Freeze Timer While Intro Song Plays and When Mario Dies

Same as in the NES version, I wish that the ColecoVision version of Donkey Kong would have the timer freeze (meaning timer doesn't tick and DK doesn't roll his barrels yet/no Firefoxes appearing yet on the rivets board/no moving elevators yet on the elevators board) until the intro song ends (all on-screen action does freeze whenever Mario dies). Why? In the original 24K ROM cart, at least, the bonus timer ticks for exactly one tick before the intro song finishes, while in the 16K ROM update the timer's appearance is delayed until the intro song ends.

Also, whenever the timer warning plays (less than 10 seconds left on the timer), in both the 24K and 16K carts the main BG music is still heard, but what I want to do is fix it so only the warning sound is heard (same as in the arcade original and the NES version). What the later 16K version did get right was that the BG music stopped whenever Mario lost a life.

~Ben

SMB2J-2Q
Posted on 08-25-24 10:30 AM, in What made you interested in hacking roms? (rev. 4 of 08-25-24 10:35 AM by SMB2J-2Q) Link | ID: 482

Red Goomba

Level: 9

Posts: 6/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
For me, it was the numerous bugfixes in Super Mario All-Stars for the SNES that inspired me to try to apply the same fixes to the original NES release of SMB. Such bugfixes included:
* Life Max Out -- no more unintended Game Over as the lives counter stops at exactly 128 lives.
* Mario's bounce rate against enemies was improved, which meant smoother stomping on Koopas against staircases for improved lives max-out.
* In World 4-3, the last pulley platform no longer pulls up by itself if you had earlier broke off the second group of platforms.
* In World 8-3, Hammer Brothers could now be destroyed by green Koopa shells perfectly.
* No more Minus World
* No more getting stuck past the goal pipe in any water level. In the original NES release it was possible to get the player stuck behind the goal pipe due to the 1-tile gap above it and then having to die via time-up; this was fixed in VsSMB, SMB2J (SMBLL), ANNSMB and SMBDX as well as the second PAL version of the NES SMB.

~Ben

SMB2J-2Q
Posted on 08-25-24 10:56 AM, in Super Mario Bros. Fixes (rev. 5 of 08-25-24 11:01 AM by SMB2J-2Q) Link | ID: 483

Red Goomba

Level: 9

Posts: 7/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
I wonder if the code change under 'NoDemote' in both SMB2J (SMBLL) and ANNSMB, which adds new checks for either power-up objects or Goombas (again), was meant to fix the "Koopa Troopa Factory" glitch in the first SMB that involved turning Goombas and Spinys into Koopa shells (either green or red) when hit by bricks above when the player was small?

ChkToStunEnemies:
lda Enemy_ID,x
cmp #$09 ;perform many comparisons on enemy identifier
bcc NoDemote ;if the enemy identifier is identical to the values
cmp #Lakitu ;$0e, $0f or $10 it will be demoted, in practice
bcs NoDemote ;$0e and $10 are values used by green paratroopas
cmp #PiranhaPlant
beq NoDemote ;enemy objects $0a thru $0d will not be demoted
cmp #UpsideDownPiranhaP
beq NoDemote
cmp #$0a ;demote enemy object $09 even though it isn't used
bcc Demote
cmp #PiranhaPlant
bcc NoDemote
Demote: and #%00000001 ;erase all but LSB, essentially turning enemy object
sta Enemy_ID,x ;into green or red koopa troopa to demote them
NoDemote: cmp #PowerUpObject
beq BounceOff ;if power-up object, branch to bounce it
cmp #Goomba
beq BounceOff ;redundant, already checked for goomba
lda #$02
sta Enemy_State,x ;set enemy state to $02 (stunned)
BounceOff: dec Enemy_Y_Position,x ;subtract 2 pixels from enemy's vertical position


~Ben (SMB2J-2Q)

SMB2J-2Q
Posted on 08-26-24 02:08 PM, in Super Mario Bros. Fixes (rev. 4 of 08-28-24 02:23 AM by SMB2J-2Q) Link | ID: 514

Red Goomba

Level: 9

Posts: 8/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Hi Shane,

In Super Mario Bros. 3 there is a data table that lists all the sound effects to be played. It is explained in detail here (and explains why the "extended" 1-UP sound exists):


I wish that we could do a similar sound effects data table check for SMB, SMB2J and ANNSMB, which would help prevent other sounds in the same three queues from overwriting each other. The reason I wish to come up with this data table like the one in SMB3 is so that I can redirect the old commands to it via a new JSR, instead of having to load for each specific routine the relevant queue first to check it for other sounds before loading the sound in question.

The table in question looked like this:

;$A507
SndLev1_SuitLost2:
ldy Sound_QLevel1
cpy #Snd_LevelPoof
bne Try_Unknown ;if not doing poof sound, jump to Try_Unknown

;"Poof" sound
lda #$1f
bne Merge ;jump (technically always) to Merge

;$A512
Try_Unknown:
cpy #Snd_Unknown
bne Try_ShoeLost ;if not doing unknown sound, jump to Try_ShoeLost

;Unknown sound
lda #$00
beq Merge

;$A51A
Try_ShoeLost:
cpy #Snd_ShoeLost
bne Try_Others ;if not doing Kuribo's shoe lost sound, jump to Try_Others
lda #$57
bne Merge

;$A522
Try_Others:
lda SndCur_Level1
bne Sfx_Others ;if any other level 1 sounds are playing, branch back to $A504

;tail wagging sound
lda #$6b

;$A529
Merge:
sta Sfx_Counter2 ;set Sfx_Counter2 accordingly
tya
and #$b0
sty SndCur_Level1 ;here is why the "extended 1-UP" fanfare plays!


~Ben

SMB2J-2Q
Posted on 08-29-24 10:19 AM, in Super Mario Bros. Fixes (rev. 3 of 08-29-24 10:38 PM by SMB2J-2Q) Link | ID: 557

Red Goomba

Level: 9

Posts: 9/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
In SMB2J (SMBLL) there is a penalty for those who like to warp: do not allow world 9 to be activated unless the player completes all 8 worlds first.

In SMB 1 beating World 8 the first time around turns on the hard mode and world selection flags whether the player used warps or not; for those of you who wish to prevent speedrunners from gaining the hard mode too early, here is what you'd do:

$06c9 = CompletedWorlds

GameMenuRoutine:
ldy #$00
lda SavedJoypad1Bits ;check to see if either player pressed
ora SavedJoypad2Bits ;only the start button (either joypad)
cmp #Start_Button
beq StartGame
cmp #A_Button+Start_Button ;check to see if A + start was pressed
bne ChkSelect ;if not, branch to check select button
lda #$00
sta CompletedWorlds ;initialize completed worlds flag
StartGame: jmp ChkContinue ;if either start or A + start, execute here



WorldBits:
.db $01, $02, $04, $08, $10, $20, $40, $80

SetupVictoryMode:
ldx ScreenRight_PageLoc ;get page location of right side of screen
inx ;increment to next page
stx DestinationPageLoc ;store here
ldy WorldNumber
lda WorldBits,y ;set bit according to the world the player is in
ora CompletedWorlds
sta CompletedWorlds
lda #EndOfCastleMusic
sta EventMusicQueue ;play win castle music
jmp IncModeTask_B ;jump to set next major task in victory mode



InitializeGame:
lda #$00
sta CompletedWorlds ;clean slate player's progress
ldy #$6f ;clear all memory as in initialization procedure,
jsr InitializeMemory ;but this time, clear only as far as $076f
ldy #$1f
ClrSndLoop: sta SoundMemory,y ;clear out memory used



EndChkBButton: lda SavedJoypad1Bits
ora SavedJoypad2Bits ;check to see if B button was pressed on
and #B_Button ;either controller
beq EndExitTwo ;branch to leave if not
lda CompletedWorlds ;check if player has finished all 8 worlds
cmp #$ff ;without warping, and branch ahead if not
bne NotDoneYet
lda #$01 ;otherwise set world selection flag
sta WorldSelectEnableFlag
NotDoneYet: lda #$ff ;remove onscreen player's lives
sta NumberofLives
jsr TerminateGame ;do sub to continue other player or end game
EndExitTwo: rts ;leave



SetInitNTHigh: sty CurrentNTAddr_High ;store name table address
ldy #$80
sty CurrentNTAddr_Low
asl ;store LSB of page number in high nybble
asl ;of block buffer column position
asl
asl
sta BlockBufferColumnPos
dec AreaObjectLength ;set area object lengths for all empty
dec AreaObjectLength+1
dec AreaObjectLength+2
lda #$0b ;set value for renderer to update 12 column sets
sta ColumnSets ;12 column sets = 24 metatile columns = 1 1/2 screens
jsr GetAreaDataAddrs ;get enemy and level addresses and load header
lda CompletedWorlds ;check to see if player finished all 8 worlds without warping
cmp #$ff
beq SetSecHard ;if so, set secondary no matter where we're at
lda WorldNumber ;otherwise check world number


~Ben (SMB2J-2Q)

SMB2J-2Q
Posted on 08-30-24 11:12 PM, in Super Mario Bros. Fixes (rev. 5 of 08-31-24 05:21 AM by SMB2J-2Q) Link | ID: 591

Red Goomba

Level: 9

Posts: 10/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Posted by ShaneM
Cool find, SMB2J-2Q!

Is that limited to SMB1 or The Lost Levels as well? I know the FDS SMB2J has a check for that under "CheckInvalidWorldNum:". On that version, it cannot be done after "FindAreaPointer:" because sm2data4.asm is loaded over that old code be it identical.

Hi Shane,

Time for a new hack question.

In Super Mario All-Stars, in the x-4 levels, the Podoboo moves up higher than in the NES original but only up to the bottom edge of the status bar. May I ask you what I'd do to fix this, so that the Podoboo goes up high but only to the status bar's bottom edge?

So far, I remember you re-coded this:

MovePodoboo:
lda EnemyIntervalTimer,x ;check enemy timer
bne PdbM ;branch to move enemy if not expired
jsr InitPodoboo ;otherwise set up podoboo again
lda PseudoRandomBitReg+1,x ;get part of LSFR
ora #%10000000 ;set d7
sta Enemy_Y_MoveForce,x ;store as movement force
and #%00001111 ;mask out high nybble
ora #$07 ;SM FIX set for at least seven intervals
sta EnemyIntervalTimer,x ;store as new enemy timer
lda #$f8 ;SM FIX podoboo moves higher up in SMAS
sta Enemy_Y_Speed,x ;set vertical speed to move podoboo upwards
PdbM: jmp MoveJ_EnemyVertically ;branch to impose gravity on podoboo


I also wanted to share this from SMAS:

InitPodoboo:
lda #$d0 ;set enemy position to below
sta Enemy_Y_Position,x ;the bottom (at 208th pixel) of the screen (why was it $02?)
lda #$01
sta Enemy_Y_HighPos,x
sta EnemyIntervalTimer,x ;set high vertical byte and timer for enemy
lsr
sta Enemy_State,x ;initialize state for enemy
jmp SmallBBox

UPDATE: SUCCESS! The Podoboos now rise up to the edge of the status bar before going back down, with the original unaltered attributes for MovePodoboo.

In the NES SMB, both the Podoboo's Y position and high Y position were checked first and both set to $02 before the enemy interval timer was set to $01 via the LSR. But in SMAS this was changed so the Podoboo's Y position was explicitly checked first, now set to $d0 (208th pixel) before the high Y position and enemy interval timer were set, now both set to $01.

Here's a screenshot of the result of this fix:


~Ben

SMB2J-2Q
Posted on 09-03-24 02:37 AM, in Super Mario Bros. Fixes (rev. 4 of 09-03-24 02:57 AM by SMB2J-2Q) Link | ID: 655

Red Goomba

Level: 9

Posts: 11/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Posted by ShaneM
Posted by SMB2J-2Q
In SMB2J (SMBLL) there is a penalty for those who like to warp: do not allow world 9 to be activated unless the player completes all 8 worlds first.



Actually, that isn't true. SM2DATA3 does a check in the subroutine "BackToNormal" on which it is commented:


lda CompletedWorlds ;if completed all worlds without skipping over any
cmp #$ff ;then branch elsewhere (note warping backwards may
beq GoToWorld9 ;allow player to complete skipped worlds)


But that comment also isn't completely true. Whenever you complete a castle, one of the 8 bits in "CompletedWorlds" ($07FA) is set. (To make this comment correct just remove the word "backwards" from the cmp #$ff line of doppleganger's disassembly though that isn't really important.) This bit is determined in "SetupVictoryMode" subroutine in SM2MAIN:


ldy WorldNumber
lda WorldBits,y
ora CompletedWorlds ;set bit according to the world the player was in
sta CompletedWorlds


The bits in the WorldBits table start with #%00000001 for world 1 and multiplies for each world in table values. So world 8 would set #%10000000. It is ORA'd to save the previous bits hence how "CompletedWorlds" would be #$FF if you complete all 8 worlds. But, the set bits remain set even after taking a warpzone.

I'll put it in layman's terms for you: Say you complete worlds 1 and 2, at the start of world 3 "CompletedWorlds" would have bits #%00000011 set. Let's say you take the negative warp zone on 3-1 back to 1-1, those bits aren't reset. Now, let's say after taking the negative warp you take the warp on 1-2 back to world 3. Well, the bits remain set. So you would still get to world 9 while taking these warps because you completed the first two castles (assuming you complete castles 3-8). The same could be said if you complete up to the start of world 8 (#%01111111 set) and on 8-1 take the negative warp zone back to 5-1 and then on 5-2 warp ahead back to 8-1. Well, after completing 8-4 $07FA would still be set to #$FF, hence even taking a possible 4 warp zones (2 regular and 2 negative) you would still end up on world 9. Does that make sense?

Hi Shane,

I understand and thank you for the heads-up on these!

BTW, I hope you enjoyed my latest SMAS discovery about the Podoboo.

I also found this in SMAS:

SetStPos: lda PlayerStarting_X_Pos,y ;load appropriate horizontal position
sta Player_X_Position ;and vertical positions for the player, using
lda PlayerStarting_Y_Pos,x ;AltEntranceControl as offset for horizontal and either $0710
sta Player_Y_Position ;or value that overwrote $0710 as offset for vertical
lda PlayerBGPriorityData,x
sta Player_SprAttrib ;set player sprite attributes using offset in X
ldx #$00 ;SMAS diff: then clear X
jsr BoundingBoxCore ;SMAS diff: do sub to get player's bounding box coordinates
jsr GetPlayerColors ;get appropriate player palette
ldy GameTimerSetting ;get timer control value from header
beq ChkOverR ;if set to zero, branch (do not use dummy byte for this)
lda FetchNewGameTimerFlag ;do we need to set the game timer? if not, use
beq ChkOverR ;old game timer setting
lda GameTimerData,y ;if game timer is set and game timer flag is also set,
sta GameTimerDisplay ;use value of game timer control for first digit of game timer
lda #$01
sta GameTimerDisplay+2 ;set last digit of game timer to 1
lsr
sta GameTimerDisplay+1 ;set second digit of game timer
sta FetchNewGameTimerFlag ;clear flag for game timer reset
sta StarInvincibleTimer ;clear star mario timer
ChkOverR: ldy JoypadOverride ;if controller bits not set, branch to skip this part

Under SetStPos, after the player's sprite attributes are set up, X is then cleared and a JSR to BoundingBoxCore is performed. I wonder what this was supposed to do in SMAS?

~Ben

SMB2J-2Q
Posted on 09-05-24 02:17 AM, in Super Mario Bros. Fixes (rev. 6 of 09-05-24 06:07 AM by SMB2J-2Q) Link | ID: 688

Red Goomba

Level: 9

Posts: 12/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Hi Shane,

Would you happen to know about why, under ClearVRLoop, SMAS removes the JSR to GetAreaMusic but also saves #$FF to the VRAM buffer?

ClearVRLoop: sta VRAM_Buffer1-1,y ;clear buffer at $0300-$03ff
iny
bne ClearVRLoop
sta GameTimerExpiredFlag ;clear game timer exp flag
sta DisableIntermediate ;clear skip lives display flag
sta BackloadingFlag ;clear value here
lda #$ff
sta BalPlatformAlignment ;initialize balance platform assignment flag
sta VRAM_Buffer1 ;SMAS diff: also save to VRAM buffer
lda ScreenLeft_PageLoc ;get left side page location
lsr Mirror_PPU_CTRL_REG1 ;shift LSB of ppu register #1 mirror out
and #$01 ;mask out all but LSB of page location
ror ;rotate LSB of page location into carry then onto mirror
rol Mirror_PPU_CTRL_REG1 ;this is to set the proper PPU name table
jsr GetAreaMusic ;load proper music into queue (removed in SMAS)
lda #$38 ;load sprite shuffle amounts to be used later
sta SprShuffleAmt+2
lda #$48
sta SprShuffleAmt+1
lda #$58
sta SprShuffleAmt
ldx #$0e ;load default OAM offsets into $06e4-$06f2
ShufAmtLoop: lda DefaultSprOffsets,x


And here's the SMAS version of the same code for reference:

CODE_039EE6:
STA $0300,y ; $03:9EE6: 99 00 03
INY ; $03:9EE9: C8
BNE CODE_039EE6 ; $03:9EEA: D0 FA
STA $0759 ; $03:9EEC: 8D 59 07
STA $0769 ; $03:9EEF: 8D 69 07
STA $0728 ; $03:9EF2: 8D 28 07
LDA #$FF ; $03:9EF5: A9 FF
STA $03A0 ; $03:9EF7: 8D A0 03
STA $1702 ; $03:9EFA: 8D 02 17
LDA $071A ; $03:9EFD: AD 1A 07
LSR $0778 ; $03:9F00: 4E 78 07
AND #$01 ; $03:9F03: 29 01
ROR A ; $03:9F05: 6A
ROL $0778 ; $03:9F06: 2E 78 07
LDA #$38 ; $03:9F09: A9 38
STA $0B43 ; $03:9F0B: 8D 43 0B
LDA #$48 ; $03:9F0E: A9 48
STA $0B42 ; $03:9F10: 8D 42 0B
LDA #$58 ; $03:9F13: A9 58
STA $0B41 ; $03:9F15: 8D 41 0B
LDX #$1C ; $03:9F18: A2 1C


~Ben (SMB2J-2Q)

SMB2J-2Q
Posted on 09-05-24 05:32 AM, in Super Mario Bros. Fixes (rev. 9 of 09-05-24 05:51 AM by SMB2J-2Q) Link | ID: 691

Red Goomba

Level: 9

Posts: 13/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Posted by ShaneM
Posted by SMB2J-2Q

Under SetStPos, after the player's sprite attributes are set up, X is then cleared and a JSR to BoundingBoxCore is performed. I wonder what this was supposed to do in SMAS?


X is used as the offset for the player object, it is not "cleared" as in clearing a flag or bit but used as the offset for the player. I'll comment it more clearly for you:


SetStPos: lda PlayerStarting_X_Pos,y ;load appropriate horizontal position
sta Player_X_Position ;and vertical positions for the player, using
lda PlayerStarting_Y_Pos,x ;AltEntranceControl as offset for horizontal and either
sta Player_Y_Position ;the original offset from the header or alt offset for vertical
lda PlayerBGPriorityData,x
sta Player_SprAttrib ;set player sprite attributes using offset in X
ldx #$00 ;SMAS set offset for player object
jsr BoundingBoxCore ;SMAS get player's bounding box coordinates
jsr GetPlayerColors ;get appropriate player palette


This isn't a bugfix that needs to be ported to the NES/FDS. The display intermediate screen (lives screen) on the SNES SMB1 and TLL is set up differently, with a picture of the current level being displayed before the level starts. The player's bound box is set during this sequence on SNES but not NES/FDS because the routine isn't called during display intermediate on there.

I NOP'd it on the SNES to see what would happen and it makes no difference. Perhaps this is quite possibly residual code as it may have been meant to be animated at one point including the player in the level intro picture. So not a bugfix or anything like that. -ShaneM

EDIT: Also, the code you posted about castle timer awards has already been in my builds for the past year or so. You're mentioning really old code. I'd prefer you not guessing my code if you don't understand exactly what I did because it's creating false labels or comments to a disassembly that is private. Thanks.

Shane,

Thank you for the update; I will discard that then. This also makes me wonder what other residual code bits there are in the SMAS versions of SMB and SMBLL that can be safely removed w/o messing up the game (and I mean besides those code chunks we already know about in the respective NES and FDS originals)? For example, the continue world code from the NES original of SMB could be removed because the world save/continue feature is different in SMAS.

I also edited my last post to remove the code in question you refer to in your last paragraph, and replaced it with something else to have you check out.

~Ben

SMB2J-2Q
Posted on 09-07-24 08:38 AM, in Super Mario Bros. Fixes (rev. 2 of 09-11-24 03:15 AM by SMB2J-2Q) Link | ID: 736

Red Goomba

Level: 9

Posts: 14/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Hi Shane,

I remember having played SMAS and, at one time, in either SMB or SMBLL I remember defeating Bowser in one of the x-4 levels and the victory music strangely did not play (it was silent the whole time Mario walked over to Toad, until the timer counted down).

The question is: what may cause the victory music to glitch out and not cue properly when you destroy Bowser?

~Ben (SMB2J-2Q)

SMB2J-2Q
Posted on 09-11-24 03:38 AM, in Super Mario Bros. Fixes (rev. 3 of 09-11-24 03:52 AM by SMB2J-2Q) Link | ID: 776

Red Goomba

Level: 9

Posts: 15/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
In SMAS, I also found another new flag for the AutoControlPlayer routine, which is at RAM 7E:0B7A. I wonder what it was supposed to have done, please?


$0b7a = AutoCtrlPlyrFlag

AutoControlPlayer:
sta SavedJoypadBits ;override controller bits with contents of A if executing here
lda #$01
sta AutoCtrlPlyrFlag ;set auto control player flag
bra NoClearACP ;then do unconditional branch to avoid clearing it in next routine

PlayerControlRoutine:
stz AutoCtrlPlyrFlag ;if branching here without performing AutoControlPlayer routine above, clear flag
NoClearACP:
lda GameEngineSubroutine ;check task here


This new flag is also checked in the ChkStart routine:

$0b75 = PauseMenuFlag
$0b7a = AutoCtrlPlyrFlag

ChkStart:
lda GameEngineSubroutine ;check if either pipe entry routine is running,
cmp #$02 ;and if so, skip to end this routine to avoid pausing game
beq ExChkStart
cmp #$03
beq ExChkStart
lda AutoCtrlPlyrFlag ;if flag for AutoControlPlayer routine was previously set,
bne ExChkStart ;also disable pause
lda PauseMenuFlag ;check if pause menu has been brought up
cmp #$02
bcs ExChkStart ;if so, exit this routine
lda SavedJoypad1Bits ;check to see if start is pressed
and #Start_Button ;on controller 1
...


The routine just above it, PauseRoutine, is also modified to disallow pausing during the victory mode. What makes me curious is that there are two different RTS branches here. The first one, which occurs if the player has defeated Bowser, branches to the end of the main pause routine, but all the subsequent RTS branches point to the end of the start button check routine.

PauseRoutine:
lda OperMode ;are we in victory mode?
cmp #VictoryModeValue
beq ExitPause ;if so, branch to exit routine
cmp #GameModeValue ;otherwise, are we doing main game mode?
bne ExChkStart ;if not, branch to exit routine
lda OperMode_Task ;if we are in game mode, are we running game engine?
cmp #$03
bne ExChkStart ;if not, branch to exit routine
lda GamePauseTimer ;check if pause timer is still counting down
beq ChkStart
dec GamePauseTimer ;if so, decrement it and leave
ExitPause:
rts


~Ben (SMB2J-2Q)

SMB2J-2Q
Posted on 09-11-24 07:16 PM, in Super Mario Bros. Fixes (rev. 2 of 09-11-24 07:17 PM by SMB2J-2Q) Link | ID: 784

Red Goomba

Level: 9

Posts: 16/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Posted by ShaneM
@SMB2J-2Q,

In a hex editor, did you try nopping all occurrences of “ AutoCtrlPlyrFlag” on a backup copy? What happened/what changes did you notice when you did?

It looks like if the player is being autocontrolled it sets a flag to disable pausing in the check start routine and if you’re manually controlling the player it is cleared. I wouldn’t know exactly for what unless I test it.

Edit: If I had to guess that’s what prevents pausing during flagpole slide or castle victory routine. A good way to test it is to NOP it and see if you can pause after touching flagpole, entry to 1-2 or castle victory. Let me know if my guess wasn’t right and I’ll figure it out when I get time if it isn’t.

About the RTS thing, Nintendo is known to do branches to not necessarily the closest RTS. It really doesn’t matter which one except farther branching. If I understood what you’re saying correctly.

Shane,

So far (when I NOP'ed the LDA instruction under 'ChkStart'), my test has failed, because it will not let me pause the game at all.

~Ben

SMB2J-2Q
Posted on 09-11-24 09:32 PM, in Super Mario Bros. Fixes (rev. 6 of 09-11-24 09:55 PM by SMB2J-2Q) Link | ID: 788

Red Goomba

Level: 9

Posts: 17/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Posted by ShaneM
Nop “lda #$01 and sta AutoCtrlPlyrFlag” in AutoControlPlayer and “stz AutoCtrlPlyrFlag” in PlayerControlRoutine and then nop” lda AutoCtrlPlyrFlag bne ExChkStart” in Chkstart. 5 different instructions in total. If not, I’ll get around to it when I can. Thanks.

Hi Shane,

Please forgive me, but I actually got it to behave the old way by also NOP'ing the BNE after it, without having to do the other things you mention.

Image 1 - end of level:


Image 2 - pipe intro:


When I ported the new AutoCtrlPlyrFlag to the NES, it does replicate what happens in SMAS by disallowing pause, except for when the player comes OUT of a pipe. I wonder what SMAS did to disallow pause while the player comes OUT of a pipe? This was the code added in to play the pipe sound coming out:

EntrMode2: lda JoypadOverride ;if controller override bits set here,
bne VineEntr ;branch to enter with vine
lda Player_Y_Position ;SMAS diff: check if player is at 176th pixel when coming out of pipe
cmp #$b0 ;SMAS
bne NoPipeUpSd ;SMAS if not, do not play pipe/injury sound
lda #Sfx_Pipe_Injury ;SMAS
sta Square1SoundQueue ;SMAS
NoPipeUpSd: lda #$ff ;otherwise, set value here then execute sub

In SMAS, there is another new address $0E4E, but again since the disassembly I am using doesn't give labels to any of these RAM addresses yet, this is why I have difficulty pinpointing exactly what they do.

~Ben

SMB2J-2Q
Posted on 09-12-24 03:39 PM, in Super Mario Bros. Fixes (rev. 3 of 09-12-24 03:41 PM by SMB2J-2Q) Link | ID: 794

Red Goomba

Level: 9

Posts: 18/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Posted by ShaneM
I had you NOP the other stuff for neatness. The code is really only used in the conditional statement in ChkStart. It is only set/cleared in the other two routines. It did exactly what I thought it would. There are a few ways to do that. I’ve coded mine a different way.

Also, $0B7A is not a valid flag on SMB1 NES. I’d use a different one.

In my case, I did assign it to a different one: $06B7, formerly used by JumpCoinMiscOffset.

I will use your version of the code, though, but I was curious as to what it did.

~Ben

SMB2J-2Q
Posted on 09-15-24 01:52 AM, in Super Mario Bros. Fixes (rev. 7 of 09-15-24 02:32 AM by SMB2J-2Q) Link | ID: 819

Red Goomba

Level: 9

Posts: 19/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Hi Shane,

I am curious as to the ChkGERtn routine:

ChkGERtn: lda GameEngineSubroutine ;get number of game engine routine running
cmp #$07
beq ExCSM ;if running player entrance routine or
cmp #$08 ;player control routine, go ahead and branch to leave
bne ExCSM
lda #$02
sta GameEngineSubroutine ;otherwise set sideways pipe entry routine to run
rts ;and leave

Specifically, this checks the GameEngineSubroutine variable for either routine $07 (for player entrance) or $08 (for player control) in action, and to branch to exit (ExCSM) if so. However, when checking for routine $08 it then says BNE (if not equal) and also leave the routine (to ExCSM), so unless they had intended to add additional code after this, then shouldn't that also be a BEQ or else if it is supposed to be a BNE branch, then shouldn't it be to StopPlayerMove? I am going to try that to see if any anomalies happen during the pipe intro scene.

UPDATE: I played the game with the change I applied and so far I have found no outstanding anomalies during Mario's automatic movement during the pipe intro scene.

~Ben

SMB2J-2Q
Posted on 09-15-24 05:43 PM, in Super Mario Bros. Fixes (rev. 2 of 09-15-24 05:47 PM by SMB2J-2Q) Link | ID: 831

Red Goomba

Level: 9

Posts: 20/39
EXP: 2707
Next: 455

Since: 08-21-24
From: Oak Grove, OR

Last post: 21 days
Last view: 19 days
Posted by ShaneM
Posted by SMB2J-2Q
Hi Shane,

I am curious as to the ChkGERtn routine:

ChkGERtn: lda GameEngineSubroutine ;get number of game engine routine running
cmp #$07
beq ExCSM ;if running player entrance routine or
cmp #$08 ;player control routine, go ahead and branch to leave
bne ExCSM
lda #$02
sta GameEngineSubroutine ;otherwise set sideways pipe entry routine to run
rts ;and leave

Specifically, this checks the GameEngineSubroutine variable for either routine $07 (for player entrance) or $08 (for player control) in action, and to branch to exit (ExCSM) if so. However, when checking for routine $08 it then says BNE (if not equal) and also leave the routine (to ExCSM), so unless they had intended to add additional code after this, then shouldn't that also be a BEQ or else if it is supposed to be a BNE branch, then shouldn't it be to StopPlayerMove? I am going to try that to see if any anomalies happen during the pipe intro scene.

UPDATE: I played the game with the change I applied and so far I have found no outstanding anomalies during Mario's automatic movement during the pipe intro scene.

~Ben


I optimized it and commented it anew. Use this one and credit me if borrowed.


ChkGERtn: lda GameEngineSubroutine ;load number of game engine routine running
cmp #$08 ;compare against the player control routine
bne ExChkGERtn ;if any other routine, branch to leave
lda #$02 ;otherwise load value to
sta GameEngineSubroutine ;set sideways pipe entry routine to run
ExChkGERtn:rts ;leave


Also, in the future could you please ask in a more generalized way instead of specifically calling me in every post for an answer? This is a community thread for everyone to participate in not just me. Thanks. LOL




Sorry about that.

I will try your optimized fix.

~Ben
Pages: 1 2


Main - Posts by SMB2J-2Q

Affiliates:


Acmlmboard v2.5.6+neo (2024-08-13)
© 2005-2024 Acmlm, Emuz, NinCollin, et al.

Page rendered in 0.142 seconds. (1021KB of memory used)
MySQL - queries: 113, rows: 471/477, time: 0.115 seconds.