The room header is a long string of hex values which contains all of the data required for rooms to be displayed and function properly within the game and, likewise, SMILE. This page will aim to show you how the data is structured and how to make additional pointers and room headers (though in a less direct manner). You'll need some basic understanding of how to use a hex editor and remember that any and all addresses in this document will be in an unheadered ROM. Also of note, I will also be using SMILE 2.5 while writing this.
First off, let's look at a room in SMILE which has a single state: room ID 793FE (the big open ocean room outside west of the Wrecked Ship). Opening your hex editor and going to that location (793FE) you should see the following:
05 00 26 00 08 06 90 A0 00 25 94 E6 E5 45 EB C2 00 0C 05 12 81 84 86 61 81 81 01 31 94 00 00 1B C1 DC 81 AE B7 CE 91
Now, this is a large sized room and all that may look like gibberish, but don't get discouraged. Let's break it down byte-by-byte before any assumptions are made.
05 - Room index 00 - Room area 26 - X-position on mini-map 00 - y-position on mini-map 08 - width of room 06 - Height of room 90 - Up scroller A0 - Down scroller 00 - Special graphics bitflag 25 94 - Door out pointer E6 E5 - Roomstate used 45 EB C2 - Level data pointer 00 - Tileset used 0C - Music: Collection 05 - Music: Play 12 81 - FX1 pointer 84 86 - Enemy Pop/Allowed pointer 61 81 - Enemy Set pointer 81 01 - Layer 2 scrolling 31 94 - Scroll pointer 00 00 - Unknown/RoomVar 1B C1 - FX2 pointer DC 81 - PLM pointer AE B7 - BG_Data CE 91 - Later1_2 (FX0/Setup code)
This first 9 bytes (05 00 26 00 08 06 90 A0 00) are known as the room's properties and can be edited in SMILE 2.5 by going to “Edit > Room Properties.” E6 E5 tells the game which data to use for what roomstate. In our current example, this room only has one state and that's what we'll work with for now (I'll get to multi-state rooms later). The “tileset used, Music: Collection,” and “Music: Play” can all be edited directly in the main SMILE window off to the right under the “Other” tab (also located under where you'd select rooms). “Layers 2 Scrolling” is editable in Tools > Background Editor > BG Layer 2/SCROLLING. Everything else is editable via the pointers window (Edit > Pointers).
Room properties define the physical characteristics of a room. Their area sub-map, width and height, and location on the mini-map are the major values that typically get edited. Additional, less impactful values are the up and down scroller, room index, and special graphics bitflag. *All* of these specific values can be edited in the Room Properties menu in SMILE rather than having to change them in hex.
05 - Room index 00 - Room area 26 - X-position on mini-map 00 - y-position on mini-map 08 - width of room 06 - Height of room 90 - Up scroller A0 - Down scroller 00 - Special graphics bitflag
This is simply the number a room is given inside the game and and doesn't have any major effect on the room itself. Think “Crateria room #1, Crateria room #2, Crateria room #3, etc.” However, certain numbers in certain areas can have an affect on the footstep effects for the room (like the splashes Samus leaves when walking above water in specific rooms).
Tells the game which sub-map/area the room is to be located in. This determines various FX that can be used in the room depending on the area such as the heat bit (which causes heat damage without Varia Suit) only being able to be set in Norfair and Tourian (where it is unused by default). A list of values pertaining to each area are found below.
00 - CRATERIA 01 - BRINSTAR 02 - NORFAIR 03 - WRECKED SHIP 04 - MARIDIA 05 - TOURIAN 06 - CERES 07 - DEBUG
The x-position and y-position of the room's boundaries as displayed on the mini-map. Due to the way the mini-map works, the top row you see in SMILE's map editor is not recorded as the topmost row. The row below is however. Our example room is located at the coordinates “26,0” on the mini-map.
These values work similar to the Cartesian grid except that the y direction is reversed. So -01 in Cartesian would be 01. If this is all too confusing, there is the much simpler method of using SMILE's map editor to alter the position of your room on the mini-map. Width and Height of the room
This is exactly what it says on the label. Room widths and heights are measured in screens which are measured as a 16×16 block of tiles. Viewing of screen sizes in the level editor can be achieved by going to “View > Options > Show Scroll Areas.” The catch here is that due to the way programming works, a one-screen by one-screen (1×1) room would be 00×00 in size. For a quick explanation, numbering with programming starts at “00” for “1.” then “01” for “2,” and so on and so forth.
There are two limitations here however! A room cannot have a total area of more then 50 screens (area = width x height) and neither dimension can be expanded beyond “0F” (16) screens in size (but remember “0F” is actually “15” in hex, yet we have to count “00” as “1” in this case). This means a room of 16×3 (0F,03) is acceptable while something like 16×4 is not. For reference, the largest possible room in Super Metroid (and the largest the engine can handle) can be found as room 79D19.
To be completely honest, I'm unsure exactly what these do. I recall hearing that they have a very, very minute affect on the camera while moving through a room. You will be able to get by just fine without editing them or even setting them to 00,00.
The “special graphics bitflag” handles specific cases where parts of the CRE (Common Room Elements) are to be overwritten or refreshed/reloaded due to additional graphics being loaded. By clicking on the box next to it's input field in SMILE, you'll get a list of values that are common. Listed below are any special cases for each value along with a description.
00 - most common value used in the vast majority of rooms. 01 - used in Crocomire's and Draygon's rooms to unload CRE. Presumably to make room for their graphics in the CRE. 02 - forces a refresh of the CRE. Used outside of Crocomire room. 05 - used in Ceres elevator, Ceres Ridley's, and Kraid's rooms.
The tileset defines the set of graphics the current room will be built with and is selectable on the right side of the main SMILE window via a drop-down box with selections between 1 and 29. For a list of tilesets, refer to this page. Likewise, music determines what song to play in the room and is also selectable on the right side of the main SMILE window, though under the “Other” tab. You can find a full list of music selections over here. Both tilesets and music selections are chosen per room being unique to it's room header, not shared between them (unlike pointers which can be).
These two bytes of information give the game important information about the room's background. This can be viewed by going into the Layer 2 scrolling window in SMILE 2.5 by going to “Tools > Background Editor > BG/Layer2 SCROLLING.” These affect what kind of background to use and how it “follows” the camera while the player moves around the room. It a bit hard to explain, and the room we've picked apart isn't a good example of this at all (since the scrolling sky is something else on its own), so you're best off to find another room a play with values there.
81 01
The first byte is for the y-axis scrolling and the second is for the x-axis scrolling. Each byte ending with a 1 tells the game to use the BG_Data pointer in the pointers window. If there room were set to use a “Layer 2 background (Custom),” the bytes would end in 0, thus making our current example look like 80 00. Again, I suggest playing around in another room other than 791F8, 793FE, and 7968F (as all of these use the scrolling sky) to see the true effect.
Pointers point to specific locations in the game where data is stored. A good handful of these are vital to a room's function and as such, they will also be broken down and explained in their appropriate sections below.
This is the almighty important pointer. As the name suggests, this is the data for the level, or room. This contains the layout of tiles on both layer 1 and 2 and the block properties of every tile within the room. While you could write all the data of one of these pointers out in hex, it's highly, highly unrecommended. Not only does this tend to be an extremely large chunk of data, it is also compressed to reduce its size.
Level data pointers can be located anywhere in the ROM so long as there is enough free space. Typical practice is to expand the ROM into bank $E0 (PC address 300000-307FFF) and beyond. After that's done, one must go into the “level_entries.txt” file (located in the “files” folder where SMILE is installed), go down to the bottom, and place the beginning and end address of the free space.
If we wanted to reserve (or maybe even use!) all of bank $E0 for level data, we'd put the following at the bottom of level_entries.txt:
300000 307FFF
From there, we could put E00000 into the top box of the pointers window and start using the new space to build rooms! Once the room is finished however, you'll need to take a peak into a hex editor to find out where free space ends, note that address, and add it between the previous two entries we've made in level_entries.txt to tell SMILE when to stop reading level data.
This is just a quick overview of how level data works and how it can be expanded on. For much more in-depth and hands on explanation, go read the room expansion guide.
Work in progress, more to be written. ~person701