ZSR Forums
November 23, 2024, 11:07:33 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: ZSR Forums are back - read only!
 
   Home   Help Search Members Login Register  
Pages: [1] 2
  Print  
Author Topic: petrie911's Big Topic of Hacks  (Read 33004 times)
petrie911
Moderator
Regular Guay

Posts: 40


Everybody Loves Hypnotoad!


« on: July 01, 2010, 12:00:00 AM »

So, this is a place for me to put tutorials, videos, and other information I've gathered relating to hacking.  Also, will contain status updates on my current full game hack.

Ocarina Song Mods

Ode of Somaria (Push blocks, Warp Whistle)
Cucco Dance (Cuccos, "Chicken Dance")
Song of Portals (Doors, "Still Alive")

petrie911's Hack
Completed areas

Forest Temple
Fire Temple

In Progress

Water Temple (Building) (4/21 rooms complete)
« Last Edit: June 15, 2013, 12:32:43 AM by petrie911 » Logged
petrie911
Moderator
Regular Guay

Posts: 40


Everybody Loves Hypnotoad!


« Reply #1 on: July 01, 2010, 12:01:42 AM »

Make a custom Ocarina Song!

All absolute addresses are for the Debug ROM.  For other ROMs, use the search to find the right places.  The relative offsets should be about the same.

Things you will need:

Hex editor (XVI32 is a good choice)
mml2m64 (more specifically z64seqrip and z64parser, which come with it)
N64 checksum fixer (GZRT works fine)

Changing the name of the song

--Search for the text string that forms the name of the song (eg "Sun's Song" or "Song of Storms").  Replace all instances with the new name for your song.

--The start menu uses sprite text.  Because of this, changing the name of the song on the start menu is beyond the scope of this tutorial.

Changing the Effect Actor

--Open the Debug ROM up in a hex editor and go to BCAE14.  Alternatively, search for 01 99 01 98.

--The 7 pairs of bytes correspond to the 7 songs.  In order, they are
   Saria's Song: BCAE14
   Epona's Song: BCAE16
   Zelda's Lullaby: BCAE18
   Sun's Song: BCAE1A
   Song of Time: BCAE1C
   Song of Storms: BCAE1E
   Scarecrow's Song: BCAE20

--Change the pair of bytes for the desired song to the actor number of the desired actor.  Follow this link to the Actor List.  If the actor you want isn't on that list, find an instance of said actor in the game, open up the corresponding map with UoT, and copy the actor number from there.
http://glitchkill.proboards.com/index.cgi?board=gdg55y&action=display&thread=463&page=1

--The actor will be summoned with variable 0000 (Song of Time summons with variable 0001).  Additionally, the actor can only be summoned in areas with its corresponding group.  For example, summoning a cucco will work in Kakariko village, but not in Hyrule Field.


Changing the Activaton Sequence

--Open the Debug ROM in your hex editor and go to BA8DA0.  Alternatively, search for 06 00 04 03.

--The songs are stored in consecutive blocks of 9 bytes.  They are in the following order.
   Minuet of Forest: BA8DA0
   Bolero of Fire: BA8DA9
   Serande of Water: BA8DB2
   Requiem of Spirit: BA8DBB
   Nocturne of Shadow: BA8DC4
   Prelude of Light: BA8DCD
   Saria's Song: BA8DD6
   Epona's Song: BA8DDF
   Zelda's Lullaby: BA8DE8
   Sun's Song: BA8DF1
   Song of Time: BA8DFA
   Song of Storms: BA8E04
   Scarecrow's Song: BA8E0C

--The 9 bytes that make up each song consist of a first byte that tells the game how many notes are in the song, and then 8 bytes that represent the activation sequence.  Each byte corresponds to a button press, as follows.

   00 A
   01 Cv
   02 C>
   03 C<
   04 C^


Changing the playback notes

--Open the Debug ROM in your hex editor and go to BA8120.  Alternatively, search for 02 00 00 12 56.

--The songs are stored in consecutive blocks of 160 bytes, in the following order

   Minuet of Forest:BA8120
   Bolero of Fire: BA81C0
   Serande of Water: BA8260
   Requiem of Spirit: BA8300
   Nocturne of Shadow: BA83A0
   Prelude to Light: BA8440
   Saria's Song: BA84E0
   Epona's Song: BA8580
   Zelda's Lullaby: BA8620
   Sun's Song: BA86C0
   Song of Time: BA8760
   Song of Storms: BA8800

--Each note consists of 8 bytes.  You can have up to 19 notes in the playback sequence, as the last note must be an end rest.

--Byte 1 controls the pitch of the note, as well as the note displayed.  It is simply the number of half-steps between the note and Middle-C.  The 5 default notes are listed below.  FF indicates a rest, ie, no note is played.

   02 A  (D)
   05 Cv (F)
   09 C> (A)
   0B C< (B)
   0E C^ (D)
   FF Rest

