I'm currently working on a tool to automatically rearrange level space in a YI ROM. I'm kind of stuck at the moment, since I'm thinking about a good algorithm to re-insert the levels. Another problem is, that Golden Egg does not leave fields of FF-bytes when relocating level data, but fields of 00-bytes, which is very inconvenient for me.
Sadly, I'm incapable of programming an editor for the game, which has better features (especially visualisations) than Golden Egg, my understanding of the ROM's inner working is too low...
However, the new tool will hopefully give you satisfactory results; I will also implement a feature to extract level data and a feature to select a folder full of extracted levels, which are then inserted into a chosen ROM.
Okay, but here is how you do it by hand:
1. Pick a
level you wish to insert and the
type of data you want to insert (
objects or
sprites); for the example I will use the
sprites of level
0x7A.
2. Find out the space consumed by the
new data. So you simply check the
file size of the extracted
RAW Level Data, which
equals that size. Note it down.
3. Find the pointer to the level data in the ROM. First, find the pointer.
For
object data, you calculate (
0xBF9C3 + 6 * <LEVEL>).
For
sprite data, you calculate (
0xBF9C6 + 6 * <LEVEL>).
Once you found the pointer offset, note it down. For the example, the pointer offset is (0xBF9C6 + 6 * 0x7A = 0xBFCA2).
Jump to that offset.
There are three bytes there.
In the example, these are [5E BC 14].
4. Find the level data.
It's best to use
LunarAddress to find out where the pointer points to.
You read the
bytes backwards, so [5E BC 14] becomes [14 BC 5E] and give it to
LunarAddress.
It spits out 0xA3E5E.
Jump to that offset.
5. Now you want to find out how
many bytes are consumed by the level data, so you can
turn it into free space/overwrite it.
The best thing is to open the level in
EggVine.
Opening level 0x7A gives us 195 bytes of
maximum usable (<== which is the important number)
Sprite Data.
Note that number down, you might need it now.
6. Now we turn that into free space or overwrite it.
Compare the sizes of your
old level data and the
new level data*.
If the
new level data is
smaller or equal the
old data, you
overwrite the old data (STEP 7A).
If the
new level data is
greater than the
old data, you have to
look for a new spot (STEP 7B).
*IMPORTANT: EggVine does not calculate the
level header for
Object Data nor the
ending FF-bytes for
both Data Types, so for
objects add 12, for
sprites add 2!!!
7A. Simply
copy the
entire new level data and
insert it into the ROM, beginning
from the original location of the data (in the example, if the new Sprite Data is smaller or equals 197 bytes, I paste it beginning from offset 0xA3E5E).
Afterwards, if the
new data is smaller than the original data,
insert FF-bytes where old data was (in the example, I have 7A.spr, which is 155 bytes. I insert it from 0xA3E5E and insert the remaining 42 FF-bytes after the new data).
7B. Go back to the offset of the data (0xA3E5E in the example) and insert 195+2 FF-bytes from there (in
Translhextion you can simply paste one byte multiple times).
You can
reload the level in EggVine. If there are now
0/0 usable bytes, it was most likely successful.
Now, that you have
erased the
old level data and got yourself some
free space, which may be used again by something later, it's time to
look for some space the new level data fits into, so you look for a
bunch of FF-bytes in the ROM (in the example, 7A.spr is 278 bytes, which fits into the space beginning from 0x11554A).
Once you have found a good place,
copy the
entire content of your
RAW Level Data and paste it into the ROM.
Note down the
start location of where you pasted it (in the example, the sprite data of level 0x7A has been pasted beginning from 0x11554A).
The
level data is now
INSIDE the ROM, however, the
game cannot access it yet.
Now you give
LunarAddress that start address where it says
PC, and it will
convert it back into
SNES LoROM format (in the example, 0x11554A becomes 0x22D34A).
Jump back to where the pointer to the data was (in the example, that is 0xBFCA2). Reverse what
LunarAddress gave you and
overwrite the existing pointer with that (in the example 0x22D34A becomes [4A D3 22]). Now, save the ROM. You can check the level in the editor of your choice now.
About your second question, I think Golden Egg just leaves the data AFTER the graphics untouched. The data before the graphics (usually 0x11554A-0x1201FF) cannot be overwritten unless someone dumb tries to mess with YCompress. Also, for inserting in YCompress, using 11 instead of 1 in the command line will not overwrite other existing data after the graphics (except if the compressed size has increased).
Also, be careful with YILEX. Always double-check the file size and the size of the level data in the REAL ROM. I cannot guarantee that it's flawless.
Aside from that, if the tutorial hasn't been clear enough tell me where you have problems.
NEW! SMW2 Yoshi's Island is done!
Last update: 2012-12-31