wader/fq

[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.

wader commented

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.

wader commented

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.

gcr commented

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.

wader commented

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.