--Byte 2 is always 00 in game-defined songs.  It seems to have no purpose.  Odd.

--Bytes 3 and 4 are the duration of the note, in input frames.  A value of 60 (0x3C) will give a note that lasts exactly 1 second.  

--This is an unsigned short integer, so the maximum number of frames a note can last is 65535 (0xFFFF). Such a note would last over 18 minutes.
   --If you don't want to calculate your own note durations, the following are a good choice.

   06 Sixteenth note
   0C Eighth note
   18 Quarter note
   30 Half note
   48 Dotted Half note
   60 Whole Note

   --A rest of 00 duration signals the end of the song.

   --If you want to have two consecutive notes with the same first byte, put a 01 duration rest between them.  Otherwise, the song won't work.

--Bytes 5 and 6 are the volume, in the form of a short integer.  Most ocarina songs use volumes between 5000 and 6000.

--Byte 7 is the pitch adjustment from the control stick.  It is a signed byte.  7F is a whole step up, while 80 is a whole step down.  Fractional steps up and down can be achieved with smaller values.

--Byte 8 is the vibrato from the control stick.  Still investigating this.

--The playback sequence is what shows up when you learn the song and when the song plays on the start menu.  Keep in mind that if you use sharp or flat notes in the playback sequence, you will have to match them when learning the song and when playing it on the start menu.
Editing the Sequence file

Firstly, you'll want to download mml2m64.  We won't actually be using it, but we will be using the tools that come with it.  It's also a nice thing to have anyways, as you can also use it to insert songs into the game.  Additionally, you will need something that can fix the game's checksum.  If you don't already have one in mind, GZRT is a perfectly good choice.

I'll also warn you now that this is going to be a lot harder than the other steps.  If this is your first time doing this, I recommend you use the Song of Storms, as it is the easiest to work with.

--Use z64seqrip to extract the Sequence files.  This part isn't wholly necessary, but it does make things easier.  Refer to the readme file included with mml2m64 to find out how to use this.

--Find the file corresponding to the song you are modding.  The song numbers can be found here. If you are using the Song of Storms, it is number 49.
http://web.archive.org/web/20080213144845/http://zso.krahs-emag.com/codes/codeinfo.html

--The music track, which is what you're going to be editing, is encoded in a file format somewhat similar to the playback sequence above.  There are 4 parameters for each note, which always appear in the following order.

Command -- This specifies both what note to play and the type of note.  See below for more.
Timestamp -- This is the length of the note, in input frames.  This works the same as the note length in the playback sequence.
Velocity -- This seems to allow for tempo adjustments (eg, ritardando).  Most songs use values in the 70-7F range.
Duration -- This affects how much time the note actually plays.  It allows you to make staccato and legato.  The larger this is, the shorter the resulting note.

To figure out the Command value, first find your pitch value.  The pitch value is the number of half-steps your note is above A1.  Equivalently, it is 39 (0x27) plus the number of half-steps your note is above Middle C.  The command value then depends on which of the 4 parameters you will be specifying.

0X00 + Pitch value -- All 4 parameters specified.
0X40 + Pitch value -- Duration is not included.  The sequencer uses the default value
0X80 + Pitch value -- Timestamp is not included.  The sequencer uses the previous value
0XC0 (fixed value) -- Rest.  Velocity and Duration are not included.
0xFF (fixed value) -- End of track.  No other parameters are included.

--For a simple yet effective way to translate your song into a sequence file, convert each note into pitch values and lengths using the same method as you did in the playback sequence.  Then do the following.

   Command Value: Add 0x67 to the pitch value.  Use C0 for rests.
   Timestamp: Simply copy the length.
   Velocity: Use 0x78.  Leave this out if the note is a rest.

Add C0 01 FF to the end of your sequence to complete it.  If you are modifying Epona's Song, the Song of Time, or the Sun's Song, add a second C0 01 FF to the end of your sequence.

--Use the z64parser to interpret the sequence file.  The thing we want from this is the offset of the music track.  Scroll down to the bottom to find it.  It should be the very first thing in the first line after the Music Track header (for the Song of Storms, it will be 0x96).  Open the file in a hex editor and insert your sequence at that location.

--Your sequence need not take up the same amount of space as the original song's sequence, but it can't go past the end of the file.  If your sequence doesn't take up the whole file, any values after its end will be ignored, so you can use them however you like.  This is a good place to put your name, to mark that you made this track.  However, don't delete any bytes from the end.  It is best to keep the new file the same length as the original.

--If you want to change the tempo or master volume, go to the header section of the parsed music file.  It will tell you the offset where these are stored.  For the Song of Storms, the volume is at 0x0A, and the tempo is at 0xC.

