News:

Don't forget to visit the main site! There's lots of helpful docs, patches, and more!

Main Menu

[SM] Where does the doors array end?

Started by Dahtamnay, June 30, 2017, 10:58:06 AM

Previous topic - Next topic

Dahtamnay

Recently I've taken a more serious interest in hacking Super Metroid. Thus in order to learn more about the ROM layout, I decided to write some code to read out data, and automatically repoint stuff too. There's one detail that has been bugging me for a while now.

The Smile RF Guide (the one by begrimed) says that the doors array for a room needs to end with 00 00. However, checking the SM ROM, I find for pretty much every room that these terminating bytes are absent. That makes me wonder: why does the guide claim the zero bytes are required, and how does SM detect the end of the array?

I can think of a few possible answers here:

1: The game does not need to detect the end of the array. It only accesses the array at specific hard coded indices, which never exceed the size of the array. The recommendation from the guide is there only to make the data more human readable.

2: The array can be terminated with any set of two bytes that combine to a value less that $8000. Since this would not be a valid LoROM pointer, the game knows the array has ended. Coincidentally, the first two bytes of the subsequent data in the ROM are always small enough to act as terminating bytes for the array (usually this is the scroll data for the room, which indeed only contain small values).

3: The number of doors in a room can be inferred elsewhere. Perhaps in the compressed level data, which I have not yet looked into.

As an aside, I am also curious how Smile handles this. Smile is able to read the correct number of doors for each room, so how does it accomplish that?
I hope anyone who knows more about the inner workings of SM can help me out.


PS: where can I submit any errors that I find in the Smile guide or other documentation on the site?

P.JBoy

Answer 1 is correct. When you hit a door transition tile, its BTS is used to index the DoorOut data directly from the ROM, there's no size or terminator; if you go out of bounds, you can trigger a door transition tile with BTS that will overflow the sane door definitions. They way that SMILE determines the number of doors will be by checking every block in the level data. In fact, you can check this by adding a door tile with a BTS of N, then you should see N (garbage) doors listed in the door editor
...

Dahtamnay

Ah, that is clear then. Thank you for your quick answer! For now I think I'll just keep track of the door count for each room in an external file starting from a clean ROM.

Scyzer

#3
P.JBoy is correct about the game. It will just use the Door's BTS as an index and grab a pointer accordingly, even if that pointer leads to garbage.

However, SMILE RF (and other versions too probably) compile the list of available doors in a room by checking for a value less than $8000, and then stops, even if a Door's BTS is higher than the compiled list. SMILE RF in particular will not allow editing of a Door BTS that is out of bounds of the compiled list. This means if you want to add extra doors in RF, you must add new pointers in with a hex editor first. Other versions of SMILE will probably try to get data for invalid doors which might crash the program.

In short: Answer 1 for game. Answer 2 for SMILE.

If you're up to the challenge of repointing, a very good system for doors that I use is to list every door together in one huge chunk, rather than splitting each room's doors individually after each room. This means that a lot of rooms will use the same Door Pointer, but the BTS of each door just keeps counting up. It's much easier to keep track of data that way, and saves a lot of space by reducing unnecessary terminator bytes for SMILE.
For EG, in Seraphim, I have each pointer for all 937 doors all together at $8F:8000. The first 50 or so rooms then have a Door Pointer of $8000, with the doors of each room continuing to count up. Room 1 will use Doors $00 to $03, then Room 2 is $04 to $06, etc. The result is well worth the effort, as adding or removing doors later becomes a simple matter of using an unused BTS, rather than having to repoint the Door Pointer and add another door entry in for that room which then leaves random unused bytes after the room header.

If you find any errors with the guide, you can message @begrimed on the forums about them, or alternatively if you use RF, use the Bug Report / Feedback tool to send me a message, and I'll be able to let Grime know for when he next updates the guide (hopefully somewhat soon because the RF build the guide was based on is soooo out of date).

Dahtamnay

Interesting to see that SMILE RF uses answer 2 to tally up the rooms. That's how I did it in the first place too, and it seemed to work fine. Grouping all doors together is a neat idea too. But if I can get my code to work, I won't have to think at all about where in ROM the data is stored. For now I won't worry too much about smile compatibility.

Anyway, thanks for the info, I'm well on my way understanding the ROM, and this knowledge certainly helps to make some programming decisions.