I'm new to QuickBMS so please go easy on me.
I'm writing a script to extract the Rayman 3 and Rayman Arena for GC audio files at the moment. This script will also extract Rayman 3 HD (that came out yesterday) and Rayman 3 for PS2's audio files if I make some small modifications. I have analyzed the files as you can see in the topic I linked to and it seems to be a very complex file system. To sum it up:
- A HXG file is divided in blocks with different identification strings.
- Blocks starting with the identification string "CGCWaveFileIdObj" contain the audio (or reference to external file) and a temporary name (8 bytes) for that audio
- Blocks starting with "CGCWavResData" contain either one, or multiple references to multiple audio files' temporary names, and each block contains one number, the counter. If there are multiple temporary names, there is always a string before the temporary name indicating the language of the audio. The files are always the same, only in a different language.
- Blocks starting with "CEventResData" contain the counter and the real name of the audio file. For a counter, there isn't always a CEventResData block. For some of the CEventResData, you actually have to look inside another file which has the same basename but the BNH extension.
I attached my script so far, if you want to take a look at it. It's huge, but then again, the format is also huge. If you have an idea to make it shorter/better or to make it work, please don't hesitate to post it.
To test it, use the example BNH and HXG files below:
Example bnh file (Knaar_60.bnh): http://www.box.com/s/uajda81un694j6ltk9bo
Example hxg file (Knaar_60.hxg): http://www.box.com/s/v0nbnfnpolenb4tome4m
Code: Select all
# Rayman 3 *.HXG script (Gamecube) # script by Droolie for QuickBMS http://quickbms.aluigi.org debug endian big get LAST_OFF long for FindLoc OFFSET STRING "CGCWaveFileIdObj" 0 "" math OFFSET -= 4 if OFFSET < LAST_OFF goto OFFSET 0 get IDSZ long 0 getdstring IDENT IDSZ 0 get TMPNAME longlong 0 get DUMMY long 0 get DUMMY long 0 get DUMMY long 0 get EXT long 0 set NAME "" set LANG "" if EXT == 1 get EXTSZ long 0 getdstring EXTF EXTSZ 0 set NAME "[EXT] " endif savepos OFFSET 0 get RIFF long 0 get RSIZE long 0 math SIZE = RSIZE math SIZE += 8 goto 0 0 FindLoc OTHEROFF longlong TMPNAME 0 "" goto OTHEROFF 0 get TMPNAME longlong 0 getdstring LANGBIT 2 0 if LANGBIT != "" set LANG "_" string LANG += LANGBIT endif for goto OTHEROFF 0 getdstring CHECKSTRING 13 0 if CHECKSTRING ^ "CGCWavResData" break else math OTHEROFF -= 1 endif next savepos ISTHISCOUNT 0 get COUNT double 0 goto 0 FindLoc COUNTOFF double COUNT 0 "" if COUNTOFF == ISTHISCOUNT goto ISTHISCOUNT 0 get CUUID1 long 0 get CUUID2 long 0 set LOOK CUUID2 String LOOK += " )" open FDDE BNH 1 goto 0 1 FindLoc LOOKOFF String LOOK 1 "" goto LOOKOFF FindLoc LOOKOFF String "file " 1 "" math LOOKOFF += 5 goto LOOKOFF FindLoc NAMESZ String " " 1 "" math NAMESZ -= LOOKOFF getdstring ADDNAME NAMESZ 1 else for goto COUNTOFF 0 getdstring CHECKSTRING 13 0 if CHECKSTRING ^ "CEventResData" break else math COUNTOFF -= 1 endif next get CUUID longlong 0 get DUMMY long 0 get NAMESZ long 0 getdstring ADDNAME NAMESZ 0 endif goto OFFSET 0 String NAME += ADDNAME String NAME += LANG log NAME OFFSET SIZE 0 else break endif next