Wednesday, June 16, 2010

New Features and a To-Do List

Alright! I know I've missed the last couple days, but I'm here to make it up. For starts, let me announce that ZOLE is nearing it's end (Hold on!). However, ZOLE is only the level editor I'm going to be making for the game. I'm looking into making another tool that you probably won't hear anything about for a while as I haven't done any research on yet. But before that, here's a list of what needs to be done before anyone should get excited (It may seem like a lot but some of the things aren't really that much to make).

-Minimap editor - I need to find the data for this.
-Gale seed spot editor - Already found the data.
-Dungeon room order editor - Already found the data, but I want to integrate it into the minimap editor.
-Graphics/tileset decompressor + repointer - This will require a small ASM hack. Not all tilesets will be able to be decompressed, as it will require over 1MB of space, so it's a choice.
-Text editor - I have no idea how text works. The text probably uses dictionary compression as around 0x60000 I believe you can find random words used in the same each starting (or ending?) with 00. Note this may not be added as it could use a totally different system than I'm thinking of.
-Dungeon name editor - Might have a little trouble with this. I've done a slim search and found nothing before.
-Dungeon portal editor - I know this gets grouped with interactions, but many people won't want to have to know ASM to edit half the simple things in the game.
-Small indoor exit warp editor - I know I said I was just going to include a tutorial, but a separate editor would just be easier for all of us.
-Full Seasons compatibility - This will not be added before the first release.

So that's the checklist. Now, I've added two things today. First thing, a palette editor. It allows the selection of any palette and then a preview of what the selected area would look like with it applied (Oh how this is useful). Here's what it looks like.



Ugh, what an ugly palette, but hey, it's just a demonstration. Right now, it only edits basically "uncompressed" palettes, which is every single palette used in tilesets except for 1 (It can still be edited just fine though). I don't want to explain what I mean by "uncompressed" so just read on.

The next thing I added is small but useful, a start editor. It really doesn't need a screenshot as it's a few labels and numeric boxes so I won't post one.

But that's all. Oh, and a heads up: I'm going to be making a forum specifically for Zelda hacking, since there doesn't seem to be one (Maybe just for the Oracles games, since I don't know half the Zelda games that are even out there nowadays). But until (hopefully!) tomorrow, see ya later!

Sunday, June 13, 2010

No Real News

Well, there isn't really any news today. I've been messing around with a program I'm making that lets two people play a game together (Like watching someone play a VBA game and then taking over by capturing the screen's buffer and sending it over and some other stuff). I've also been playing around with the editor recreating Zelda Link's Awakening's maps (Which is actually pretty fun) and I noticed that I have to figure more out about interactions, because I can't seem to get the ID for those little green blobs that pop out.

Oh well. Until tomorrow, see ya later!

Saturday, June 12, 2010

One Down, X To Go!

A strange title, but the point I was getting at is another feature down and only so many more to go. The feature I'm talking about is the Chest Editor. Here's what it looks like.



A small, yet powerful window. You're probably thinking, "Oh my gosh, 65536 possible chest items?! How am I supposed to know what's what?!" Well, obviously you just find a map with the chest item you're looking for, swap data (or just copy the ID) and you're good.

But anyway, I've been thinking. Should I have a dungeon room order editor? In my opinion, this is extremely useless as all of the data is raw and will never be used by another room. I doubt anyone would find any use of it, so I'm thinking against it, but I want to get opinions first (This is not like ZLADE/ZLA where the maps are compressed and certain data is used over and over again).

So that's all for today's short post. Other than this I've been fixing bugs and messing around with debugging. Until tomorrow, bye!

Friday, June 11, 2010

More Data Findings, Map Scripts, and a New Feature

Well, I haven't worked on the editor today except for warp saving fixes, but I have found quite a few pieces of data.

For starts, let me introduce a new feature, patching. Basically, the editor will have a menu with categories of patches and things to add or remove. This is to basically decrease the knowledge needed to remove some of the annoying things that would kill hacking. Most of these patches (all so far) just change one byte. There will be no way to revert them back to normal.

So far, patching includes removing the random forest maps (That annoying game) and all possibilities of it. There is also one to change the map the gate to the Maku Tree is (However I will go on further about this). There will be many map patches, such as changing the animal and volcano town maps, but right now there are only two.

