/* The Wild Arms Music Driver */ ---Technical Notes--- The Wild Arms music driver is a little different to what you would think would be in a game. You would think it would be sensible to have a LoadMusic function which can load any music from the game (eg. by some index number) and play it using some other function. Nearly every game uses a system like that. Wild Arms, however, just to be annoying, ties different music to different stages. There are 127 stages contained within cdrom://bin/cdstg.bin, which is 76021760 (0x4880000) bytes large. Weirdly enough, each stage occupies exactly 593920 (0x91000) bytes, except for stage 24, which occupise 1187840 (0x122000) bytes (or maybe there just isn't a stage 25?). I must say, this is very sloppy storage on behalf of the programmers, as there is a significant amount of free space in each "stage block". On a side note, the "debug menu" gameshark cheat code (8012F8BC 0009) allows you to warp to all 127 stages. The stages are listed, in order, but the list skips stage 25 (which is why there are only 127 stages and not 128). Wild Arms has some stage loading function which *always* loads the 0x91000 byte stage block into 0x8014F000. Each stage contains one or two VAB headers, one to six (or possibly more) SEQs, one or two VAB bodies as well as a bunch of other stuff. Where there is only one VAB body/head, the VAB contains the sound effects. Where there are two VAB bodies/heads, one VAB contains the sound effects and the other one contains the samples for music. Of course, the problem is, because the music loading function can only load music -from the current stage-, the stage block has to contain all the music that could possibly play in that stage. This results in a total of over 300 SEQs in cdstg.bin! (Most are duplicates.) At the start of each stage block there is a 64-byte "header". The last four bytes seem to be "Sony". Following the header is a bunch of offsets. I think the game programmers took shortcuts here, because these offsets point into the 0x8014F000 - 0x801E0000 range. By subtracting 0x8014F000 off the offsets, you can get an offset into the current stage block. The offset at 0x84 points to "pBAV", but it is not what we're looking for. The offset at 0x80 points to an array of signed longs. The entries in this array are added to the offset pointed to by offset 0x80. For example, stage 0 has entries 0x0, 0xC20, 0x5240, 0x6138, 0x6E74 and 0xFFFFFFFF. (Note that -1 (0xFFFFFFFF) terminates the list.) The pointer at offset 0x84 points to 0x80155314, which is 0x6314 from the start of stage block 0. That means there's stuff at 0x6314, 0x6F34, 0xB554, 0xC44C and 0xD188. 0x6314 and 0x6F34 point to "pBAV", indicating that those are the two VAB headers. The other three point to five bytes preceding "pQES". Actually, they point to "compressed SEQ" data. It seems this data has the format: unsigned long uncompressed_length char something=0xEF char seq_magic='pQES' ***compressed data*** We don't really need to worry about it, since the game provides a decompression routine for us. So we have the SEQ data and VAB headers. Now we need the VAB body/bodies. Well, at 0x59000 in each stage block is a structure similar to the one pointed to by the pointer at offset 0x80. It will contain either one or two offsets from 0x59100. For example, stage 0 has entries 0x0 and 0xF730. This means there is a VAB body at 0x59100 and 0x68830 from the start of the stage block. In fact, the first VAB head/body pair is always sound effects. Where there is only one head/body pair, there is no music. Note that stages 0x4A and 0x4B have SEQ data, but they don't work. Warping to those stages, I found out that they play streamed music (the "trailer" when you leave it at the "press START" screen for a while and the "cutscene" right after (or during) the opening credits). The driver is pretty ordinary, a SEQ/VAB driver recognizable by IDA Pro. The way the SEQ/VAB functions are called is of course weird, oweing to the format detailed above. Originally, I just patched (NOPed) out stuff to get a working driver, but it was causing some processing overhead, so I just created a new main() and called the SEQ/VAB functions manually. On a last note, the SEQ magic identifier doesn't always mean there is a complete SEQ file there. It seems there is a certain amount of space allocated in a stage block for SEQ data. If the SEQ data doesn't use it all up, the remaining space is padded with the original SEQ data over and over again (why nulls weren't used instead stumps me). Therefore, all occurrences of "pQES" aren't actually music. If you're wondering why the .minipsf files are all so small, it's because they contain no data themselves! They reference to a specific stage, a "music selector" and of course the driver. As I said before, a stage may contain up to five or six tracks, so a music selector selects which one to play. If you view the raw tag (click on "Raw Mode..." button in "File Info" - this only applies to the Winamp version of Highly Experimental), you can see the stage (eg. "_lib3=stg1D.psflib") and music selection number (eg. "_lib2=wasel00.psflib"). Note that "global.psflib" is sort of a stage; it contains music that applies globally to the whole game (eg. battle music and victory music). The "global" music is not stored the same way as stage music, but I converted it into the stage music arrangement (with all the weird offsets 'n stuff) to make things easier for the driver.