Points of Required Attention™
Friendly reminder: Please don't respond to spammers! Their posts inevitably get memory-holed when staff get around to, leaving behind an inexplicable tableau of you shouting at nothing and (if they otherwise would have been alone in a thread) dangling posts and wrong postcounts.
Views: 47,900,468
Main | FAQ | Uploader | IRC chat | Radio | Memberlist | Active users | Latest posts | Calendar | Stats | Online users | Search 07-19-18 07:38 AM
Guest: Register | Login

0 users currently in ROM Hacking | 2 guests

Main - ROM Hacking - SMB2j skid sound into SMB1 New thread | New reply

Posted on 04-23-08 10:03 PM Link | Quote | ID: 82274

Level: 53

Posts: 384/691
EXP: 1154564
Next: 2555

Since: 06-27-07
From: cKy

Last post: 1485 days
Last view: 1197 days
I've already accomplished doing this. However the skid sound is located in the worst place to compromise for compression. It's coding is located around level 1-2 and 1-4's level layout.

I'm not really good with ASM, but couldn't I expand the ROM and move the code to an empty spot?


Posted on 07-10-10 12:23 AM Link | Quote | ID: 132812

Level: 5

Posts: 3/4
EXP: 433
Next: 96

Since: 07-09-10
From: hmm what happened here

Last post: 2931 days
Last view: 2930 days
Hello I AM AWSOME!Probably, you would have to find the spot where Mario Skids and see how to add a sound to that. I've never thought of that!


Posted on 07-10-10 09:19 PM Link | Quote | ID: 132853

Hammer Brother
Level: 64

Posts: 555/1050
EXP: 2098875
Next: 115222

Since: 02-16-08
From: Insectduel's office

Last post: 90 days
Last view: 90 days
SMB1 did use a 512 byte trainer header. If your ROM is 41,488 bytes, then you should learn ASM and especially JMP or JSR.

Posted on 07-11-10 09:27 AM Link | Quote | ID: 132866

Yellow Stalfos
Level: 66

Posts: 981/1145
EXP: 2459976
Next: 1875

Since: 07-06-07
From: Qu├ębec

Last post: 1518 days
Last view: 770 days
Hmmm, I'm perplex. Super Mario Bros. (JU) [!].nes has no trailer, a length of A010 bytes, and virtually no free space at all...

Posted on 07-11-10 07:56 PM (rev. 3 of 07-11-10 08:01 PM) Link | Quote | ID: 132885

Level: 31

Posts: 143/194
EXP: 172938
Next: 12425

Since: 05-02-07
From: Shelton, WA

Last post: 364 days
Last view: 207 days
Posted by Trax
Hmmm, I'm perplex. Super Mario Bros. (JU) [!].nes has no trailer, a length of A010 bytes, and virtually no free space at all...

We all can get by with using doppleganger's SMB disassembly (SMBDis) via Romhacking.net.

Mske sure you have a prebuilt header, and 8k CHR from the SMB ROM

And even though it breaks compatibility with current SMB tools (AND normal IPS patch format), you can still make a new hack out of it, via UPS, Binary Diff, or better yet, Xdelta.

Just make sure to know what you are doing and possibly learn bankswitching too, For that, get Disch's Mapper Documentation collection:


Beware of the Sprite 0 detection near the end of Non Maskable Interrupt (NMI) code, I could not even hack it without corrupting the whole game, making it glitch!

Trainers are a outdated and stupid feature that is mainly for compatiblity reasons, Do not even use it unless you want to get criticized by Romhacking.Net and such!

Mah boi, romhacking is what all true warriors strive for!

I wonder what's for dinner?

(post deleted) ID: 158681

Posted on 10-10-14 07:32 AM Link | Quote | ID: 158724

Compromised account.
Please contact an admin to restore access.
Level: 32

Posts: 178/285
EXP: 193202
Next: 13240

Since: 02-17-14

Last post: 1029 days
Last view: 544 days
Since SMB1 is NROM, it is limited to 8000 bytes of binary. Here are some ways to attain over 200 free bytes to add the code (more than enough). Use doppleganger's SMB1 disassembly and assemble with a make.bat file:

Remove residual code. Here are some places that code can be removed, also some other ways to save space; if you follow my advice, you'll get roughly 200 free bytes (note that not everything labeled in the disassembly as 'residual' are really residual; the ones I listed I've proven residual):

;In "PrintVictoryMessages:", remove these
cmp #$09
bcs IncMsgCounter

