[Feature] Support for Doom WAD Files
sleibrock opened this issue · 5 comments
Can fq
run Doom?
I have a small pet project based around exporting data from Doom WADs and would love to add the functionality to fq
here. Unsure if it's within the scope of the project, but Doom WADs have been around for almost 30 years at this point, so I figured why not ask? It's not a terribly complex format.
Hey! sure i'm willing to add any format that is used publicly. Want to work on adding support? as it seems to be a quite basic archive format i'm guessing it shouldn't be that much work.
Definitely! I can't say I'm familiar with the internals of fq
just yet but I would love to get started and see what I can pull off. Doom WADs have a very simple structure of header, LUMP table, then a blob of all object tables. It should be fun to add in.
Nice! hopefully you should not need to know much about most internals, the decode API used by a format decoders don't know much a the rest of fq on puropse. Maybe a good start is to look at some existing format decode that is similar, maybe ar, tar or zip? also i'm happy to help out, you can for example open a PR with a early draft and then we work from that.
Here's a very rudimentary decoder you can use in fq
. Run fq -d raw -i . MAPS2.wad
and paste the following into the REPL:
def num_le: tobytes|explode|reverse|map(. band 0xff)|tobytes|tonumber;
tobytes as $file | {}
| .type = $file[:4]
| .n_lumps = ($file[4:8]|num_le)
| .offset = ($file[8:12]|num_le)
| ($file[.offset:]) as $lumpdir
| .lumps = [
range(.n_lumps)
| ($lumpdir[16* . :16*( . +1)]) as $rec | {}
| .offset = ($rec[:4]|num_le)
|.size = ($rec[4:8]|num_le)
|.name = ($rec[8:16]|gsub("\u0000";""))
|.data = $file[.offset:.offset+.size]
]
fq
doesn't support creating Decode Values, so you don't get those nice-looking hexdumps like this, but it's a start.
Nice! tip is to put the code into a file wad.jq
as a function from_wad
and then do fq -d bytes -I . 'include "wad"; from_wad' file.wad
btw is this for an older version of fq? the band
infix-operator is now a function band/2
and -d raw
has been split into bytes
and bits
for different slicing units.