don't click here

S2-SMS block maps

Discussion in 'Engineering & Reverse Engineering' started by Ambil, Sep 17, 2005.

Thread Status:
Not open for further replies.
  1. Ambil


    I want that heinous hedgehog hammered! Member
    Kay, this is the next episode of my research in the Sonic 2 for SMS game. As I told you in the previous topic, each 32x32 block (which are directly placed in the screen) are made of 16 tiles (8x8), as Magus explained in his SMS guide. The data to create the blocks from the tiles is called the 32x32 mappings, and it's quite well explained in Hivebrain's hacking guide. But the questions about how the blocks are placed in the levels is a mstery that I have to found by myself, andhere I got the answers.

    As I explained in the previous topic, level layout data for UGZ1 (for example) is compressed at offset 0x3ADBB in the ROM. However, there's no plan to be working with compressed data, so after I made a savestate, I knew I had to research in the SMS features.

    Master System has 8 KB of RAM ($2000 bytes, from 0xC000 to 0xDFFF in the memory map). The level layout is located in the lower $1000 bytes, while the upper 4 KB are destinated to hold misc variabes (I'll talk about that later). But how come that, having only 160 ($A0) blocks, they are listed in the RAM as all values $00-$FF? The answer is found in the 32x32 mapping offset index for the level in the ROM. As shown in Hivebrain's ROM map, this offset index starts at 0x3DD80 to 0x3FD80, and it contents 256 16-bit, little endian pointers, which point to their respective ($00-$FF) next data in ROM for the 32x32 block mappings. To sum up, each type of 32x32 block may be represented by different numbers in the RAM.

    So I got this, started to look at the pointers in the offset index, and figured out how the values in the RAM fit to the blocks, represented in this text file. And we have then this table of 32x32 blocks. See how some of them are exactly equals:


    I have to credit a guy called DMEnduro for creating this block sheet, and for teaching me a very interesting feature of Photoshop. You can create image files right from the RAM content -- yes! It is made with RAW image files. How to do:

    In the level you're playing in MEKA, choose Dump, Configuration, and set Raw mode for the next dumps. Then, dump the RAM content to a simple binary file.

    This said, open the dump in a hex editor and cut off the bytes from 0x1000 to the end (as only 0x0000 to 0x0FFF will represent the level layout). Name it with .raw extension and open it in Photoshop. The program will ask you for the image dimensions, colors and header. I'm going now to explain how to fill all the fields.


    Color settings will always be 1 channed in 8-bit depth, and the header is 1 byte (that $00 at the beginning). Also, be sure to set the mark in "Remember when saved".

    The deal is now, I have found the meaning of that "level size" in the ROM level headers. Start with our example, the level header for UGZ1 (located at 0x56FB) is 22 ($16) bytes long, copied here.

    Code (Text):
    1. 0F 80 9D 0E BC AD A8 00 58 FF 98 04 08 00 08 00 00 14 10 02 45 4B                              
    This means, according to Hivebrain's notes, that the level is $14 wide and $02 high. Well, after researching through the level and the memory editor of MEKA I could find these offsets in the RAM:

    $D284 = X Cam (2 Bytes, Little endian)
    $D286 = Y Cam (2 Bytes, Little endian)

    Those are for sure, and how they match to the values in ROM is a mistery now uncovered. That $14 means that the X camera will go through $1400 positions. At the beginning, the X camera will be set to $0000, and at the end it will read $13FF.

    Does this mean that the level is $1400 pixels wide? No. The camera position is the most up-left pixel that you see in the screen. And we must remember that the SMS screen is 256 ($100) pixels wide. So this means that UGZ act 1 is $1500 = 5376 pixels wide.

    Same way, $02 high means that the Y camera will be in $200 positions. The virtual screen of the SMS is 224 ($E0) pixels high (despite we can only see the upper 192 lines), so the level is $200 + $E0 = $2E0 = 736 pixels high.

    No matter if you do the calculations in decimal or hex base, you will get that UGZ1 is 168 blocks long and 23 blocks high. So then, why not input these sizes to the Photoshop dialog box?


    And bingo, we get the block map. Each pixel represents one 32x32 block. We can apply the same methods to all levels in the game, while we go through its levels, and get a collection of all level block maps.

    So yeah, this is what I could do with the sources I had, and even I'm not sure if this will be directly useful for my project Sonic lol, now we have a little diagram of each Sonic 2 SMS level.

    Credits go to Magus, Hivebrain and MDEnduro. Hope you like it and good luck,

  2. Hivebrain


    53.4N, 1.5W
    Nice work. Something just occurred to me:

    0F 80 9D 0E BC AD A8 00 58 FF 98 04 08 00 08 00 00 14 10 02 45 4B

    The level sizes could be two bytes long, little endian. This would make more sense than only using one byte.
  3. Ambil


    I want that heinous hedgehog hammered! Member
    Maxim already had that idea, he explained it at SMS Power, and since I can draw a whole block map with one byte, he suggests that the 16-bit data could just be the viewable area.
  4. Tweaker


    Ambil for Tech Member!

    This information will be really useful to me, because I plan on hacking the SMS games when I can. Good work!
  5. Robjoe


    Indeed. Awesome stuff you got there. Now if only people hacked the 8-bit games. If we could get enough info. compiled into one guide, that might spark somehacking. But the 16-bits will probably always reign supreme in the hacking scene because of their flashiness and our abundant knowledge on them.
  6. Mustapha


    A+ Oldbie
    A PLUS
    Kick ass work, Ambil..and congrats on your promotion, you deserve it :(

    Edit: Added a better ending.
Thread Status:
Not open for further replies.