;In "Palette1_MTiles:" remove these
.db $24, $2f, $24, $3d ;flag ball (residual object)

;In "WaterPipe:" remove this:
ldy AreaObjectLength,x

;In "ScrollScreen:" remove this
sta ScrollIntervalTimer

;In "FlagpoleSlide:" remove these
cmp #FlagpoleFlagObject
bne NoFPObj

;In "NoFPObj:" remove this
inc GameEngineSubroutine

;In "UseMiscS" remove this
sty JumpCoinMiscOffset

;In "MovePlatformUp:" remove these
cpy #$29
lda #$09

;In "CheckEndofBuffer" remove all these
lda (EnemyData),y
and #%00111111
cmp #$2e
beq CheckRightBounds

;In "SetupGFB" remove this
jsr GetFirebarPosition

;In "BPGet:" remove these
lda FlyCCBPriority,y
sta Enemy_SprAttrib,x

;In "DrawFlameLoop:" remove this
sta Sprite_Y_Position+12,y

;In "FirebarSpin:" remove
ldy #$18

;In "SpinCounterClockwise:" remove
ldy #$08

;In "RightPlatform:" remove
sta $00

;Remove "ResidualXSpdData:" completely

;In "CheckToAnimateEnemy:" remove this

;In "DrawBrickChunks:" remove
lda #$75

;In "PowerUpGrabFreqData:" remove these at the end
.db $22, $1c, $14

;In "FindAreaMusicHeader:" remove this
sty MusicOffset_Square2

;Remove "ResidualHeaderData:" completely

;Did you know you could get 16 free bytes from changing lda BrickShatterEnvData,y in "ContinueBrickShatter:" to "lda BowserFlameEnvData,y"? They both make the same SFX but now you have 16 free bytes where the data used to be!

Optimize the following routine to get another 32 bytes:

;This is the original routine
ldx ObjectOffset
jsr DumpSixSpr
lda #$02
jsr DumpSixSpr
jsr GetXOffscreenBits
ldy Enemy_SprDataOffset,x
bcc SChk2
lda #$f8
sta Sprite_Y_Position,y
SChk2: pla
bcc SChk3
lda #$f8
sta Sprite_Y_Position+4,y
SChk3: pla
bcc SChk4
lda #$f8
sta Sprite_Y_Position+8,y
SChk4: pla
bcc SChk5
lda #$f8
sta Sprite_Y_Position+12,y
SChk5: pla
bcc SChk6
lda #$f8
sta Sprite_Y_Position+16,y
SChk6: pla
bcc SLChk
lda #$f8
sta Sprite_Y_Position+20,y
SLChk: lda Enemy_OffscreenBits
bcc ExDLPl
jsr MoveSixSpritesOffscreen
ExDLPl: rts

;okay, now change it to this:

ldx ObjectOffset
jsr DumpSixSpr
lda #$02
jsr DumpSixSpr
jsr GetXOffscreenBits
ldy Enemy_SprDataOffset,x
ldx #$06
SChk: asl
bcc SChkNx
lda #$f8
sta Sprite_Y_Position,y
SChkNx: iny
bne SChk
ldx ObjectOffset
sbc #$18
lda Enemy_OffscreenBits
bcc ExDLPl
jsr MoveSixSpritesOffscreen
ExDLPl: rts

There are many more ways to clear up free space. This next method will get you about 150 free bytes:

SMB1 was very wasteful with level data. For example look at this:

^The above leftmost brick can be made to a horizontal brick length 4 and the rightmost brick can be removed (see below). This can be done with various objects in ALL levels/rooms to save space while functioning the same.

The above trick can also be done with enemies while function the same, too. See below.



Notice that I changed it from a 'Little Goomba' to a '2 Little Goomba (V=10).

With the above, counting every possible level, you get around 150 free bytes this way. I hope this was helpful instead of having to convert this from NROM to MMC3 and extra routines. 200 or so free bytes is a lot of free space to make many routines.

EDIT: Here is another code that can be optimized.

;Original code

lda Player_OffscreenBits
cmp #$f0
bcs ExCPV
ldy Player_Y_HighPos
bne ExCPV
lda Player_Y_Position
cmp #$d0
ExCPV: rts

;Optimized code
lda Player_OffscreenBits
and #$f0
beq ExCPV
ExCPV: rts

;you've saved 7 bytes

Also, remove anything labeled as "free space" etc. They will always be bytes of $FF. They are scattered throughout the file and will add up to another 20 or so free bytes.

