Jump to content

Sage of Mirrors

Member
  • Posts

    255
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by Sage of Mirrors

  1. n6b1koy.png

     

    This is a text editor for the Master Quest debug version of Ocarina of Time. It has the ability to add and remove messages from the list, and it automatically adjusts for bigger or small amounts of text in a message. No more space limitations due to hex editing!

     

    Currently, it can only open a big endian debug ROM, and it can save to another ROM, to a PPF patch, or to two files (StringData.bin, the actual string data, and MessageTable.tbl, the message list). There are minor improvements to be made, but it is unlikely that any major changes will be made to the program.

     

    Github Link: https://github.com/Sage-of-Mirrors/Ocarina-Text-Editor

     

    Current Release: https://github.com/Sage-of-Mirrors/Ocarina-Text-Editor/releases/tag/v1.0.2

     

    Wiki: https://github.com/Sage-of-Mirrors/Ocarina-Text-Editor/wiki

    • Like 2
  2. Well, here's a document that I've compiled on the JFVB object. It's the only entirely unique object type, as the others share the same structure. JFVB does not. Enjoy:

     

     

    JFVB holds data used for animated actions. Typically these actions are only related to the camera (JCMR), but it's possible that

    other objects could use it, too.
     
    Different commands utilize the entries in the FVB object for different things. The animated Field of View and Roll commands use
    1 entry, while the animated camera and target positioning commands use 3 - one entry for each axis (X/Y/Z).
     
    JFVB consists of a header that is 18 (hex)/20 (dec) bytes long, and a variable number of entires, which themselves 
    are variably sized. The header begins at offset 0x20 (hex)/32 (dec) in an STB file, and follows this format:
     
    /*+0x00*/ int totalSize; //size of the object from 0x00
    /*+0x04*/ string "JFVB";
    /*+0x08*/ string "FVB";
    /*+0x0C*/ Unknown; //shouldn't worry about it, it's the same everywhere
    /*+0x10*/ int fvbSize; //size of the section from 0x08. I dunno, it's weird
    /*+0x14*/ int numEntries;
     
    The entries themselves seem to mimic the other objects in that they are technically composed of commands, but the structure
    is the same across nearly all of them. The first entry in an FVB object is at 0x18 in the object, or 0x38 in the entire STB file.
    These fields are common for all entry types:
     
    /*+0x00*/ int entrySize;
    /*+0x04*/ int16 entryType;
     
    The entry type seems to determine something, but I don't know what yet. The majority of the entries have a type of 5, but some
    have a type of 6. There are major differences in commands between the two.
     
    In a type 5 entry, there are typically 3 commands - animLength, interpType, and data. While these follow the command syntax
    found in the other object types, I will forego explaining it here in favor of doing it elsewhere where it would be more
    useful. The offsets of the commands are as follows:
     
    +0x08 animLength
    +0x14 interpType
    +0x1C data
     
    animLength is C (hex)/12 (dec) bytes long, and seems to give an inconsequential estimate as to how long the animation is in-game.
    The relavent floating point data can be found at 0x08 relative to the command, or 0x10 relative to the start of the entry itself.
     
    interpType seems to be how the engine interpolates between the points. The default value is 3, which is a smooth spline
    running through each of the coords. The data here begins at 0x04 relative to the start of the command.
     
    data holds what JFVB was designed to hold - floating point coords. It is structured like so:
     
    /*+0x00*/ int16 loadLength; //length of the command starting from 0x04
    /*+0x02*/ int16 commandType; //this just indicates that it holds the coord data
    /*+0x04*/ int numCoordPairs;
     
    Coords start at 0x08 relative to the command, and 0x24 to the entry. They are 8 bytes long. The first 4 are the
    interpolation timestamp, and the last four make up the actual coordinate.
     
    The timestamp controls when the engine interpolates to the coordinate that it preceeds, which controls the speed
    and smoothness of the animation. They act as a sort of timeline, giving the engine at what time since the animation started
    it should be at the coord. The data is length in seconds, encoded in floating point.
     
    Every entry is padded at the end by 4 null bytes. These are counted in totalSize and fvbSize, but NOT in the data command.
     
     

     

     

    • Like 1
  3. "Loading zones" as in, say, dungeon entrances/exits? I'm gonna go ahead and guess that's some exit-enabled collision polygons, the same way the N64 Zelda's work.

     

    I hadn't looked very deeply into collision in WW, but if it's similar to OoT/MM, then you've got a collision polygon type that's set to trigger one of the exits defined elsewhere (in this case presumably in the SCLS chunk), as well as any number of polygons that are set to be of that type. If you step onto one of those polygons in-game, it triggers the transition to whatever map is defined by that exit.

     

    Hope that helps any, even if it's just a theoretical idea.

    It works similar to that, yeah. LordNed and I have just about completely decoded the collision format. It's some other technical things (and laziness/free time shortages/lack of coding experience on my part) that have stopped us from making an obj2dzb converter. It would be fairly simple - no texture data needed. The only data we'd need from the model is the vert and face data. Everything else can be automatically generated or handpicked by the user.

     

    My STB research is just about complete. At one point, I had a version of Wind Viewer that could view the basic structure of an STB file:

     

    ByoFQnn.png

     

    I never got around to finishing it, as I believe I messed up my only copy of Wind Viewer's source (I'll have to grab it again and re-do this), but this is how I hope to get STB files editable. Also on a side note, the "Unknowns" in that list are known now.

    • Like 2
  4. Nothing new to report in the past few months. I've still been documenting the STB files, but I'm having trouble with them. I can't figure out how the engine assigns JACT chunks to the models in the archive. I originally thought that it had to do with the order both the models and the JACT chunks are in the RARC/STB file (As in the first model gets the first JACT, the second model the second JACT, ect.), but after several attempts to put the King of Hyrule into the title screen's STB file, I'm starting to think that that's not the case. Could anybody lend me a hand in looking at these files?

     

    Also, another thing I've been doing is trying to trace where the Wind Waker direction/notes are stored. However, I haven't had much luck yet. I've looked at the code in the .dol, but since I can't read PPC that well, I couldn't find anything. Having custom Wind Waker songs is a must. I'd appreciate some help in this area, too.

     

     

    Ha! I did it!

     

    Posted Image

     

    What this is is the King of Hyrule's model and a wait animation inserted into the archive of the title cutscene, Demo51. I found out that model assignment is actually a command in the JACT section, 04 07 39. While I was able to get this working, I'm still not entirely sure how it works... I know 04 07 39 assigns a JACT to a model, but the source of the argument for that command that decides which model to use isn't clear. What I had to do to make the King work was cycle through values starting at 00 to find the ones that the game wouldn't error on. I still have to look into it, but I believe it has to do with the files' entry in the RARC header - that is, the chunk for those files that determines their size and location in the archive. 

  5. Got some info on some of the chunks in cutscene files.

     

    JSND controls sound effects and music. This is the header:

     

    xx xx xx xx 4A 53 4E 44 00 00 00 zz yy yy yy yy yy yy yy yy

    Where:

     

    X = Size of JSND chunk

    Z = Unknown

    Y = ASCII ID of chunk ("SE" and "sound" are common names here. I don't think it matters.)

     

    The actual entries are surprisingly regular, and are 0x18 bytes long.

     

    02 00 00 xx 80 00 00 10 00 04 07 99 yy 00 zz zz 00 04 05 C2 00 00 00 00

    Where:

     

    X = Delay before sound is played

    Y = Type of sound: 00 for a sound effect, 80 for a sequence file, and C0 for a stream

    Z = Index of desired sound effect/sequence file/stream

     

     

    JMSG is similar, and deals with text.

     

    02 00 00 xx 80 00 00 08 00 04 08 59 yy yy yy yy

    Where:

     

    X = Delay before displaying string

    Y = Entry number of desired string

     

    There's usually a second portion to JMSG, called "control." This section deals with what the cutscene should do when text is displayed - namely, if it should wait until the text box is closed to continue the scene. Unfortunately, it's not that simple, and the only thing I've really got is the entry length and the variable:

     

    02 00 00 xx 04 00 00 01

    Where:

     

    X = The variable. What this actually does isn't quite clear. Changing it to a high value causes some of the strings to fill one text box and overflow it while the cutscene plays without stopping, while a lower value tends to stop the text box from displaying at all. My theory at the moment is that this value is related to something in the Jstudio chunk, which I haven't gotten around to digging into yet.

     

     

    JPTC deals with particle effects. It's actually pretty simple. Here's a sample entry:

     

    00 00 00 74 4A 50 54 43 00 00 00 xx xx xx xx xx xx xx xx xx xx 00 00 00 02 00 bb bb 80 00 00 34 00 07 06 18 yy yy yy yy yy yy 00 00 00 0B 06 38 zz zz zz zz zz zz zz zz zz zz 00 00 00 04 06 42 00 00 00 01 00 04 08 99 aa aa aa aa 00 04 05 C2 00 00 00 00 02 00 00 5E 80 00 00 10 00 04 04 02 00 00 00 00 00 04 05 E2 00 00 00 00 02 00 00 08 00 00 00 00

    Where:

     

    X = Unique ASCII ID of the entry

    Y = Actor within STB file associated with particle effect

    Z = Bone in actor to attach the effect to

    A = Particle effect ID

    B = Delay before effect is rendered

     

    I was able to attach a particle effect to Grandma by simply changing Y to "Ba1" and Z to "neck:"

     

    Posted Image

     

    There are probably more variables in there, such as what particle bank to call from.

  6. I think I may be onto something with Unknown2!

     

    Look at this entry, from Minihyo:

     

    01 00 FF FF 00 01 00 08 00 1E 00 1F 00 2D 00 36 00 3E 00 57

    I wanted to see what would happen if I changed 01 00 to 01 01, and I did. It didn't make the room hang - it only made the walls (not the tops) of the ice slides nonsolid. This was interesting me, so I poked around a bit in the geometry sections of the file. Faces didn't seem to do anything, so I set my sights on vertices.

     

    As it turns out, vertices 01 and 08 are parts of the slide walls! This might mean that Unknown2 defines wall surfaces, and/or climbable ledges by vertex. I still need some validation, but I can't really get that until Lord Ned can log back on. We might have finally figured out what Unknown2 does.

  7. Lord Ned and I have documented Unknown3 of the .dzb files, which turned out to be surface properties.

     

    They're always in this format:

     

    07 FF xx FF 00 yy yy FF FF FF FF 00 00 00 00 00

    Where:

     

    x = Walking sound effect/Item interaction (what happens when you hit stuff with the sword, arrows, ect.)

    y = Surface type (Solid ground, lava, ice, ect.)

     

    Lord Ned and I believe that each face contains its component vertices and two indexes. One of these indexes seems to point to a group in Type_t (the last section of the file), while the other points to a surface property.

     

     

    Now, we're stuck. The last completely unknown section, Unknown2, makes absolutely NO sense. For an example, take the first few entries from the .dzb for Minihyo, the minidungeon inside Ice Ring Isle:

     

    01 00 FF FF 00 01 00 08 00 1E 00 1F 00 2D 00 36 00 3E 00 57
    01 00 00 00 FF FF 00 02 FF FF 00 03 00 04 00 05 00 06 00 07
    01 01 00 01 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    01 01 00 01 00 01 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    01 01 00 01 00 02 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    01 01 00 01 00 03 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    01 01 00 01 00 04 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    01 01 00 01 00 05 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    01 00 00 00 00 09 00 10 00 11 00 12 00 13 00 14 00 15 00 1D
    01 00 00 08 FF FF 00 0A 00 0B 00 0C 00 0D 00 0E FF FF 00 0F
    01 01 00 09 00 06 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    01 01 00 09 00 07 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    01 01 00 09 00 08 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    01 01 00 09 00 09 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    01 01 00 09 00 0A FF FF FF FF FF FF FF FF FF FF FF FF FF FF

    Here's what we do know:

    • Entries that begin with 01 00 have valid data from byte 5 to the end, while those that start with 01 01 only have valid data in the 5th and 6th bytes
    • Changing the data causes the game to behave oddly, such as triggering autojump at the top of a very shallow slope and causing water to force the room to reload as if Link fell into a bottomless pit
    • Forcing the engine to read 1/2 the number of actual entries (by changing the count in the header) causes various things, such as the water, some walls and the dragon statue in Minihyo to become nonsolid
    • The game refuses to load the room if the entry count drops below a certain point
    It's a mystery as to what this does right now. Based on the findings of our poking around, the section is important to collision. Perhaps it defines groups within the Type_t groups? As I understand it, .bmd and .bdl files have something similar - packets of primitives organized into batches.

     

    Type_t is also a mystery. It's very sensitive - most of the time, changing the values for a section either breaks that group's collision or causes the room to hang. In one case, giving one group, "Zou," (which appears to be the dragon statue in Minihyo) the values for "Water_00" caused the water collision to become solid. What caused this is unknown.

     

    Right now we're stumped. Can any of you guys help us figure either of these out?

  8. Lord Ned, when you edited K_test02, did you have to rotate the model at all to get it to render in the right position? Or does OBJ2BDL convert the model as-is, with no rotation? I'm asking because I want to make a custom test room to test out OBJ2BDL. Also, what was the scale that you edited the model in? The dumped models from BMDView2 are huge when imported into Blender, so I want to see if I actually have to make custom maps that big.

  9. Nice job with the model edit. I need to look into those programs soon.

     

    Custom collision is the one thing that we really need now that it seems that custom models with textures are possible. If you could get a collision converter, that would be sweet!

     

    Also, Xdan, I've been meaning to ask you - can you update WindViewer to make some of the stuff we've documented editable? I'm mainly looking at SCLS and TRES (being able to edit them without a hex editor would be super handy), but maybe some of the .dzs entries, too...? I did put some of them on the wiki page, but it's been a while since I've looked at it, so I'm not sure exactly what I've put in. Ah, EVNT (.dzs) has also been documented well, I believe.

  10. I've been researching what's in the SCOB and SCOx sections of the .dzr files. What I've discovered are things that I'm going to name "tags" due to the fact that many of them have the word "tag" in them. All tags follow this format:

     

    xx xx xx xx xx xx xx 00 yy yy yy yy zz zz zz zz zz zz zz zz zz zz zz zz zz FF 00 00 aa aa aa aa bb bb bb FF
    
    

    Where:

     

    x = Name of Tag

    y = Variable Field 1 (what variables are in here depends on the tag name)

    z = Coordinate data (pretty sure)

    a = Variable Field 2 (Doesn't seem to be used a lot)

    b = Collision x, y and z

     

    Note that this could be off a bit. Wind Viewer seems to make more fields for tags than there actually are.

     

    Here's a list and description of the tags I've researched so far.

     

     

    Name: ky_tag0/1/2

     

    Purpose: Controls weather conditions and forest particle effect

     

    Variable Field 1:

     

    xx xx yy zz

    x = Unknown

    y = Weather condition/particle effect

    z = Type/intensity

     

    Variable Field 2: N/A

     

     

    Name: TagEv

     

    Purpose: Calls an event from the EVNT chunk of a .dzs. It can be used to call regular cutscenes, too, as long as the cutscene is referred to in both the area's event_list.dat and .dzs.

     

    Variable Field 1:

     

    xx FF yy yy

    x = Event index in .dzs (starting from 0)

    y = Unknown. Seems to play a part in how the event is called. Needs more investigation.

     

    Variable Field 2: N/A

     

     

    Name: TagMsg

     

    Purpose: Calls an event from the EVNT chunk of a .dzs, with the added ability to display text. It works the same way as TagEv.

     

    Variable Field 1:

     

    xx FF yy yy

    x = Event index in .dzs (starting from 0)

    y = Unknown

     

    Variable Field 2: Message ID of text

     

     

    Name: AttTag/AttTagB

     

    Purpose: Makes Link like in the direction of the tag.

     

    Variable Field 1:

     

    xx xx xx xx

    x = Unknown

     

    Variable Field 2: N/A

     

     

    Name: TagIsl

     

    Purpose: Unknown. It's found with a few of the major islands, such as Greatfish and Dragon Roost. The ID it uses to identify the islands isn't the normal island ID. When the ID is changed, the tag teleports Link to the specified island. Only three of them seem to work, though - 01, 02 and 03, which are Dragon Roost, Forest Haven and Greatfish, respectively.

     

    Variable Field 1:

     

    xx FF xx yy

    x = Unknown

    y = Nonstandard Island ID

     

     

     

    There are a ton of other tags that need documented, but they will get done sooner or later.

  11. (If I'm not allowed to do this, please tell me and I'll think of something else.)

     

    *I run next to lilyhawk, and point my rifle to warden and robed man*

    "Yeah, you better just give up, or me and my friends will..."

    Before I manage to finish my sentence, the black robed man swings his arm and casts some kind of magic spell, and my rifle flies through air next to his feet. He looks at the warden.

    "As you wish, my lord.", says the warden, and he steps forward. He is wearing a plate armor and he is wielding an enormous hammer.

    "After I'm done with you, I'll feed your corpse to prisoners!", he says, and he dashes forward.

     

    The silhouette of a man appears in a nearby window. It raises an arm, and a ripple of energy shoots out towards the warden in an attempt to stop him.

  12. Over the past few days I've been working on a sort of hack that compiles all that we know about TWW. This is the first release of that hack.

     

    http://www.mediafire...t7jcg9tjvdcyyxw

     

    From the Readme:

     

    *The Legend of Grandma*

     

    This is a small hack of The Legend of Zelda: The Wind Waker. It is mostly to demonstrate what

    we have learned so far in the realm of how The Wind Waker works.

     

    Here are the things that are present in this hack:

     

    -Actor placement

    -Waypoint placement

    -Text editing

    -Event editing

    -Treasure Chest editing

     

    Now, due to issues encountered regarding the making of a patch, this hack

    is being distributed as its component files. In order to place these files in the ISO, you must download GCRebuilder,

    which can be found here:

     

    http://www.romhackin.../utilities/619/

     

     

    A set of instructions for compiling and starting the hack are in the Readme, as well. Xdaniel and Lunaboy (the creator of the arc packer I used) have both been credited.

     

    Here are some screenshots:

     

     

    Posted Image

     

    Posted Image

     

    Posted Image

     

     

     

    Keep in mind that this is a work in progress. I'm still trying to figure out how certain events (like the cutscene that starts when you first enter the forest) work with the use of Tags. Once that has been settled, though, I will begin editing the forest and lengthening the hack.

     

    Now, I'm not sure how this will work on a PAL ISO. Replacing the bmgres.arc that is in the .7z might work, but it also might not due to differences.

     

    All in all, this is pretty rough, so there might be an improvement in the future.

  13. Well, anyway.

     

    While digging through the .dol, I discovered a lengthy list of names starting at 0x36F818. It looks to hold all of the valid actor names, as well as DZS and DZR header strings (PALE and ACT, for instance) and a few things from STBs. What could this be for? Could it be a reference table for the game? What about a remnant of an in-game editor? I haven't looked into it much, but I will try changing stuff and see if it messes with anything.

     

    I see!

     

    The list is a set of entries 0xC bytes long. The last three bytes are typically the variables. When I copied the variables from one boss (bwds) and put them into Gohdan's entry (bst), the result was that the game tried to load bwds (it loaded both the .rel and the actor's .arc), but there were severe problems with the registers and heap size and such. So this list is used by the game; in fact, it's probably how the game identifies actors.

     

    Alright. In the case of the DZS header strings, the variable is actually the offset in RAM of the code that reads or inits the section.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.