misc/libphysfs/archiver_wad.c
author Wuzzy <almikes@aol.com>
Tue, 26 Sep 2017 05:09:33 +0200
changeset 12535 baee67bfa5c2
parent 12213 bb5522e88ab2
permissions -rw-r--r--
ASA, the final battle: Fix mission panel not appearing if you watched the dialog
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     1
/*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     2
 * WAD support routines for PhysicsFS.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     3
 *
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
     4
 * This driver handles DOOM engine archives ("wads"). 
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     5
 * This format (but not this driver) was designed by id Software for use
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     6
 *  with the DOOM engine.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     7
 * The specs of the format are from the unofficial doom specs v1.666
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     8
 * found here: http://www.gamers.org/dhs/helpdocs/dmsp1666.html
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     9
 * The format of the archive: (from the specs)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    10
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    11
 *  A WAD file has three parts:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    12
 *  (1) a twelve-byte header
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    13
 *  (2) one or more "lumps"
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    14
 *  (3) a directory or "info table" that contains the names, offsets, and
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    15
 *      sizes of all the lumps in the WAD
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    16
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    17
 *  The header consists of three four-byte parts:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    18
 *    (a) an ASCII string which must be either "IWAD" or "PWAD"
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    19
 *    (b) a 4-byte (long) integer which is the number of lumps in the wad
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    20
 *    (c) a long integer which is the file offset to the start of
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    21
 *    the directory
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    22
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    23
 *  The directory has one 16-byte entry for every lump. Each entry consists
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    24
 *  of three parts:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    25
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    26
 *    (a) a long integer, the file offset to the start of the lump
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    27
 *    (b) a long integer, the size of the lump in bytes
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    28
 *    (c) an 8-byte ASCII string, the name of the lump, padded with zeros.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    29
 *        For example, the "DEMO1" entry in hexadecimal would be
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    30
 *        (44 45 4D 4F 31 00 00 00)
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
    31
 * 
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    32
 * Note that there is no way to tell if an opened WAD archive is a
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    33
 *  IWAD or PWAD with this archiver.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    34
 * I couldn't think of a way to provide that information, without being too
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    35
 *  hacky.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    36
 * I don't think it's really that important though.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    37
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    38
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    39
 * Please see the file LICENSE.txt in the source's root directory.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    40
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    41
 * This file written by Travis Wells, based on the GRP archiver by
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    42
 *  Ryan C. Gordon.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    43
 */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    44
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    45
#define __PHYSICSFS_INTERNAL__
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    46
#include "physfs_internal.h"
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    47
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    48
#if PHYSFS_SUPPORTS_WAD
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    49
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    50
static UNPKentry *wadLoadEntries(PHYSFS_Io *io, PHYSFS_uint32 fileCount)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    51
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    52
    PHYSFS_uint32 directoryOffset;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    53
    UNPKentry *entries = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    54
    UNPKentry *entry = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    55
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    56
    BAIL_IF_MACRO(!__PHYSFS_readAll(io, &directoryOffset, 4), ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    57
    directoryOffset = PHYSFS_swapULE32(directoryOffset);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    58
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    59
    BAIL_IF_MACRO(!io->seek(io, directoryOffset), ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    60
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    61
    entries = (UNPKentry *) allocator.Malloc(sizeof (UNPKentry) * fileCount);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    62
    BAIL_IF_MACRO(!entries, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    63
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    64
    for (entry = entries; fileCount > 0; fileCount--, entry++)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    65
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    66
        if (!__PHYSFS_readAll(io, &entry->startPos, 4)) goto failed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    67
        if (!__PHYSFS_readAll(io, &entry->size, 4)) goto failed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    68
        if (!__PHYSFS_readAll(io, &entry->name, 8)) goto failed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    69
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    70
        entry->name[8] = '\0'; /* name might not be null-terminated in file. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    71
        entry->size = PHYSFS_swapULE32(entry->size);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    72
        entry->startPos = PHYSFS_swapULE32(entry->startPos);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    73
    } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    74
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    75
    return entries;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    76
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    77
failed:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    78
    allocator.Free(entries);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    79
    return NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    80
} /* wadLoadEntries */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    81
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    82
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    83
static void *WAD_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    84
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    85
    PHYSFS_uint8 buf[4];
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    86
    UNPKentry *entries = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    87
    PHYSFS_uint32 count = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    88
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    89
    assert(io != NULL);  /* shouldn't ever happen. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    90
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    91
    BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    92
    BAIL_IF_MACRO(!__PHYSFS_readAll(io, buf, sizeof (buf)), ERRPASS, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    93
    if ((memcmp(buf, "IWAD", 4) != 0) && (memcmp(buf, "PWAD", 4) != 0))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    94
        BAIL_MACRO(PHYSFS_ERR_UNSUPPORTED, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    95
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    96
    BAIL_IF_MACRO(!__PHYSFS_readAll(io, &count, sizeof (count)), ERRPASS, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    97
    count = PHYSFS_swapULE32(count);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    98
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    99
    entries = wadLoadEntries(io, count);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   100
    BAIL_IF_MACRO(!entries, ERRPASS, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   101
    return UNPK_openArchive(io, entries, count);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   102
} /* WAD_openArchive */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   103
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   104
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   105
const PHYSFS_Archiver __PHYSFS_Archiver_WAD =
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   106
{
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   107
    CURRENT_PHYSFS_ARCHIVER_API_VERSION,
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   108
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   109
        "WAD",
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   110
        "DOOM engine format",
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   111
        "Travis Wells <traviswells@mchsi.com>",
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   112
        "http://www.3dmm2.com/doom/",
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   113
        0,  /* supportsSymlinks */
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   114
    },
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   115
    WAD_openArchive,
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   116
    UNPK_enumerateFiles,
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   117
    UNPK_openRead,
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   118
    UNPK_openWrite,
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   119
    UNPK_openAppend,
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   120
    UNPK_remove,
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   121
    UNPK_mkdir,
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   122
    UNPK_stat,
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   123
    UNPK_closeArchive
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   124
};
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   125
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   126
#endif  /* defined PHYSFS_SUPPORTS_WAD */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   127
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   128
/* end of archiver_wad.c ... */
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   129