# Question about Sonic 2 tile mappings

Discussion in 'Engineering & Reverse Engineering' started by AeroGP, Aug 5, 2008.

Not open for further replies.
1. ### AeroGP

Member
130
1
18
Los Angeles, CA
Sonic for GameMaker: Studio
Are the 8x8 indexes in the 16x16 mappings the same in VRAM as they are in the actual rom (assuming you apply the correct offset)? If not, is there a known conversion between the two?

It seems as though they're not, because some of them are not divisible by 0x20, would exceed the correct pattern section if multiplied by 0x20, and would start at the wrong starting position for an 8x8 pattern if used as is.

Maybe they're based on every pattern overall, and not just the one matching them when disassembled? Please help me out here.

Tech Member
3. ### AeroGP

Member
130
1
18
Los Angeles, CA
Sonic for GameMaker: Studio
I've already been using that as a guide.

PCCY XAAA AAAA AAAA, where A is the index of the pattern in VRAM divided by 0x20.

Just pulling the first 16-bit pairing from EHZ's 16x16 mappings (disassembled):

63 8C

Isolating A from this yields 0x38C. The patterns are ordered in groups of 32 (0x20) bytes, correct? So this index number, for it to start at the beginning of an 8x8 pattern, should be divisible evenly by 0x20, but it's not. The size of EHZ/HTZ's patterns is 0x2980. Multiplying 0x38C by 0x20 yields 0x7180, which exceeds that limit, so we can't use it that way either - the file would go out of bounds.

According to Saxman, the position in VRAM shouldn't be any different from in the ROM, so if this is to be correct, I'm obviously doing something wrong with these numbers, and I need to know what it is.

4. ### shobiz

Tech Member
Yeah, you have to multiply the \$38C by \$20, not divide it. The tile index can refer to any tile in VRAM, it doesn't necessarily have to refer to a level 8x8 tile (though it usually does), and I'm guessing that's the case here - try looking at the next few 16x16s and see what tiles they refer to.

5. ### AeroGP

Member
130
1
18
Los Angeles, CA
Sonic for GameMaker: Studio
Does that mean that all the 8x8 patterns should be placed in one file? If so, what order should they go in?

6. ### shobiz

Tech Member
Nope, the game loads everything into VRAM itself. The simplest way to see which tile is at \$7180 is using Kmod's VRAM viewer - IIRC the address display in the viewer actually displays the tile index rather than the tile address, so it's quite easy to see which tile is at index \$38C.

7. ### Upthorn

TAS Tech Member
239
0
0
As the guide says, the 0x38C is the address after it has been divided by 0x20.
Multiplying by 0x20 you get 0x7180, correctly. The thing you have done wrong here is that you aren't accounting for the fact that the EHZ tile patterns are compressed in the rom and are decompressed in VRAM. If you open sonic 2 in gens, start emerald hill, and look at the VDP in the debug menu, you'll see EHZ patterns go all the way fro 0x0000 to at least 0x7800. Which means that 0x38C -> 0x7180 is well within the EHZ block art boundaries.

8. ### FraGag

Tech Member
Another thing you did wrong is that you didn't decompress the actual mappings; they are Kosinski-compressed.
<!--g1--><div class='geshitop'>Syntax Highlighted Code: ASM</div><div class='codemain'><!--eg1--><pre class="asm">[color= #adadad; font-style: italic;]; EHZ 16x16 block mappings (Kosinski compression) ; was: (Kozinski compression)[/color]
BM16_EHZ: BINCLUDE [color= #CC33CC;]"mappings/16x16/EHZ.bin"[/color]</pre><!--gc2--><!--OyBFSFogMTZ4MTYgYmxvY2sgbWFwcGluZ3MgKEtvc2luc2tpIGNvbXByZXNzaW9uKSA7IHdhczogKEtv
emluc2tpIGNvbXByZXNzaW9uKQpCTTE2X0VIWjoJQklOQ0xVREUJJnF1b3Q7bWFwcGluZ3MvMTZ4MTYvR
UhaLmJpbiZxdW90Ow==--><!--egc2--><!--g2--></div><!--eg2-->
You'll see that the first block is 40 00, so the address of the first tile is at 0x0 (and uses the third palette line).

9. ### AeroGP

Member
130
1
18
Los Angeles, CA
Sonic for GameMaker: Studio
So, even after being disassembled, they're still compressed?

Is there a way to decompress them externally? Or is the original asm the only means to translate the files?

10. ### FraGag

Tech Member
You can use The Sega Data Compressor (get it from the Sonic Hacking Utilities page). You can use it to manually compress and decompress files using Kosinski, Nemesis, Enigma or Saxman compression. If you're decompressing data from a split file, use 0 as the offset. If you've edited the uncompressed data, don't forget to re-compress it before building the ROM.

11. ### AeroGP

Member
130
1
18
Los Angeles, CA
Sonic for GameMaker: Studio

One more question: I tried to apply these principles to the 128x128 tiles, but it doesn't seem to work. Are they already uncompressed? Do I still multiply \$20? What could I be forgetting this time? -_-;

12. ### FraGag

Tech Member
If you had bothered to look at the comments in the disassembly, you'd have seen that those mappings are also compressed. However, I believe they use a different format, as they reference 16x16 blocks.

13. ### shobiz

Tech Member
They're also compressed in the Kosinski format, and the format is described at Block_mappings#Format_2

14. ### AeroGP

Member
130
1
18
Los Angeles, CA
Sonic for GameMaker: Studio
SSTT YXII IIII IIII

Same situation as last time. I.E: EHZ's 16x16 are size \$FA0 uncompressed. Multiplying the index I by \$20 would exceed the file boundaries. Multiplying by \$8 is too large, as well. Any other number would be an incorrect offset. What did I do wrong here?

15. ### shobiz

Tech Member
You don't have to multiply at all, the II IIII IIII is just the 16x16 number. 0 means the 1st 16x16, 1 means the 2nd 16x16, and so on and so forth

EDIT: Might've misread the above post a bit - if you want to get the position of the 16x16 inside the block table, you'd multiply by 8, since one 16x16 occupies 8 bytes. Shouldn't cross the file boundaries - you decompressed the 16x16s and 128x128s right?

16. ### AeroGP

Member
130
1
18
Los Angeles, CA
Sonic for GameMaker: Studio
Yes, they're decompressed, and it does cross the boundary.

I.E: It crashes upon reaching this number at offset \$100: 02 FC.

02FC * 8 = 17E0 > FA0 (16x16 boundary)

What should I do?

17. ### shobiz

Tech Member
Thing is, the 16x16 mappings of each level are decompressed into RAM, and it's this RAM area that's accessed throughout the game. Now, the block table in RAM occupies \$1A00 bytes (from \$9000 to \$AA00), so it can hold a maximum of \$340 16x16s. The extra 16x16s are dynamically loaded into RAM - each level has an entry in the offset table known as AnimPatMaps in Xeno's disasm, and the routine at loc_402FA loads these extra 16x16s into RAM.