Video game file translation tools
gctools is a set of tools for reading and translating video game files. These tools can understand:
The macOS releases on the GitHub repository are built for the latest version of macOS on an arm64 (Apple Silicon) system.
The Windows releases on the GitHub repository are built for the amd64 architecture and are dynamically linked with Cygwin DLLs, so you'll have to install some parts of the Cygwin runtime environment to use them. See the Building section for how to install the dependencies.
On Windows, install the dependencies via Cygwin (https://www.cygwin.com/install.html). During the step where it asks which packages to install, set View to "Full", then search for each of these packages and change "Skip" to the latest version available:
On macOS, install the dependencies with Homebrew or MacPorts. For example, with Homebrew:
brew install cmake libsamplerate openal-soft
On Linux, install the dependencies with apt-get:
sudo apt-get install cmake libsamplerate-dev libopenal-dev
After the dependencies are installed (on any platform), do this:
cmake . && make
in the root directory of gctools. Executables will be generated for each tool. These tools all build and run on macOS and Ubuntu, but are untested on other platforms.afsdump - extracts all files in an AFS archive to the current directory. Works with AFS archives found in several Sega games.
mkdir out && cd out && afsdump ../archive.afs
gcmdump - extracts all files in a GCM file (GameCube disc image) or TGC file (embedded GameCube disc image) to the current directory. You can force formats with the --gcm or --tgc options (by default gcmdump will try to figure out the file format itself).
mkdir out && cd out && gcmdump ../image.gcm
gcmasm - generates a .gcm image from a directory tree. Ideally the source data would be a directory tree produced by gcmdump, but if not, you can provide the header data on the command line instead.
gcmasm extracted_image_dir
(produces extracted_image_dir.gcm)gsldump - extracts all files in a GSL archive to the current directory. This format was used in multiple versions of Phantasy Star Online for various game parameters.
mkdir out && cd out && gsldump ../archive.gsl
gvmdump - extracts all files in a GVM archive to the current directory, and converts the GVR textures to Windows BMP files if they use pixel formats that gvmdump understands (which is not all of them). Also can decode individual GVR files outside of a GVM archive.
mkdir out && cd out && gvmdump ../archive.gvm
rcfdump - extracts all files in a RCF archive to the current directory.
mkdir out && cd out && rcfdump ../archive.rcf
pae2gvm - extracts the embedded GVM from a PAE file. The decompressed PAE data is saved as
pae2gvm file.pae
prsd - decompresses data in PRS, Yay0, and Yaz0 formats, or compresses data in PRS format.
prsd -d < file.prs > file.bin
prsd < file.bin > file.prs
prsd --yay0 -d < file.yay0 > file.bin
prsd --yaz0 -d < file.yaz0 > file.bin
smsdumpbanks - extracts the contents of instrument and waveform banks in AAF, BX, or BAA format. Games using this format include Luigi's Mansion, Pikmin, and Super Mario Sunshine. Produces text files describing the instruments, uncompressed .wav files containing the sounds, and .bms files containing the music sequences. Before running this program, do the steps in the "Getting auxiliary files" section below.
mkdir sms_decoded_data && smsdumpbanks sms_extracted_data/AudioRes sms_decoded_data
smssynth - synthesizes and debugs music sequences in BMS or MIDI format. There are many ways to use smssynth; see the next section.
modsynth - synthesizes and debugs music sequences in Protracker/Soundtracker MOD format. Run it with no arguments for usage information.
smssynth deals with BMS and MIDI music sequence programs. It can disassemble them, convert them into .wav files, or play them in realtime. The implementation is based on reverse-engineering multiple games and not on any official source code, so sometimes the output sounds a bit different from the actual in-game music.
Before running smssynth, you may need to do the steps in the "Getting auxiliary files" section below. Also, for sequences that loop, smssynth will run forever unless you hit Ctrl+C or give a time limit.
Once you have the necessary files, you can find out what the available sequences are with the --list
option, play sequences with the --play
option, or produce WAV files from the sequences with the --output-filename
option.
Here are some usage examples for GameCube games:
smssynth --audiores-directory=luigis_mansion_extracted_data/AudioRes --list
smssynth --audiores-directory=sms_extracted_data/AudioRes k_bianco.com --disable-track=15 --output-filename=k_bianco.com.wav --time-limit=240
smssynth --audiores-directory=sms_extracted_data/AudioRes k_bianco.com --play
smssynth --audiores-directory=pikmin_extracted_data/dataDir/SndData --play cave.jam
smssynth can also disassemble and play MIDI files. This was implemented to synthesize the Classic Mac OS version of SimCity 2000's music using the original instruments, which wouldn't play on any MIDI player I tried. Some other Classic Mac OS games use the same library (SoundMusicSys), and most of these games' music resources now work with smssynth as well. To play these sequences, provide a JSON environment file produced by resource_dasm. Make sure not to move or rename any of the other files in the same directory as the JSON file, or it may not play properly.
SoundMusicSys environments have a lot of options, which resource_dasm packages up into a JSON file. You can produce an appropriate JSON file by running resource_dasm like resource_dasm "Creep Night Demo Music" ./creep_night.out
. This will produce a JSON file for each SONG resource contained in the input file.
After doing this, you can play the songs with (for example) smssynth --json-environment="./creep_night.out/Creep Night Demo Music_SONG_1000_smssynth_env.json" --play
. The --disassemble
and --output-filename
options also work when using JSON files (like for JAudio/BMS), but --list
does not.
I've tested smssynth with the following GameCube games that use JAudio/BMS and assigned an approximate correctness value for each one:
--disable-track=15
to silence them.Classic Mac OS games that use SoundMusicSys currently fare much better than JAudio games:
resource_dasm --index-format=mohawk
to get the MIDI files from NISMIDI.dat and MIDISnd.dat and use the template JSON environment generated by resource_dasm from the game application. That is, provide both --json-environment and a MIDI file on the command line.Luigi's Mansion should work without any modifications. Just point --audiores-directory
at the directory extracted from the disc image.
You'll have to copy msound.aaf into the AudioRes directory manually to use the Super Mario Sunshine tools. To do so:
prsd -d --yaz0 < nintendo.szs > nintendo.szs.rarc
).You'll have to manually extract the BARC data from default.dol (it's embedded somewhere in there). Open up default.dol in a hex editor and search for the ASCII string "BARC----". Starting at the location where you found "BARC----", copy at least 0x400 bytes out of default.dol and save it as sequence.barc in the SndData/Seqs/ directory. Now you should be able to run smsdumpbanks and smssynth using the Pikmin sound data. --audiores-directory
should point to the SndData directory from the Pikmin disc (with sequence.barc manually added).
After extracting the AudioRes directory, rename the Waves subdirectory to Banks.
The sequences are stored in a compressed RARC file, and don't appear to be listed in the environment index. (This means --list
won't work and you'll have to specify a sequence file manually.) To get the sequences:
prsd -d --yaz0 < Seqs/Z2SoundSeqs.arc > .Seqs/Z2SoundSeqs.arc.dec
rarcdump Seqs/Z2SoundSeqs.arc.dec
Like Twilight Princess, the sequences are stored in a RARC archive, but this time each individual sequence is compressed, and the index is compressed too. Fortunately they're all Yaz0:
prsd -d --yaz0 < SMR.szs > SMR.baa
rarcdump Seqs/JaiSeq.arc)
ls Seqs/JaiSeq.arc_dir/szs/*.szs | xargs -I {} bash -c "prsd -d --yaz0 < {} > {}.bms"