--To insert your newly formed zseq file into the ROM, open the original zseq file, your new zseq file, and the ROM in hex editors.  Search the ROM for the last 16 bytes of the original zseq file; this should immediately take you to the ROM's zseq file's location in memory.  Now scroll up until you find the beginning of the zseq file.  The file on the ROM will be the same length as the original zseq file.  Now, starting with the beginning of the ROM's zseq file, block off a number of bytes equal to the number of bytes in the original zseq file, and delete them.  Now, insert your zseq file into the ROM exactly where you deleted the ROM's file.

--There is one last thing you need to do.  The sound files are part of the ROM's checksum, which you have now changed.  Run your ROM through your chosen checksum fixer, and you're done.

Credit to the excellent people at glitchkill for most of the stuff not pertaining to the MIDI format.
« Last Edit: March 09, 2011, 08:56:10 PM by petrie911 » Logged
petrie911
Moderator
Regular Guay

Posts: 40


Everybody Loves Hypnotoad!


« Reply #2 on: July 01, 2010, 05:38:42 AM »

Sample Song -- Song of Portals

So, we're going to change the Song of Storms into the Song of Portals, which will summon a door and sound like the beginning of "Still Alive".  Here's the steps we have to follow.

1) Replace instances of "Song of Storms" with "Song of Portals".  For example, changing "You played the Song of Storms." to "You played the Song of Portals."



2) Change the effect actor of the Song of Storms to "door".  The Actor List tells us that the actor number of a door is 0009.  So, we go to address BCAE1E, and change it from 018B to 0009



The next steps all involve the actual music to Still Alive.  The relevant part is here



3) Change the activation sequence of the Song of Storms.  We'll probably want to use the first 5 notes there.  A good approximation is C^ C< C> C> C<.  So, we change the note count to 05 and the notes to 04 03 02 02 03 00 00 00.



4) Change the playback sequence.  We'll use the standard 5000 volume and my suggested note lengths, so they'll all have 000C length.  The pitch sequence is C-B-A-A-B, which translates to 0C-0B-09-09-0B.  Remembering to put a short rest in between the two As, we have

0C00 000C 5000 0000
0B00 000C 5000 0000
0A00 000C 5000 0000
FF00 0002 5000 0000
0A00 000C 5000 0000
0B00 000C 5000 0000
FF00 0000 5000 0000

However, if you try this out, you'll find that during playback, the game uses R + C< for the first note.  We'd rather it use C^, so we switch the first note to 0E, and use the pitch modulator to change its pitch back to C.  So the new first note is

0E00 000C 5000 8000



5) Edit the sequence file.  You can either use the simplified or advanced method.  Either way, though, first translate the sheet music into list of pitches and durations.  Then replace each note with its pitch value, the number of half steps it is above middle C plus 0x27, and each duration with its value from before



C5 1/8  =>  33 0C
B5 1/8  =>  32 0C
A5 1/8  =>  30 0C
A5 1/8  =>  30 0C
B5 1/8  =>  32 0C
Rs 3/4  =>  C0 48
D4 1/8  =>  29 0C
C5 1/8  =>  33 0C
B5 1/8  =>  32 0C
A5 1/8  =>  30 0C
A5 1/4  =>  30 18
B5 1/8  =>  32 0C
Rs 1/4  =>  C0 18
G4 1/4  =>  2E 18
A5 1/8  =>  30 0C
D4 1/8  =>  29 0C

Simple method:

For each note that is not a rest, add 0x40 to the pitch value to get the command value, leave the length unchanged to get the timestamp, and use 0x78 for the velocity.  Finally, add 0C 01 FF to the end.  This is now your sequence file.

73 0C 78
72 0C 78
70 0C 78
70 0C 78
72 0C 78
C0 48
69 0C 78
73 0C 78
72 0C 78
70 0C 78
70 18 78
72 0C 78
C0 18
6E 18 78
70 0C 78
69 0C 78
0C 01 FF

The simple method sometimes gives poor results, and takes up a little more space than the advanced method.  However, in this case it does a very good job. 

Advanced method:

--The first note begins the same way as in the simple method.

--If the current note is the same duration as the previous note, add 0x80 to the pitch value, place a 0x78 after that value for the velocity.  Place 0x00 after that if the next note is a different pitch, else place 0x20.  This is the duration.

--If the next note is a rest, don't add anything to the pitch value.  Add the current note's length to the rest's duration and use that as the timestamp.  Place a 0x78 after that.  Finally, divide the rest's length by the timestamp, and multiply it by 0x100.  Round to the nearest integer if necessary, and use it as the duration.

--In other cases, use the simple method.

Applying these rules gives us

73 0C 78      (first note)
B2 78 00      (same length)
B0 78 20      (same length, next note is same pitch)
B0 78 00      (same length)
32 60 78 C0      (next note is rest, rest takes 3/4 of duration)
69 0C 78      (new length)
B3 78 00      (same length)
B2 78 00      (same length) 
B0 78 20      (same length, next note is same pitch)
70 18 78      (new length)
32 24 78 AA      (next note is rest, rest takes up 2/3 of duration)
6E 18 78      (new length)
70 0C 78      (new length)
A9 78 00      (same length)
0C 01 FF      (end of track)