In other news, I've cracked how the Gale Seed Warping works. Actually, it's extremely efficient and just screams "HACK ME!". There are three straight-forward bytes per spot (Although the third one seems kind of useless), and room for about 3 or 4 extra warps at the end of the data (I've tested this and we can easily add or remove them).

The only thing I worry about is area editing, such as editing what makes the minimap say Cresent Island is Cresent Island, and there's a Scent Seed Tree there. I've found other unimportant things, such as the cursor offset, sprite, and palette, but I doubt anyone would care to edit those.

Back on the topic of patches, I want to get into the map changing, or what they're really called, map scripts (Like how the Maku Gate stays forever removed after being opened. This is, of course done by a flag somewhere in the 0xC000 bank, but I mean the other part of it). The way they're done is kind of similar to how interaction script locations are calculated. The CPO (Common pointer operation, which is where you have a base address, add the map group * 2, and calculate the pointer there) is done to address 0x124A7. The date here is in pairs of two. The game reads the first byte as the map. If the byte matches the map you're going in to (Like 48 if you're heading up from the Ring Shop), the next byte (Always read but only matters if the Z flag is set) is a reference to the next procedure (I'm going to call these scripts from now on).

The new script is calculated by taking the script reference byte and multiplying it by 2, adding it to 0x012437, and calculating the pointer there using bank 4.

For example purposes, the generated script address takes us to 0x12673. The only thing done here is a global flag check. The flag it checks is bit 2 of 0xC6D2, which is set if the Maku Gate has been opened. If you're wondering, here's how to find the address of the flag and the bit number. Basically, the upper 5 bits are the value to be added to the memory address and the lower 3 are the value added to 0x0000F8 to be read as the bit AND value.

Calculating Address Flag and Bit Number [C# Syntax]
byte value = 0x12; //This is the one used in the Maku Gate check
byte b = (byte)(((value & 0xF8) >> 3)); //0x2
int memoryAddress = 0xC6D0 + b; //C6D2
b = (byte)(value & 0x07); //2 byte
bit = ROMData[0xF8 + b]; //ROMData being the file buffer

Calculating Address Flag and Bit Checking Value [C# Syntax]
byte value;
int dMemoryAddress = 0xC6D2; //Let's make this as easy as possible
byte dBit = 0x2; //The bit to check
byte b = (byte)(dMemoryAddress - 0xC6D0);
byte final = (byte)((b << 3));

Not too bad, but they probably could've saved more space using two bytes instead of one and not performing the procedure. But anyway, that's how those map-specific entry events work. Pretty handy-dandy if you ask me, and it only makes hacking these games better. See you tomorrow!

Thursday, June 10, 2010

A LOT of Interaction Stuff

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!

Late News, but It's Good!

Well, this will be a short post (And sorry for it being late, but I was watching the Black Hawks get their well-earned Cup!) but I have good news. I've found more data that will only make hacking much better. For starts, the first thing I found is the starting stuff. This includes the map group, the map index, and your position. Next, just recently, I've found how music works. Luckily it's simply one uncompressed byte for each map and easy to access. This pretty much ends what I need to find, as I know how pretty much everything works (Although I would like to know what forces the game to not let you in the east and south bounding areas). I have not yet found the overworld minimap graphical or ordered data, but I'm sure it shouldn't be any trouble at all.

Some more things I have left to discover the data for are events (According to JS there is a scripting engine. I'm not sure if this is bad or not. Hopefully it shouldn't be too hard to crack!), how checks work, and some more stuff about interactions (Mainly what enemy groups spawn what and where). Note that the script editor (If I crack the scripting engine. However, I have a feeling I can as long as my debugging skills are good enough, since obviously interactions use it and I have their addresses) will not be implemented into the level editor, but made as a separate program for organization.

So that's all for discoveries and data findings. I got bored earlier today and killed some time and remade 20 of the LA maps (There is one mapping error in here I did not notice [A tree using the wrong corner], so ignore that). Oh, and these are actually playable as I made them using the level editor.



So that's all for today's. Tune in tomorrow for more updates!

Tuesday, June 8, 2010

Aah, Sweet News at Last!

Sorry to keep you waiting, but I have something to post about! Don't worry, the project is still under development and I've gained even more knowledge on some things, like address that control the tile grass turns into after being chopped, or when to swap a room or tile with another. Basically things that can really only be done with an assembler and a hex editor.

So anyway, I've finished both stages of the warp editor (Currently STILL only a viewer, but not to worry, it will surely be able to edit when I stop slacking). This means we can see what maps have what warps, and exactly where those warps lead to. Here's a screenshot of the editing screens.



On the left is the normal, global room warp, middle is position-specific, and right is side-room. The ones below them are their windows for editing the secondary warp.

Other than warps, it is now possible to edit area properties (Including what area a map gets). I've also fixed an ASM bug with side room loading from warps, since they use groups 6 and 7 instead of 4 and 5, so they were loading improper pointers. But that's all good, and that concludes today's post. Thanks for staying with me so long and bearing my unexpected vacation. Until tomorrow, keep on trollin' (I wonder if BreakingNYC will start again now... Hmm...).