Make sure that the assembled binary file is no GREATER or LESS than 32,768 bytes. Whenever you add or minus code, you need to pad it or else there will be trouble. I can tell you are new to this. My advice is use something like Notepad++ that tells you the line numbers for when the assembler shoots out a "value out of range" or a line with an error or what not.

Here's one more that's easy to miss. The underwater level has a room pointer to World 3 that's never used. (Room pointers always take 3 bytes). So removing it will give you three more. I just mentioned this because this one was hard to find. But the other wasteful ones are easy.

In total, another 33 bytes right here (I took advantage of these in my SMB1 hacks to load the beta tiles I found):

;In "VRAM_AddrTable:", remove
.dw UnusedAttribData

.dw BowserPaletteData

;You can also remove the 8 bytes from the "BowserPaletteData" data and just change the palette to $1A using FCEUX PPU viewer.

;you can also remove these; remember to update where the immediate values are loaded for certain objects like trees (only takes a few minutes):
.db $45, $47, $45, $47 ;breakable brick (not used)
.db $24, $47, $24, $47 ;half brick (not used)

;remove this completely
lda #$ff ;this is residual code, this value is
sta $06c9 ;not used anywhere in the program

;In "ProcHammerObj:" remove
sta $01

;In "SwimCCXMoveData:" remove
.db $04, $04

;In "ShufAmtLoop:" remove
jsr DoNothing

Here's another way to get 55 more free bytes:

;original did this...change it to what I have after this to save 55 bytes

.db $f8, $a0, $70, $bd, $00

.db $20, $20, $20, $00, $00

lda Enemy_State,x ;check cheep-cheep's enemy state
and #%00100000 ;for d5 set
beq FlyCC ;branch to continue code if not set
lda #$00
sta Enemy_SprAttrib,x ;otherwise clear sprite attributes
jmp MoveJ_EnemyVertically ;and jump to move defeated cheep-cheep downwards
FlyCC: jsr MoveEnemyHorizontally ;move cheep-cheep horizontally based on speed and force
ldy #$0d ;set vertical movement amount
lda #$05 ;set maximum speed
jsr SetXMoveAmt ;branch to impose gravity on flying cheep-cheep
lda Enemy_Y_MoveForce,x
lsr ;get vertical movement force and
lsr ;move high nybble to low
tay ;save as offset (note this tends to go into reach of code)
lda Enemy_Y_Position,x ;get vertical position
sec ;subtract pseudorandom value based on offset from position
sbc PRandomSubtracter,y
bpl AddCCF ;if result within top half of screen, skip this part
eor #$ff
clc ;otherwise get two's compliment
adc #$01
AddCCF: cmp #$08 ;if result or two's compliment greater than eight,
bcs BPGet ;skip to the end without changing movement force
lda Enemy_Y_MoveForce,x
adc #$10 ;otherwise add to it
sta Enemy_Y_MoveForce,x
lsr ;move high nybble to low again
BPGet: lda FlyCCBPriority,y ;load bg priority data and store (this is very likely
sta Enemy_SprAttrib,x ;broken or residual code, value is overwritten before

;;;;delete the above and replace it with this to save the 55 extra bytes:

ldy #$20
lda Enemy_State,x ;LDA $1E,X
and #$20
bne end ;$CEE8
jsr MoveEnemyHorizontally ;$BF07
ldy #$17
end: lda #$05
jmp SetXMoveAmt ;$BF9B

In total, if you did everything I told you to do, you've saved near 300 bytes! More than enough to add skid sound. To add the skid sound, rip the code from the SMB2J disassembly by doppleganger. If you can't find it, let me know and I'll assist you. --ShaneM

EDIT: Here is the skid code in SMB2J:

.db $47, $49, $42, $4a, $43, $4b

PlaySkidSfx: ;;this code needs to be used in NoiseSfxHandler. make a conditional bmi mnemonic for this to work (hint: ldy NoiseSoundQueue as the class 2 statement).
sty NoiseSoundBuffer
lda #$06
sta Noise_SfxLenCounter

lda Noise_SfxLenCounter
lda SkidSfxFreqData-1,y
lda #$18
bne DecrementSfx3Length

At the end, when the day is over, the only one left to face is yourself. Have you been true to yourself and made the most of your day?

Main - ROM Hacking - SMB2j skid sound into SMB1 New thread | New reply

Acmlmboard 2.1+3δ (2016-01-08)
© 2005-2016 Acmlm, blackhole89, Xkeeper et al.

Page rendered in 0.108 seconds. (351KB of memory used)
MySQL - queries: 62, rows: 89/0, time: 0.064 seconds.