The advanced method gives more control over the music, and also makes shorter files.  However, it's also more difficult to work with, and thus is only recommended if the simple method proves inadequate.  Still, the advanced method gives good practice working with the commands, which is good if you want to try some more complicated things with articulation.

Anyways, now that we have a sequence, we now must find the Song of Storms in the ROM.  The zseq file ends in 70 36 70 C0 2A FF (highlighted in red below).  Searching for that string takes us immediately to the file.  We can find the start of the track by inspection: since 78EF5 is the second to last occurance of byte FF (highlighted in blue), the track must start at 78EF6.  Starting at that point, write your sequence into the ROM.



Finally, open the ROM in GZRT, go to Operations, and choose "Fix CRC".  This will fix the ROM's checksum, allowing PJ64 and other emulators to play it.

If all has gone well, you should have ended up with something like this:

http://www.youtube.com/watch?v=k626U5wG-rI
Logged
NOKAUBURE
Regular Guay

Posts: 68



Email
« Reply #3 on: July 01, 2010, 09:06:28 AM »

this needs a cheat code port to make more easy. There are one to modificate the song of storms efect.
It can be useful making a scarecrow song and then put his playback on other song??
Logged

Tongue
petrie911
Moderator
Regular Guay

Posts: 40


Everybody Loves Hypnotoad!


« Reply #4 on: July 17, 2010, 07:37:24 AM »

Files and Actors and Groups, Oh my!
A guide to hex editing your map files

While the Utility of Time is the main method you'll be using when editing maps, there are a few times when its abilities fall short.  In these cases, you don't really have a choice but to hex edit the map file directly.  The main time you'll be doing this is when adding actors or groups to the map.  This guide will cover that.

What are groups, anyways?

Groups are the actual data for the actors.  If a group's number is on a room's group list, the game will load that group when loading the room.  If an actor's group is not on the group list, the game will not have the data for the actor, and will not load it.  With a few exceptions, all actors must have their corresponding group on the group list if you want them to work.

The exceptions mentioned above are actors in groups "0000" through "0003".  Many scenes have some or all of these groups pre-loaded into them.  Dungeons nearly always have all 4 of those groups.  As such, groups "0000" through "0003" do not need to appear on the group list for their actors to work.

WARNING: Some versions of UoT display the group list as being 1 longer than it actually is.  If your version does this, keep in mind that the last group it displays is not actually on the list, and may in fact be part of the actor data.

Getting to know your map files



The first 4 lines of the map file are the header.  This tells the game what properties the room has and where the various pieces of room data are.  We are only concerned with the last 2 lines for the purposes of this tutorial.  The example above is the first room of the Forest Temple.

The 8 bytes highlighted in blue tell the game where vertex data is located.  You can tell it's the vertex data because it begins with 0A.  It's generally best to let UoT edit these.  The most important thing to notice is the part after "03 00", which tells you where the vertex data starts.  In this map, vertex data starts at offset "D0".

The 8 bytes highlighted in green tell the game where group list is located.  You can tell it's the group list because it begins with "0B".  The byte after "0B" tells the game how many groups there are, and the bytes after "03 00" tell the game where group list starts.  In this map, there are 7 groups, and the first group is located at offset "40".

The 8 bytes highlighted in yellow tell the game where actor list is located.  You can tell it's the actor list because it begins with "01".  The byte after "01" tells the game how many actors are in the room, and the bytes after "03 00" tell the game where the actor list starts.  In this map, there are 8 actors, and the first actor is located at offset "50".

After the header comes the group data, highlighted in orange, starting at offset "40" just as the header said.  Each group is 2 bytes long.  In this map, the groups are

0072 0073 000E 00A4 005D 0024 015C

Which are Forest Temple Objects, Forest Temple Textures, Chests, Torches, Bubbles, Skulltulas, and Collectible Heart, respectively.

Next comes the actor data, highlighted in red, starting at offset "50", again just as the header said.  Actors are 16 bytes long, consisting of 8 pairs of bytes.  Their format is as follows:

Actor#  X pos.  Y pos.  Z pos.  X rot.  Y rot.  Z rot.  Actor Var.

This room has 5 Skullwalltulas ("0095"), a big Skulltula ("0037"), a chest ("000A"), and a switch ("012A").

Lastly, after the actor data is the vertex data, in red text, starting at D0 as the header said.  The vertex data is more complicated to edit than the other two, and again is best left to UoT.

Adding Groups to your map

There are two methods to add groups to a map.  One method is used when you want to take a map with 8 or fewer groups and give it 12 or more groups.  The second method should be used in all other situations, and is the one we will be discussing.

The first thing we're going to do is to move the group list so it starts at offset "3A".  To do this, remove the 6 bytes that precede the group list, and insert 6 blank bytes after the group list.

