Well, once again I'm back to posting about interactions. Before I go on though, if you care, warps are now editable instead of just viewable. But anyway, I've been debugging stuff and trying to get more information on interactions. Many of my findings include that the "enemy spawn group" ID is actually a memory pointer (Bank 0x12) to more spawns. Opcode 7 isn't for tree seeds, but it's some sort of trigger that tells the game not to respawn the interactions the instant you walk into a room (A guess, however highly correct. If tree seeds and enemies both use it, obviously you know that they both don't respawn the instant you walk into a room. This is what I'm going to call it from now on).
I've also discovered a script editor shouldn't be needed for dungeons. There are already interactions that contain things such as "Open this hatch when there aren't any enemies". For example, a 02 interaction with the ID of 0xB1E would open up a right-pointed door once all enemies are defeated (Such as the one right of the first room in Level 1).
Warning: The following is very long and was written as I was debugging. Scroll down until you see more bold text to see something useful.
This next finding might not be right. However, I believe the script pointer for 02 interactions is calculated by taking the first byte (The lower byte of the 'ID'), multiplying it by 2, adding it to 0x3B8B, and calculating the pointer there using the set bank (See further for how this is calculated.).
Calculating Script Bank [C# Syntax]:
byte value = (byte)(id & 0xFF);
if (value < 0x3E) bank = 0x08;
else if (value < 0x67) bank = 0x09;
else if (value < 0x97) bank = 0x0A;
else if (value < 0xDC) bank = 0x0B;
else bank = 0x10;
The resulting address directly points to an ASM procedure, or script in our case. After thinking a bit, the game might not have its own script engine (Very possible. For example, the script can just load a pointer for a text pointer and then call another ASM procedure. Its own scripting language wouldn't help much. If I remember correctly, Pokemon Red used all ASM and CBM still did a great job with Brown). The parenthetical point I was trying to get at is you can think of it as a scripting language, but really it's most likely ASM with arguments (Heh... Aren't all scripting engines like that? What I mean is there probably isn't ASM that has script opcodes and works from there, like in Pokemon GSC).
[An hour later]
I've been able to get filled in even more. In the room to the right of the first room in Level 1 (I'll be talking about this room from now one), there is an object positioned in the top left that controls where and when to open the north door. Now, let's walk through the script calculated from the IDs (Or, script reference I guess).
The ID is 0x81E. 0x1E means a 0x08 bank, and after the pointer calculating is done, we're left off at 0x0206E4. 0x1E is commonly used and found in rooms with opening doors. But anyway, at that address is an ASM script calling 0x0026EC. I'm not exactly sure what this does, other than checks the first byte in the interaction's data. 01 is normal and 02 resets a sprite by setting 64 bytes starting at its base to 00.
So after that calling, another procedure is called at 0x0026E4. This procedure starts by checking what's at 0xCD00. This value is set according to the room scrolling going on. Bit 3 (0-based) is set if you're going room-to-room, bit 0 is set if the room transition is complete, and bit 7 is set if the room is scrolling regularly.
Back to the 0x26E4, the procedure checks if the room transition is complete or not, and if not, then return (This is why doors don't open if we've killed all enemies until we've finished going from room-to-room). The rest of the procedure isn't really important as long as we know that, so let's move on.
Truthfully I'm not sure what is at 0xCCDD, as it's always been 00 and I haven't been able to find a command that writes something other than constant 00, so let's ignore it for now. After the 02 check, the next lines check the value at 0x**44 (** being the current interaction), which from my understanding controls whether or not the interaction is enabled. The accumulator is set and a past version of the script is recalled and some other stuff is added (You can learn more about this by checking out the script at 0x000000).
Now we're at 0x0206FC. 01 is placed at 0x**44. The Y position of the interaction, or as it's used here, the Y location of the door to open, is copied over to 0x**7F. The same thing is done to the interaction's X position, except copied over to 0x**7E. After this, the absolute X is calculated (It's just the X <<>= 0x80, it continues on. If not, it returns. Upcoming is a check at 0x**46. If the value there is 00, the script continues at 0x002567. If not, the value at 0x**46 decreases by 1 and the procedure returns.
At 0x002567, the value at 0x**47 is read. If 00, the script continues at 0x002573. If not, the value is decreased and if not 00, procedure 0x00201D is called. The accumulator is then reset and the procedure returns.
Once again continuing (Gosh this is getting REALLY annoying, but I see a for-sure-to-reach return!) at 0x002573, the game reloads are second calculated script pointer (0x0206FE) and calls procedure 0x002518.
Here we find out that script pointer is really at 0x306FE, because of a bank switch from 0x08 to 0x0C. If the value there is not 00, we call the procedure at 0x30000.
OKAY! I've honestly had enough of that. The deep down ASM that we're never going to touch is unimportant.
Something Useful
So, for events like doors to work, The first byte of the type 02 interaction must be 0x1E. The other byte has to do with bit work. Bit 0 and 1 are the door direction (00 being down, etc). Bit 2 is a flag that's used for events (What kind, I'm not sure, but the room with the cube in Level 1 has it set), and bit 3 is set for when doors open when all enemies are killed (Or a block is pushed if there are no enemies). I have not messed with the other 4 bits yet though.
A Custom Door and Event
Here is something I tried in a test. It brings in three Stalfos, adds a new door to the bottom that automatically closes and opens up when you kill the enemies. It also proves the click-and-set editing feature and shows off the warp editor.
Watch the video: http://www.youtube.com/watch?v=8RNQkZ8HV1E
That's all for today's extremely long and boring post, but hey, I found out a lot and now hacking can be made even better. Until next time, see ya later!
Subscribe to:
Post Comments (Atom)
Nice work.
ReplyDelete