rsrcdump converts Classic Mac OS resource forks to JSON. It will also convert some common resource types to formats usable in modern tools:
Resource type | Converts to |
---|---|
cicn | PNG |
icl4, icl8, ICN#, ics#, ics4, ics8 | PNG |
PICT | PNG (raster only – see known limitations) |
ppat | PNG |
snd | AIFF-C (see note on AIFF-C files below) |
SICN | PNG |
STR, TEXT | UTF-8 text (stored in index.json) |
STR# | Array of UTF-8 strings (stored in index.json) |
Other resource types | Hex dump or structured JSON |
You can also use rsrcdump to create a resource fork from JSON input, enabling you to edit resource forks on a modern setup without fiddling with ResEdit.
Python 3.10 or later.
Note that macOS currently ships with Python 3.9, which is too old; you can install a more recent version via Homebrew:
- Install Homebrew
- Run:
brew install python
First, ensure you're using Python 3.10 or later with: python3 --version
To install or upgrade:
pip3 install --upgrade git+https://github.com/jorio/rsrcdump@master
Or you can do so from the cloned repo:
git clone https://github.com/jorio/rsrcdump.git
cd rsrcdump
pip3 install -e .
To uninstall:
pip3 uninstall rsrcdump
- How to use
- Advanced usage patterns (list, include, exclude)
- Dealing with “weird” resource type names
- Generate structured JSON from arbitrary resource data
- Create resource forks from JSON files
- Use as a Python library
- Note on AIFF-C files
- Known limitations
- License
Let’s look at extracting a resource fork when your file originates from one of the following scenarios:
- Dual-fork files on modern versions of macOS
- Zip archives made with macOS, extracted on Windows/Linux (__MACOSX folder)
- Old archive formats (.bin/.sit/.cpt) extracted by The Unarchiver
- Files on a host volume shared with BasiliskII or SheepShaver
This section only applies to macOS.
On modern versions of macOS, resource forks still exist. They can be accessed by appending /..namedfork/rsrc
to a filename.
So, on macOS, let's try to extract the music from Mighty Mike. Get Mighty Mike.zip
from Pangea Software, and unzip it. Then run:
rsrcdump --extract "Mighty Mike™/Data/Music/..namedfork/rsrc"
You’ll find the resource table in Music.json
and the audio files in a folder named Music.json_resources
in the current working directory.
If you have ever come across a zip file made with macOS, you may have noticed that extracting it on Windows or Linux produces a directory named __MACOSX
. That folder contains resource forks as AppleDouble file; rsrcdump can work with those. (Note that files inside __MACOSX may be hidden for you because they start with a dot.)
For example, if you’re using Linux, get Mighty Mike.zip
from Pangea Software, and unzip it. You can then run this command to extract the game’s music:
rsrcdump --extract "__MACOSX/Mighty Mike™/Data/._Music"
You’ll find the resource table in Music.json
and the audio files in a folder named Music.json_resources
in the current working directory.
If you have an old Mac archive (such as .sit, .cpt, .bin, etc.), you can use the command-line version of The Unarchiver and tell it to keep the resource forks. They’ll appear as .rsrc
files once extracted. The Unarchiver wraps them in an AppleDouble container (which rsrcdump will automatically detect).
As an example, get bloodsuckers.bin
from Pangea Software and extract it like so:
unar -k visible bloodsuckers.bin
Then you can extract the sound effects with:
rsrcdump --extract "bloodsuckers/Data/Sounds.rsrc"
You’ll find the resource table in Sounds.json
and the audio files in a folder named Sounds.json_resources
in the current working directory.
When you share a host volume with BasiliskII or Sheepshaver, the emulator stores resource forks in a folder named .rsrc
.
For example:
rsrcdump --extract ".rsrc/SomeResourceFile"
rsrcdump --list "Bloodsuckers 2.0.1.rsrc"
If you’re only interested in a few resource types, pass them with -i
(or --include
).
For example, if you’re interested in STR
and icl8
resources only, you could use this:
rsrcdump --extract "Bloodsuckers 2.0.1.rsrc" -i STR -i icl8
Same as above, but use -e
(or --exclude
) instead of -i
.
Switches like --include
, --exclude
and --struct
work with 4-character resource type names (also known as “ResType”).
If a ResType is difficult to spell out on the command line, you can use a “URL-encoded” version of it. For example, %53%54%52%23
and STR%23
are both equivalent to STR#
.
Also note that if you pass a ResType with fewer than 4 characters, it will be right-padded with spaces. So, STR
will be interpreted as STR
.
With --struct
, you can customize the JSON output for specific resource types. These resources will appear as structured data in the JSON output instead of a raw hex dump.
--struct
takes an argument that must follow the restype:format:fields
template, where:
restype
is the four-character code of the resource type;format
is a Python struct format string describing the data layout of the struct;fields
is a list of names for each field (optional).
Adding a +
to the end of the format string signifies that this struct may be repeated multiple times in a single resource.
You can combine several --struct
switches. You can also put all of your struct specifications in a text file and pass it to rsrcdump with --struct-file
(see the included file sample-specs.txt).
Example 1: Parse a Hedr
from Otto Matic terrain files:
rsrcdump --extract \
--struct "Hedr:L5i3f4i44s:vers,items,width,height,tilePages,tiles,tileSize,minY,maxY,splines,fences,uniqueST,waters" \
EarthFarm.ter.rsrc
The JSON output will look like:
{
"vers": 134217728,
"items": 594,
"width": 176,
"height": 176,
"tilePages": 28,
"tiles": 21881,
"tileSize": 10.0,
"minY": 0.0,
"maxY": 68.0,
"splines": 26,
"fences": 46,
"uniqueST": 428,
"waters": 7,
".field13": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
Example 2: Parse a list of FnNb
(fence nub positions) from Otto Matic terrain files:
rsrcdump --extract --struct "FnNb:ii+:x,z" EarthFarm.ter.rsrc
The JSON output will look like:
[
[409, 2057],
[335, 2057],
[259, 2060],
[184, 2062],
...
]
Example 3: Parse an Otto Matic terrain file with all struct converters defined in sample-specs.txt:
rsrcdump --extract --struct-file sample-specs.txt EarthFarm.ter.rsrc
With --create
, rsrcdump can create resource files from JSON input, enabling you to edit resource forks on a modern setup without fiddling with ResEdit.
The JSON input may be structured with the help of custom struct converters.
Example: Say you have extracted one of Otto Matic’s level files, for example “EarthFarm.ter.rsrc”, to “EarthFarm.ter.json” (with --struct-file sample-specs.txt
). You’ve edited the JSON file by hand and now you want to pack it back to a resource fork so you can play your modded version. Simply run rsrcdump --create
with the JSON file as input:
rsrcdump --create --struct-file sample-specs.txt EarthFarm.ter.json -o MyModdedEarthFarm.ter.rsrc
Call rsrcdump.load(...)
which returns a resource fork that you can explore like a normal Python dict
.
>>> import rsrcdump
>>> rezfork = rsrcdump.load("Nanosaur/Data/Skeletons/Deinon.skeleton.rsrc")
>>> rezfork
ResourceFork(1 Hedr, 20 Bone, 20 BonP, 20 BonN, 1 RelP, 15 AnHd, 15 Evnt, 15 NumK, 300 KeyF, 1 alis)
>>> rezfork['Bone'][1008].name
b'Right Leg 1'
>>> rezfork['Bone'][1008].data
>>> rezfork['Bone'][1008].data
b'\x00\x00\x00\x00\x0bRight Leg 1\x01o\x01n\x01m\x01l...'
AIFF-C files produced by rsrcdump are 1-to-1 conversions of the snd
resources. The sample stream inside the AIFF-C file is a verbatim copy of the snd
resource’s sample stream, keeping the original codec intact.
This means that, for further processing, you’ll need to use software that supports the codec used in the original resource. (Common codecs include MAC3
, ima4
, etc.)
You’ll have good results with ffmpeg or Audacity. Other audio editors may have incomplete support for old AIFF-C codecs.
- Compressed resources are not supported.
- PICT conversion:
- Only raster images are supported
- Vector and text opcodes not supported.
- QuickTime-compressed images not supported.
--create
doesn’t support external files (e.g. you can’t create a resource fork of PICTs from PNG files).
© 2023 Iliyas Jorio, MIT license