WARNING: It is very important that you insert the 6 blank bytes BEFORE the start of the actor list.  Further, not all maps start their actor list on a new line like this one does.  If you are unsure where the actor list begins, consult the header as detailed above.



Next, we will need to tell the game that the group list starts in a new location.  So you will need to change the "40" at the end of the group section to "3A".

Lastly, you will need to tell the game that the group list now has however many groups you want there to be.  In this case, there will be 10 groups in the room, so change "07" to "0A".



And that's it!  Now, you can go into UoT and change the extra blank bytes into the groups you want.

WARNING: Adding too many groups to a map will cause the game to freeze when loading the room.  How many is too many depends on both the map and which groups are on the list.  If you encounter this problem, see if there are any groups you're not using and remove them from the list.

Adding Actors to your map

Adding actors also has two methods.  One lets you add at most 1 or 2 actors to your map (how many depends on the map in question).  The other allows you to add as many actors as you want to a map.  This section will deal with the latter.

The first step is to copy and paste the room's current actor list onto the end of your map file.  As mentioned before, the location of the actor list can be found by consulting the header.  Once you've done that, add 1 new line to the end of the file for each actor you wish to add.



Next, find the offset where you pasted the room's current actor list.  take this value and place it after the "03" in the actor section of the header.  Additionally, change the number of actors (found after "01" in the same section) to the new number.  In this case, we change the offset to DB90 and the number of actors to 11 ("0B")



Now you are done hex editing the map file.  You can change and move your newly-added actors by opening the map in UoT.  However, because you changed the size of the map file, we are not entirely done.  We will need to inform the scene file and the main file table that the map is now larger.

WARNING: When UoT injects a file into the ROM, it always replaces the file's last byte with "00".  The best way to avoid this is to make sure that your last actor has a variable that ends in "00".  If this is impossible, you will have to hex edit the ROM itself to fix the error.

First, go to your scene file and open it up in your hex editor.  You should see two columns of "FF"s.  Those actually represent doors, but that's a topic for another guide.  After the doors are the offsets of the maps.  That's what we're looking for.  Each map takes up 8 bytes--4 for the start offset and 4 for the end offset.



The map offsets are thankfully in the same order as the maps.  So, in this case, we want the very first one.  Take note of what the end offset is ("02 16 CB 90"), then add "10" to it for each line you added to the end of the file.  In this case, add "B0" to get "02 16 CC 40".  Save your scene file and use UoT to inject it and your map into your ROM.

WARNING: Make sure that you haven't added so many actors that you run into the next file.  If your end offset is larger than the start offset of the next map file, you have too many actors.

The nest step is to edit the main file table.  Open your ROM in the hex editor, and search for the end offset you took note of earlier.  Do the same thing to it as you did in the last step.



The final step is to fix the game's checksum.  Open the ROM in GZRT and use the checksum fixing tool to do so.

Adding actors through file optimization

This is the other method mentioned above.  While it's really only good for 1 or 2 actors, it doesn't change the size of the map file, meaning you don't have to do all that stuff with editing the scene and file table.  So if you only need that 1 extra actor for your room, this is a good way to do it.

Firstly, go through the steps outlined in adding groups, where you move the group list to start at "3A".  Next, find where the Vertex data starts and delete all blank bytes between the end of the actor list and the start of the vertex data.  Now insert the same number of blank bytes you just deleted at the beginning of the actor list.



If all goes well, your actor list should now start on a new line, the vertex data should start immediately after it, and there should be a large number of blank bytes between the groups and the actors.  If these blank bytes form a full line, you can insert an actor there.  You may need to remove groups to achieve a full line.  Once you've added your actor(s), change the number of actors and the offset of the actor list accordingly.

For example, in the above, we could change the number of actors to 9, starting at offset "50".  Or, if we could reduce the number of groups to 3, we could increase the number of actors to 10, starting at offset "40".

WARNING: UoT sometimes has trouble changing the actor number of the very first actor on the list.  If you run into this problem, simply open the map in your hex editor and change the actor number yourself.

You can further optimize your file by letting the actor and group list share data.  For example, in the map below, the fact that the Lizafos actor number ("0025") is the same as the Torch Slug group number is used.  Additionally, by placing the Lizafos at X position 11 ("000B"), the Wallmaster group can be added to the room.

Logged
NOKAUBURE
Regular Guay

Posts: 68



Email
« Reply #5 on: July 17, 2010, 11:03:28 AM »

is that somaria song, the song that link plays with a whistle in NES? it remembers me alot.
Another thing, you can spawn cuccos without the group loaded? or only works in kakariko, valley and ranch?
Logged

Tongue
petrie911
Moderator
Regular Guay

Posts: 40


Everybody Loves Hypnotoad!


« Reply #6 on: July 17, 2010, 06:42:12 PM »

