Language…
7 users online:  BeeKaay, Daizo Dee Von, DashGamer, E623, Guido_Keller, Isikoro, kasoku - Guests: 233 - Bots: 431
Users: 64,795 (2,377 active)
Latest user: mathew

[OBSOLETE] Disassembling SMAS (SMASH DIZ! Project)

Link Thread Closed
Apply this to your SMAS ROM, and play SMB2. You will notice a slight difference.

I was a bit lazy here, so I just cluttered some things up. This room is pretty much what I can do with SMB2 levels right now (heh, not much. I'm a bit more familiar with the bonus slots and Character Select / Game Over screens, though.), namely, changing the object and sprite placing data, HDMA BGs, BG pointers, main level header format and music.
No, this is definitely not that good thing I promised for next week. This is just... another test.

Oh yeah this hack is hard.
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------
Originally posted by Roy


You might want to remind everyone whether the SMAS ROM must be headered or headerless, and also whether the SMAS ROM must be from USA or Europe.

If I would guess, I would either use a headered ROM from USA (like I do with SMW), or use the firstly found ROM; but my guess might be wrong. I will not be one of the users to try Roy's patch (because I am not playing SMAS in emulator), so I am not checking my guess.

I found some ROM sites; they seem to have four versions of SMAS:
* Super Mario All-Stars (E)
* Super Mario All-Stars (U)
* Super Mario Collection (J) (V1.0)
* Super Mario Collection (J) (V1.1)

Hacking Super Mario World since 28 February 2009
SMWDISC
Well, if it isn't headered, you can just remove the 'header' part in the Xkas patch. And use the American version, of course. Although I doubt it would make much of a difference, whether you'd use the American or European version - not sure about the Japanese.

There seems to be a ROM on the internet which has a few significant changes from the real game (like rotating text when you load up the ROM). Don't use that one.
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------
Now that sucks. Because that is exactly the version I have :/
Hm, actually it does work. Small testing error, I guess. Really though, that ROM is quite different from the original SMAS. I wonder why they made it that way... (An example, besides from the image on ROM load-up, is that the SMB3's Blooper acts different.)
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------


Okay, I discovered where the 'Story' data was, and, well... that made me go wild with ideas...

...not quite. XD This is the only decent idea I could get. Meh.

Quote

CODE_1290FF: A9 15 LDA #$15 ; \ Bank num = $15.
CODE_129101: 85 05 STA $05 ; |
CODE_129103: BF 3F E8 15 LDA POINTER_15E83F,x ; | Get address of tables...
CODE_129107: 85 04 STA $04 ; | ...which contain the 'Story' data...
CODE_129109: BF 50 E8 15 LDA POINTER_15E850,x ; | into [$03]
CODE_12910D: 85 03 STA $03 ; /


The actual data ranges from $15E861-$15EAE0.

I also found out (finally!) how the sprite tables really work. Their format is a piece of cake - I wonder why I didn't see this all the time.

Let's say we have this table:

Quote

TABLE_11F6D1: .db $03,$01,$EC,$07,$01 ; Level 1-1, main room.
.db $1C,$02,$5C,$03,$E5,$07,$01,$6C
.db $02,$8C,$01,$CC,$05,$03,$79,$01
.db $D4,$09,$01,$04,$02,$34,$3B,$87
.db $3B,$C7,$07,$03,$A9,$03,$BC,$03
.db $C6,$05,$01,$9C,$03,$E5,$05,$01
.db $2C,$02,$4C,$07,$01,$1C,$03,$45
.db $02,$4C,$05,$01,$95,$14,$D1,$01


As you'd guess, we start with the first byte.
The first byte here tells you how many sprites are going to be loaded for that screen (since this is the first value in the table, that'd be screen 0 of the room in question). 1 sprite = 2 bytes, and this byte includes itself.
So in this case:

Quote
$03,$01,$EC


This is the set for screen 0. The first byte ($03) specifies how many bytes there will be loaded for that screen - 3. For the amount of sprites, that means: (3 - 1) : 2 = 1 sprite. $01 specifies the sprite type (Red Shyguy), $EC the position it will appear in (X = E, Y = C).
Then, it goes to the next set.

Quote
$07,$01,$1C,$02,$5C,$03,$E5


( 7 - 1 ) : 2 = 3. So, 3 sprite. $01,$1C = Red Shyguy on X = 1 and Y = C, $02,$5C = Tweeter on X = 5 and Y = C, $03,$E5 = Blue Shyguy on X = E and Y = 5.
And then it goes to screen 2. And it just goes on and on - there isn't a byte to terminate it. Dependant on the size of the level, you will need a set of sprites for each screen. To load no sprites at all for one screen, use:

Quote
$01

The only group this will form, is a group with itself. It means no sprites will be included.

Having that said, I'm thinking about starting a SMB2 hack up. It's going to be slightly harder than SMB2 itself actually is, and the levels should be longer.
I'm also thinking of adding a few (small) ASM hacks in.
One thing I'm thinking of is to give each character its own special ability to survive - Luigi and Peach already have that, Toad might, but Mario doesn't have one yet.
I'm still thinking of one.
Another one I'm thinking of, is to give a hint each level, like 'High ledges', 'Freight train', etc.
Heck, that might become level names.
This is because I'm going to make levels in which you need a specific character to pass the level.

Enough rattling, here are some screens:


Getting out of here isn't hard per se - take your time. I wouldn't use Toad, by the way.


You have to ride the Beezo to make it. It's a bit harder than riding a Pidgit, since Beezo actually tries to get rid of you.


This is the uninspired end, for now. I'm still building this level up, anyway.

Expect a full level out later this week.
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------
It's amazing what I am seeing here. I knew the day would come that Super Mario All-Stars was going to get hacked, but I didn't know there would be an editor and such. Also Roy, nice find on the text editing, must of taken you a while!

I can't wait to hack this a game, a great hacking future awaits Team Haunted and the rest of the users on SMWC.
Keep up the good work!
Yesterday I found the Map 16 page data (by checking the object load routine around $12F000). This is an illustration of page 0 (there are, like in SMW, page 0 and page 1):



I was quite surprised to see quicksand tiles can be used in grass worlds :o. Oh, yes, this illustration uses the World 1 graphics and the grassland palette. It might look different in other areas. I'm pretty sure the ice tileset is different, for example.

Either way, direct Map16 access might make it easier to add ground. Because the regular ground SMB2 uses (the grassy ground), is not controlled by loading an object, but it is controlled by the level header and a few special objects. (Special objects are determined by a relative position of $Fx - I haven't explained how objects are loaded in the levels, have I?)
Either way, that's quite inconvenient, since customizing the ground is very hard to pull off. With direct Map16 access, this would certainly be easier.

The Map16 RAM tables are from $7E2000 through $7E8FFF - low byte, and $7E9000 through $7EFFFF - high byte.
Why are these so big, when a room can only contain screens 0-F? Well, these tables hold the Map16 information of ALL rooms in the level. This means any level has no more and no less than 10 rooms. Yes, I'm sorry about this limit - complain to Nintendo.
I'm not sure why they did this, there doesn't seem to be an apparant reason for it, other than the fact that loading times during rooms might take a little longer...
'But 1-1 doesn't have 10 rooms?' It does have them - however, 4 of them remain unused. But they can easily be repointed to data to make them usable.

Yeah that's it for now. I'm a bit too lazy to make an illustration of page 1 - maybe tomorrow.
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------


No, I have no idea what the garbage at the bottom is.
That's all for now.

Edit: Note of interest:

Data for most of this screen (except for the border) is at $15E250-$15E41E.

Edit 2: Plol.


Table here is at $15E00F-$15E24F.
Oh yeah, these are stripe image tables.
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------
Originally posted by Roy
note of interest

[23:04:53] <Roy> <%Roy|SMB2> http://i43.tinypic.com/9kxveb.png <-- Why Roy's SMB2 will be unpopular.
[23:05:34] <~Ersanio> WHAT
[23:05:35] <~Ersanio> HAVE YOU DONE
[23:05:39] <~Ersanio> OH MY GOD!!
[23:05:43] <~Ersanio> MARIO... ;_;
[23:05:47] <Roy> XD
[23:05:56] <~Ersanio> WHYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
[23:05:59] * ~Ersanio rage
[23:06:01] <~Ersanio> ...
[23:06:02] <~Ersanio> *ahem*
My blog. I could post stuff now and then

My Assembly for the SNES tutorial (it's actually finished now!)
HDMA Expansion Patch v1.0!

Instead of being limited to 4 HDMA BGs, you can now expand the amount of HDMA gradients you want to have in SMB2 to 255. You have to code these yourself, but this ASM hack helps a lot. I also included the sunset BG you saw earlier.

Credit not needed.

I guess this is my first released SMB2 production.

Edit: My room edit doesn't count for that.
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------
This is starting to develop well. Nice work, guys. One question: was the story data in different hex numbers e.g. 12 0F 19 (ROY) Or done with spaces? 12 00 0F 00 19.
I just noticed the patch kind of alters the unused sea BG... I'll fix that when I get home. (Which is not now, no.)
Also, do you know how stripe image works? If not...
The letter tiles start at CA, and they end at E3 (except for Q, it uses tile EA. You'd expect it to use DA, but that's an 'X' sign...).
Either way, this is done with stripe image. So, you specify the place where the tiles are loaded, the amount of tiles for one stripe, then the actual tile data comes in the following format: TTTTTTTT YXPCCCTT where TTTTTTTT = tile number and the YXPCCCTT byte is for the tile properties. (Y = flip tile around X-axis, X = flip tile around Y-axis, P = priority bit, CCC = palette number, TT = tile page.)

IIRC, SMB2 has 5 slots of 7F tiles reserved for Layers 1 and 2. (As opposed to 4 in SMW.)

To get back at your question, 'ROY' would have to be DB 15 D8 15 E2 15, where the 15s are the YXPCCCTT bytes.
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------
Here's the working version of the patch.
It's also structured in a way that you might understand the whole thing better.
Any questions about the patch - I'd rather see them in a PM, please. (So they don't fill this thread. NOT that I expect many people to use this patch, but....)

And that's the last post I'll waste on this one.
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------
Well, it seems that SMB2 has a Map16 table for Layer 3. This one doesn't change per level, but per room - thus, it is smaller.
It's located at $7FC000-$7FC95F.

Here's a small illustration I made:



There's more, but it's mostly garbage. (Doesn't mean it can't be used for other stuff in the future.)

Edit: VRAM map, I'm relatively sure it's correct.

$0000-$1FFF : Layer 1 Tilemap
$2000-$3FFF : Layer 2 Tilemap
$4000-$8FFF : Layer 1+2 Character Data
$9000-$9FFF : Layer 3 Tilemap
$A000-$BFFF : Layer 3 Character Data
$C000-$FFFF : Object character data
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------
There's actually slightly more to it than I thought.
I was searching for a Map16 table for Layer 3 and I found it relatively quickly - $159237 through $159306 cover up tiles 00-19, and $159307 - $15934E holds 1A-22, which I neglected yesterday, because I thought they were just random.
They're certainly not - they're the light beams from the shining doors.
However, it seems like there are two sets of Map16 tiles that can be loaded - all tiles of 00-22 (and garbage after that), or just 1A-22 (and garbage). I wonder what's the purpose of this seperation, since the first covers the second.

Here's what I mean:

Quote


CODE_1583F2: AE 33 05 LDX $0533 ; \ Get room + level number into index.
CODE_1583F5: BF 98 D0 11 LDA TABLE_11D098,x ; |
CODE_1583F9: 18 CLC ; |
CODE_1583FA: 6D 34 05 ADC $0534 ; |
CODE_1583FD: AA TAX ; |
CODE_1583FE: BF 6B 91 15 LDA TABLE_15916B,x ; | Load which set of Layer 3 Map16 tiles to use (the cloud tiles or the light beams of the shining door)
CODE_158402: 0A ASL A ; | Multiply by 2.
CODE_158403: AA TAX ; |
CODE_158404: BF 33 92 15 LDA POINTER_159233,x ; | Get low byte of Map16 table.
CODE_158408: 8D 44 07 STA $0744 ; |
CODE_15840B: E8 INX ; |
CODE_15840C: BF 33 92 15 LDA POINTER_159233,x ; | Get high byte of Map16 table.
CODE_158410: 8D 45 07 STA $0745 ; |
CODE_158413: A9 15 LDA #$15 ; | Bank number = $15.
CODE_158415: 8D 46 07 STA $0746 ; /
CODE_158418: 60 RTS ; Return.

POINTER_159233: .dw TABLE_159237
.dw TABLE_159307


I personally don't see any purpose in this. Since, I assume, what would be tile 00 if you'd load 159307, would be the same thing as tile 1A if you were to load 159237.

Just take a look when I changed it to use 159237 in a cave level which originally used 159307:


--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------
I found the Layer 3 Map16 table for SMB1 and TLL.


Location: $7F3000-$7F3A7F

Using this, I mapped out the very first screen of clouds:


Your layout has been removed.
Oh, that's quite nice.

Either way:



I found the data for the miniature levels at the 'World x-x' screens, the palette data as well as the tilemap data.

Tilemap pointers:

Code
TABLE_15EF00:           .dl TABLE_15EF15 ; World 1, grassy image. (Images during 'World x-x' screen.)
                        .dl TABLE_15F0A5 ; World 2, desert image.
                        .dl TABLE_15EF15 ; World 3, grassy image.
                        .dl TABLE_15F235 ; World 4, ice image.
                        .dl TABLE_15EF15 ; World 5, grassy image.
                        .dl TABLE_15F0A5 ; World 6, desert image.
                        .dl TABLE_15F3C5 ; World 7, air image.


Palette data:

Code
TABLE_13DCDA:          .db $00,$00,$00,$00,$00,$00,$60,$00
                       .db $00,$00,$00,$00,$C0,$00

TABLE_13DCE8:          .db $51,$7F,$40,$49,$51,$7F,$F5,$7E
                       .db $51,$7F,$40,$49,$F5,$7E

CODE_13DCF6:        C2 30         REP #$30                  ; Accumulator and Index = 16-bit.
CODE_13DCF8:        AD 35 06      LDA $0635                 ; \ Get world number * 2 into index.
CODE_13DCFB:        29 0F 00      AND #$000F                ;  |
CODE_13DCFE:        0A            ASL A                     ;  |
CODE_13DCFF:        AA            TAX                       ; /
CODE_13DD00:        BF E8 DC 13   LDA TABLE_13DCE8,x        ; \ Get BG colour for the 'World x-x' screen.  
CODE_13DD04:        8D 00 0B      STA $0B00                 ; /
CODE_13DD07:        BF DA DC 13   LDA TABLE_13DCDA,x        ; \ Get index for different palette set.     
CODE_13DD0B:        AA            TAX                       ; /
CODE_13DD0C:        A0 00 00      LDY #$0000                ; \ Y = #$0000.
CODE_13DD0F:        BF 55 F5 15   LDA TABLE_15F555,x        ;  | Load colours into palette 1.
CODE_13DD13:        99 20 0B      STA $0B20,y               ;  |
CODE_13DD16:        BF 75 F5 15   LDA TABLE_15F575,x        ;  | Load colours into palette 2. 
CODE_13DD1A:        99 40 0B      STA $0B40,y               ;  |
CODE_13DD1D:        BF 95 F5 15   LDA TABLE_15F595,x        ;  | Load colours into palette 7. 
CODE_13DD21:        99 E0 0B      STA $0BE0,y               ; /
CODE_13DD24:        E8            INX                       ; \ Get to next colours.
CODE_13DD25:        E8            INX                       ;  |
CODE_13DD26:        C8            INY                       ;  |
CODE_13DD27:        C8            INY                       ;  |
CODE_13DD28:        C0 20 00      CPY #$0020                ;  | Check if full palette has been uploaded.
CODE_13DD2B:        D0 E2         BNE CODE_13DD0F           ; / If not, loop.
CODE_13DD2D:        A9 FF 7F      LDA #$7FFF                ; \ Palette 3 colours D-F = white.
CODE_13DD30:        8D 7A 0B      STA $0B7A                 ;  |
CODE_13DD33:        8D 7C 0B      STA $0B7C                 ;  |
CODE_13DD36:        8D 7E 0B      STA $0B7E                 ; /
CODE_13DD39:        A9 96 28      LDA #$2896                ; \ Palette 5 colour 9-B = pink-ish colours.
CODE_13DD3C:        8D B2 0B      STA $0BB2                 ;  |
CODE_13DD3F:        A9 5F 49      LDA #$495F                ;  |
CODE_13DD42:        8D B4 0B      STA $0BB4                 ;  |
CODE_13DD45:        A9 9F 6E      LDA #$6E9F                ;  |
CODE_13DD48:        8D B6 0B      STA $0BB6                 ; /
CODE_13DD4B:        E2 30         SEP #$30                  ; Accumulator and Index = 8-bit.


I added a small ASM hack to create a gradient, as I'm personally not a huge fan of backdrops that exist out of only 1 colour.
I'm planning to make an ASM hack that will make it possible to have a different miniature level per level instead of per world - this shouldn't be extremely difficult, since this will only require some repointing of the pointer tables.
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------
Roy, your work never ceases to amaze me.
----------

Interested in MushROMs? View its progress, source code, and make contributions here.

Link Thread Closed