#metconst @ irc.esper.net
-> Documents -> Room expansion (part 1)
This is the first how-to I've written for anything hack-related, so forgive me if it's a little rough around the edges. I'll find my knack along the way. Let's do the thang.
- Lunar Address
What you'll be doing/learning by following this guide (hopefully)
- Identifying rooms by their ID and the amount of level data that they have
- Expanding your ROM to use new banks of free space
- Using a hex editor to analyze bank offsets (no hex actual editing will be done)
- Converting bank offsets to level data pointers with Lunar Address
- Changing level data pointers and effectively controlling any room's data allowance
If you're not familiar with hex, use HxD so this walkthrough is easier to... walk through. I use SMILE 2.0, so I can't guarantee the steps will be exactly the same if you have a different version, but it shouldn't be hard to figure out. If your Super Metroid ROM has a header, REMOVE IT (in SMILE: click "Tools" > "Header" > "Remove Header"), otherwise the values in this guide will be off. Taking away the header will not damage your ROM.
What is room data and what is the advantage of expanding?
Room data, or tile data is the allotted space each room has. It varies depending on the size of the room, and for a lot of people there's plenty of space to work with by default. For others who put a lot of detail into level design, size limits can become a problem. Expanding and learning to choose how much space a room has allows for a lot more creative control.
Note the room ID, and the room sizes reference. The room pictured above would be "793AA - 462"
What if we want to make the room bigger or just give it a lot of pretty detail? 462 isn't much space to work with at all. TIME TO FIX THAT.
To make it easier, we're going to set aside a whole bank for room data. If you don't know about banks, don't worry, you can still make it through this. All you need to know right now is that SMILE is capable adding new banks to the ROM. These banks are free space for you to do whatever you want with. Okay, great. Here's a run-down of the process.
1. In SMILE, open the room ID you want more data for. I'm gonna use 793AA in this example. You should too if this is your first time ever touching hex.
2. Click "File" > "Save Room" - this causes the [## / ##] to display like in the picture above.
3. Click "Tools" > "Expand ROM" > "Yes"
4. Pay attention to what bank SMILE tells you that it just added. If it's your first time expanding, it will be '$E0' and from there it continues to $E1, $E2, $E3, etc., all the way up to $FF. That's 32 banks total. To give some perspective, 1 bank = about 32000 room data. 32 banks = about 1024000 room data.
5. In this case, we'll be using bank $E0 for our room data. Open HxD and load your ROM in it.
6. Click "Search" > "GOTO" > type in the offset "300000" (make sure the "hex" and "begin" buttons are checked) > "OK"
Observe that "00300000" is the beginning of bank $E0.
To save some time and energy, I threw together a quick reference with the offsets for banks $E0-$FF and the level data pointer for each. You're welcome.
7. Open "level_entries.txt" in smile\files and scroll to the very bottom.
8. Add the values "300000" and "308000" to the very bottom of level_entries.txt so it looks like this:
9. Open Lunar Address and enter "300000" into the "PC File Address" box. Make sure the "LoROM - PC 80:8000 - FF:FFFF" circle is checked. The "SNES LoROM" box should then tell you "$E0:8000" (your new level data pointer) like in the image below. Uncheck the "Format Results" box if you want it display as "E08000" instead.
I know this doesn't seem related to expanding rooms, but I promise there is a point to all of this. Just wait.
10. Open SMILE back up and save the changes you made to level_entries.txt now. Click "Edit" > "Pointers" and replace whatever is already in the 'Level Data' field with E08000 like so:
11. Next, click "Save Pointers" > Save and Re-Open? "OK" > What do we have here?
Can I get a hell yeah?
12. If you did every step right, your tile data allowance should jump to a delicious 32000. That's wonderful and all, but keep in mind that your room is now pointing to all of bank $E0's data at once. The two values, 300000-308000 that you entered in level_entries.txt were the start-end points of bank $E0. Unless you plan on making it an insanely huge room by adding doors and/or repointing scroll data, it's unlikely you'll ever go over 10,000 for a single one.
By making more conversions with Lunar Address and learning to recognize the level data in hex, you can easily distribute bank $E0 throughout many rooms. Take a look at this:
Observe the "00300000" again - but something's different...
Let's take a closer look at some things about the screenshot above. See all of those garbled letters and numbers inside the green square? If you'll remember in this image, there was originally nothing but a bunch of FF FFs surrounding 00300000. If the picture didn't make it obvious enough, the added randomness is the 353 bytes that room 793AA is currently using, which you directed right to offset 300000 by entering E08000 in SMILE's pointer window and saving. Oh, cool, everything is tying together now. I hope? If it helps any, count the rows/lines inside the green square and multiply both numbers(16 rows long, 22 lines tall; 16x22 = 352).
Now, about those values I told you to pay attention to. The numbers themselves aren't important. I'm pointing them out to emphasize what lines are. "Is he seriously telling us what LINES are?" Yes I am. I know this is a given for most who will read this, but I'm trying to be as noob-friendly as possible here.
Line 1: 00300140
Line 2: 00300150
Line 3: 00300160
Line 4: 00300170
4 lines tall. Got it? Good. So when I tell you to "skip 10 lines" you should know exactly what I'm talking about now. Let's continue.
13. Build your room in SMILE. Make it awesome. Once you're happy with what you have, save the room and write down the amount of tile data being used. After slathering random graphics all over layers 1 and 2 for the sake of example, I wound up with [1686 / 32768]. Naturally, data usage will vary widely from person to person and room to room.
14. Back to HxD. "Search" > "GOTO" > Offset "300000" > Oh, wow. The random characters have multipled ever so swiftly!
Yes, hundreds of lines.
15. Do as the picture commands and scroll down. Keep scrolling. Keeeeep scrolling. Or hit the Page Down key. Whatever works. Stop right where the data goes from being letters and numbers to FF FF only (shown in the red below):
Notice the 5 lines between red and green
The highlighted red lines are where room 793AA's level data ends. The highlighted green line is where the next repointed room's level data will start going. I only left 5 lines of free space between the red and green because I won't be making any more changes to 793AA. You'll probably want to skip more than 5. 20 works.
My room 793AA is taking up 1686 / 32768 tile data right now. That 1686 is approximately 106 lines in the hex editor. If you wanted 793AA to be left with somewhere around 1686 / 2000 after repointing again, you would skip about 20 lines between the red and green.
16. Back to that highlighted green line. See the offset for it? "00300700"
Bring up Lunar Address again. In the "PC File Address" box, type in 300700. The result that appears in the "SNES LoROM" box should be $E0:8700. There you have it. You're set up to expand another room. All you have to do now is replace another level data pointer with E08700. Let's go do that right now, just to refresh our memory.
17. Open room ID 79A44
18. It's time to add another level_entries.txt entry. Can you guess what we're putting in this time?! Since the offsets 300000-308000 are the beginning-end points for bank $E0, we will be putting our new level data pointers between them. The end of your level_entries.txt file should now look like this:
19. Save level_entries.txt and return to SMILE.
Click "Edit" > "Pointers" and replace the 'Level Data' value (C4811E) with our new value, E08700.
Click "Save Pointers" > Save and Re-Open? "OK"
How 'bout that? It isn't 32000 this time. That tells us that the bank's space is being distributed properly. Now take a quick glance back in HxD at our 300700 offset. Just like offset 300000, the FF FF that surrounded it has been replaced by miscellaneous numbers and letters. Sweet:
Yes. Hundreds of lines again. Possibly.
20. Seeing the pattern yet? Now we're back to the "Build a room and make it awesome" phase. After you build an awesome room and are ready to repoint again, go to offset 307000. Scroll down until the ## ##s turns into FF FFs, skip however many lines you want, look at the blue 00###### offset for the line you choose, punch it into Lunar Address, grab your pointer from the "SNES LoROM" box and enter that as any room's new 'Level Data' pointer. Lather, rinse, repeat. Get all of that down, and room size will never be an issue again.
That's it for part 1 of this expansive expansion extravaganza. Let's go on to part 2.