It only works with the group loaded.  Of course, there's nothing stopping you from adding the cucco group to any map, so that isn't as much of a problem as you'd think.  In fact, it's actually kind of helpful.  Unlike with, say, push blocks or doors, you can limit where cuccos are summonable.

And, yeah, the Ode of Somaria is the whistle from LoZ.  It seemed appropriate.
Logged
Matt23488
Regular Guay

Posts: 40


Meh


Email
« Reply #7 on: July 17, 2010, 08:44:41 PM »

Wow, thanks a bunch petrie911. This is extremely helpful. When I get some time I plan on working on a hack of my own, and this will definitely come in handy.
Logged

Zach
Deku Scrub

Posts: 4


« Reply #8 on: July 18, 2010, 03:44:33 AM »

I noticed you said you're "planning" for the water temple. How do you go about planning just out of curiosity?
Logged
thundrio
Special Guay

Posts: 216



Email
« Reply #9 on: August 04, 2010, 04:39:58 PM »

i just have a quick question. if i have never modded anything in uot (looked around in it) how hard would it be for me to add a cuccoo to a place where there are no cuccoos (not even unloaded cuccoos), because i am testing something that requires a cutscene dive and the cuccoo is the only one i am good with (or if somebody knows where to find a code to "fake" a cutscene). thanks
Logged

[19:30] <13@jiano> i love programmin
[19:30] <13@jiano> if thing == otherthing: do thingything !!!!!!!!
petrie911
Moderator
Regular Guay

Posts: 40


Everybody Loves Hypnotoad!


« Reply #10 on: September 13, 2010, 09:19:06 PM »

How to make enemies hookable

Making actors hookable is actually pretty simple.  There's one byte you need to change, plus one more byte for every hitbox on the actor you want to make hookable.  Thankfully, the bytes in question are fairly easy to find.  So, without further ado, let's get started.

Step 1: Find the relevant actor file

All enemy actor files are listed as ovl_En_XXX.zactor. Bosses are ovl_Boss_XXX.zactor.  Unfortunately, not all enemies are clearly named.  However, you can usually get a hint by finding an instance of an enemy in UoT, and looking at what the enemies' group is named.  For example, Like Likes are object_rr, so the Like Like actor is ovl_En_rr.zactor.  If this doesn't work, you may need to do some guesswork.

Additionally, it should be noted that several things you probably wouldn't consider enemies are considered as such by the game.  For example, Gossip Stones, Bombs, and Bombchus are all enemies.

For demonstration purposes, we will make Torch Slugs (ovl_En_Bw.zactor) and Queen Gohma (ovl_Boss_Goma.zactor) hookable.

Step 2: Find your actor file in the ROM

Search your actor file for 0xFFCFFFFF. That hex string is the marker for hitbox collision data.  That's exactly what we want.  When you find it, it should be fairly close to the end of the file.  Once you do, scroll up until you see a line that has the form AAAA XXXX XXXX XXXX GGGG XXXX XXXX XXXX, where AAAA is the actor number, GGGG is the group number, and a fair number of the XXXX should be zeroes.  This line is highlighted in the picture below.

Now, open up the ROM in your hex editor.  After the actor number line, there should be four words that all begin 0x809XXXXX.  Search the ROM for that entire line.  This should take you directly to the actor data in the ROM.  check to make sure it did by seeing if the previous line matches the one from the actor file.  If not, continue searching.

Step 3: Modify bytes



Take a look at the byte highlighted in the picture.  Find the corresponding byte in your editor, and add 0x04 to that byte.  This tells the game that the enemy is hookable.

Next, look for sections of the code of the form FFCF FFFF 0000 0000 XX01 01XX.  The first instance of this is highlighted in red for both Queen Gohma and the torch slug.  Add 0x0004 to XX01. This will make the hitbox hookable.

Now, you'll notice the torch slug doesn't have any more of these sections.  That's because the torch slug only has 1 hitbox.  Meanwhile, Queen Gohma has many of these sections, and as you might guess, it's because she has a lot of hitboxes.  You can experiment with which hitbox is which if you like, but each one is made hookable in the same way.  Of course, if you want any part of Queen Gohma to be hookable, just change them all.

And that's it.  You can now make any enemy you want hookable.  On a similar note, if you want to make an enemy non-hookable, simply go through the procedure again, and subtract 0x04 from the relevant bytes instead of adding it.

Special note for bombchus

If you try to do this with bombchus, you'll notice that they explode when you try to hook them.  You'll still be pulled to the place where the chu was, but the hook point will stay in place.  If you want to the hookshot to move with the chu, change address 0xD7F5D7 from 0x02 to 0x00.  For those of you who are curious, this forces the game to skip the check that makes bombchus explode when attacked.  This has the side-effect that stabbing chus will no longer cause them to explode.

The end result should look something like this.

You may also want to change the relative speeds of the hookshot and bombchus.  To do this, first determine the speed you want to change them to.  For reference, the default hookshot speed is 30 and the default bombchu speed is 8.  Next, find the representation of your speed in Floating Point, which can be done here.  Take the first 4 hex digits of the result.  This will be your speed constant.

