physfs icon indicating copy to clipboard operation
physfs copied to clipboard

POD file format? (Terminal Velocity, Fury3, Hellbender, FLY!, Monster Truck Madness, etc)

Open StrikerTheHedgefox opened this issue 1 year ago • 1 comments

Would you consider adding POD format support to PhysFS?

https://moddingwiki.shikadi.net/wiki/POD_Format

There's several different versions of the format throughout Terminal Reality's history, and here's a python file for reading and extracting nearly all of them: https://github.com/ghoost82/podextract/blob/master/podextract.py

This should give you a good idea on how to read/write them.

I'm asking this, because I'm developing a source port for Terminal Velocity, Fury3, and Hellbender, and would like to use PhysFS with it, having some experience with it already in EDuke32.

StrikerTheHedgefox avatar May 28 '24 20:05 StrikerTheHedgefox

Here are the other POD versions checksum and compression algorithms and header/entry structures: POD file format versions Checksum Algorithm

jopadan avatar Sep 24 '24 12:09 jopadan

I'd gladly donate $50 CAD to anyone who can get this done.

StrikerTheHedgefox avatar Oct 03 '25 22:10 StrikerTheHedgefox

I need some help. I'm trying to implement this myself, but I need clarification on something. In the POD format, there's no separate directory entries, the directory is included in the filename. Ie: "ART\SHIP.RAW"

So, here's my function, based on info here: https://moddingwiki.shikadi.net/wiki/POD_Format

static int pod1LoadEntries(PHYSFS_Io *io, void *arc)
{
    PHYSFS_uint32 numfiles;
    PHYSFS_uint32 i;

    BAIL_IF_ERRPASS(!readui32(io, &numfiles), 0);
    BAIL_IF_ERRPASS(!io->seek(io, 84), 0);  /* skip past description */

    for (i = 0; i < numfiles; i++) {
        char name[33];
        PHYSFS_uint32 size;
        PHYSFS_uint32 offset;
        BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, name, 32), 0);
        BAIL_IF_ERRPASS(!readui32(io, &size), 0);
        BAIL_IF_ERRPASS(!readui32(io, &offset), 0);
        name[32] = '\0';  /* just in case */

        replaceChar(name, '\\', '/');

        BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, -1, -1, offset, size), 0);
    }

    return 1;
} /* pod1LoadEntries */


static void *POD_openArchive(PHYSFS_Io *io, const char *name,
                             int forWriting, int *claimed)
{
    void *unpkarc = NULL;

    assert(io != NULL);  /* shouldn't ever happen. */
    BAIL_IF(forWriting, PHYSFS_ERR_READ_ONLY, NULL);

    PHYSFS_uint32 dummy;
    char description[80];
    BAIL_IF_ERRPASS(!readui32(io, &dummy), 0);
    BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, description, 80), NULL);
    if ((description[0] == 0) || (description[79] != 0)) // Check if we're lacking a description or last char isn't a null terminator.
        return NULL;

    io->seek(io, 0);

    *claimed = 1;

    unpkarc = UNPK_openArchive(io, 0, 1);
    BAIL_IF_ERRPASS(!unpkarc, NULL);

    if (!(pod1LoadEntries(io, unpkarc)))
    {
        UNPK_abandonArchive(unpkarc);
        return NULL;
    } /* if */

    return unpkarc;
} /* POD_openArchive */

Would this be considered correct? Or is it preferred to somehow split off the directory from the name, and do something else with it? Just want to make sure it correctly resolves the directory paths somehow.

@icculus Your thoughts?

StrikerTheHedgefox avatar Oct 19 '25 02:10 StrikerTheHedgefox