To change the hookshot speed, change the halfword at 0xC34182 to your speed constant.

To change the bombchu speed, change the halfwords at 0xD7F57A and 0xD7F51E to your speed constant.
« Last Edit: September 18, 2010, 09:46:51 PM by petrie911 » Logged
pikmin
Deku Scrub

Posts: 9


Email
« Reply #11 on: September 17, 2010, 07:30:52 PM »

question from lazy people like me: can we request songs?  And then get  patch for the debug rom?  Thanks
Logged
petrie911
Moderator
Regular Guay

Posts: 40


Everybody Loves Hypnotoad!


« Reply #12 on: September 18, 2010, 09:47:27 PM »

Sure, I suppose.  No guarantees on how quickly it'll get done, though.

Also, added how to make bombchus not explode when hooked, and how to modify the hookshot speed.
« Last Edit: September 18, 2010, 09:51:10 PM by petrie911 » Logged
petrie911
Moderator
Regular Guay

Posts: 40


Everybody Loves Hypnotoad!


« Reply #13 on: November 17, 2010, 10:46:14 PM »

Switches, Doors, Chests, and All That Jazz

A guide to dungeon infrastructure

Probably the biggest part of Zelda hacking is making your own dungeons.  The Utility of Time is great for changing your actors and moving them around, but it won't help you design the dungeon itself.  If you want to make a good, solid, Ocarina-of-Time-style dungeon, you're going to need to understand the basic elements that create a dungeon.

Also, a quick note.  I refer to a single hexadecimal digit as a "hex".  This is not standard usage, but I feel nybble and hexit sound stupid.  Anyways, on with the guide.

Event Flags

Event flags are the way the game keeps track of what you've done in the dungeon.  Each flag is a single bit, which can be either 0 or 1.  Normally, the flag starts out as 0.  Changing a flag to 1 is called setting the flag, and changing it to 0 is called clearing it.  Thus, if a flag is cleared, it is 0, and if the flag is set, it is 1.  Objects which react to a flag being cleared or set are said to be attached to it.  If they react when the flag is set, they are said to be rising-edge triggered.  Those that react when the flag is cleared are falling-edge triggered.  An object attached to a flag can be both rising- and falling-edge triggered, and it can also be neither.

Chest Flags

Chest flags are a distinct group of flags.  As their name suggests, they tell the game which chests in the dungeon have been opened.  Each dungeon has its own set of 32 chest flags.  If two chests share the same chest flag, opening one will cause the other to be open as well.

Which flag a chest is attached to is determined by its actor variable.

Chest
000A WYY0 + 00ZZ, Group 000E

W  - The type of chest.  See below for a list
YY - Contents of chest.  Always even.
ZZ - Chest flag.  Ranges from 00 to 1F.

For a list of chest contents YY, see the Actor List.

The RAM address for the current scene's chest flags is 0x00213D58.

Clear Triggers

Clear Triggers are another distinct group of flags.  Each dungeon has up to 32 clear triggers.  However, since no dungeon has 32 rooms (Spirit Temple comes closest with 29), they will not all be used.

The way the clear trigger works is very simple.  When all enemies in the room are killed, the clear trigger is set.  There is no way to clear a clear trigger without some form of ASM modification.  When a room's clear trigger is set, enemies are forbidden from spawning in the room.  However, keep in mind this definition of "enemies" may not always be what you think it is.  For example, the clear trigger does not count Gold Skulltulas as enemies.

Many objects have a way to attach to the room's clear trigger.  For most of these, this will be discussed when we discuss switch flags below.

The RAM address for the current scene's clear triggers is 0x00213D5C.

Switch Flags

Switch Flags are by far the most important group of flags.  They control just about everything in the dungeon not mentioned above.  There are 64 switch flags in a dungeon, which can be divided into three groups.

00-1F -- Permanent flags -- retain their values when you leave the dungeon
20-37 -- Temporary flags -- cleared when you leave the dungeon
38-3F -- Local flags -- cleared every time you change rooms

An important thing to note is that Farore's Wind saves the values of the temporary flags when cast.  When you warp back to the room you cast it in, it writes these values back into the temporary flags, regardless of what their current values are.  Most importantly, this holds true even if you are warping between two different rooms of the same dungeon.

It is also just a generally good idea to never attach anything to switch flag 3F.  Several things use "attached to 3F" as a shorthand for "not attached to anything" or "attached to clear trigger".  It can be done, but it'll save you a lot of headache to just not do it.

Also, it is a bad idea for two adjacent rooms to use the same local flag.  This is because the next room will load before the flags are cleared, and you may set off things in the next room you didn't intend to.

Lastly, in dungeons with a boss key, switch 14 is reserved for the boss door.  Don't use it.

The RAM address for the current scene's switch flags is 0x00213D48.

« Last Edit: December 03, 2010, 05:46:01 PM by petrie911 » Logged
petrie911
Moderator
Regular Guay

Posts: 40


Everybody Loves Hypnotoad!


« Reply #14 on: November 17, 2010, 10:50:45 PM »

Attaching actors to switch flags

Now that we've discussed how switches work, it's time to start using them.  Below is a list of actors that can be attached to switch flags, how to change their actor variable to attach them, and their behavior with regards to changing switch flags.  The switch flag will always be represented as XX.  You must fill in the value with the desired switch.

Some actors have properties that depend on individual bits of the actor variable.  In this case, the relevant hex will be expanded into its 4 bits, and each bit will have its function listed.  Bits represented with ? have unknown function.

Some actors will have their actor variables given as arithmetic expressions.  The final actor variable will require evaluating the expresson.  If you're not familiar with doing math in hexadecimal, the standard calculator in Windows has a hexadecimal mode.

General Objects

Basic Switch
012A XXZY, Group 0003

Y = switch type
   0 - Floor switch
   1 - Rusted switch
   2 - Eye switch
   3 - Crystal switch
   4 - Targetable crystal switch

Z = I?PT
   I = 1 - frozen in ice
   P = 1 - clears when not stood on (floor and rusted only)
   T = 1 - can be turned on and off



Chest
000A WYY0 + 00ZZ, Group 000E

YY = Contents, see actor list

ZZ = Chest flag, see above

W = Chest Type

   0 - No action, Large
   5 - No action, Small
   2 - No action, Ornate (Boss key)

   1 - Clear Trigger, Large
   7 - Clear Trigger, Small

   4 - Invisible, Large
   6 - Invisible, Small

   9 - Zelda's Lullaby, Large
   A - Sun's Song, Large

Switch-triggered chests

   3 - Falling, Large
   8 - Falling, Small
   B - Appearing, Large

Unlike most objects, chests don't specify the switch they're attached to in their actor variable. To attach a chest to switch XX, set the chest's Z-rotation to XX.  If using UoT for this, remember that the switch number XX is in hexadecimal, while UoT accepts angles in decimal.

Switch-triggered chests are rising-edge triggered only.  Falling chests will land on the first solid thing they encounter.  When loading a room containing a falling chest after its switch has been set, it will be on the first solid thing below it.



Standard Door
0009 0080 + 00XX, Group 0002

This is a small key door.  It triggers on neither edge.  The flag will be set when the door is opened for the first time.  If you don't want to attach the door to a flag, use 003F as your actor variable.



Lifting Door
002E 0YY0 + 00XX, Group 0002

YY = door type
   08 - barred on one side
   18 - barred on one side, barred to clear trigger on the other
   2C - locked door
   14 - boss door

Lifting doors need a bit more looking in to, as the full functionality of YY is unknown. Barred doors trigger on both edges, locked doors on neither.  To attach to the clear trigger instead of a switch flag, use XX = -1.  The boss door should always be attached to flag 14.  If you just want a normal lifting door, use 003F as the actor variable.



Unlit Torch
005E 10XX + 0040*N, Group 00A4

N - number of torches that need to be lit to set the flag.

Unlit torches have an internal timer that causes them to go out after a certain period of time if the flag has not been set.  If the flag is set, the torches will all be lit and stay lit.  The torches immediately go out when the flag is cleared, and will all immediately ignite when the flag is set.

Golden Torch Stand
005E 03XX, Group 00A4

Triggers on both edges.  Is lit when switch is set, goes out when switch is cleared.



Flame Circle
0049 ZYXX, Group 0001

Z - Behavior of flame circle, see Actor List
Y - Camera movement on rising edge.  Use F if unsure.

Flame circles are rising-edge triggered only.  Timed flame circles clear their switch flag when time runs out.



Hookshot Tower
012D XXY1, Group 011C

Y = ??I?
   I = 1 - frozen in ice

Switch-triggered hookshot towers are rising-edge triggered only.  They start with their base 100 units below their specified actor position, then rise 100 units when triggered.  A hookshot tower is exactly 100 units tall.

If you don't want the tower to be switch-triggered, use FFC0 as the actor variable, or FFE0 for a frozen one.



Transparent Platform
01B4 XX01, Group 01B4

Transparent platforms trigger on rising and falling edges.  They are present when the flag is set and absent when the flag is cleared.

Transparent Platform Timer
01B4 XX02, Group 01B4

Rising edge triggered only.  I have only tested this with XX = 39.  When triggered, the timer sets both 38 and 39, and clears both when the timer runs out.

This list will be continued with other general actors and dungeon specific actors, but I think this is a good starting place.
« Last Edit: December 02, 2010, 04:00:48 AM by petrie911 » Logged
Pages: [1] 2
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.20 | SMF © 2013, Simple Machines Valid XHTML 1.0! Valid CSS!