misc/libphysfs/archiver_wad.c
author koda
Sun, 20 Mar 2016 03:08:51 -0400
changeset 11612 b7d5d75469ee
parent 10017 de822cd3df3a
child 12213 bb5522e88ab2
permissions -rw-r--r--
Move pixel format conversion from uVideoRec to AVWrapper This has several benefits, being in C-land allows us to better use libav API and avoid mixing memory allocated from Pascal. Also the C code for the conversion loop generated by GCC or Clang is probably more optimized than by Freepascal. Finally it will simplify code in the future if we are going to enable any other pixel format than yuv420p. Change the coefficients to improve color accuracy during conversion.
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
 *
10017
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 8524
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)
10017
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 8524
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
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   107
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   108
        "WAD",
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   109
        "DOOM engine format",
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   110
        "Travis Wells <traviswells@mchsi.com>",
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   111
        "http://www.3dmm2.com/doom/",
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   112
    },
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   113
    WAD_openArchive,        /* openArchive() method    */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   114
    UNPK_enumerateFiles,     /* enumerateFiles() method */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   115
    UNPK_openRead,           /* openRead() method       */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   116
    UNPK_openWrite,          /* openWrite() method      */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   117
    UNPK_openAppend,         /* openAppend() method     */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   118
    UNPK_remove,             /* remove() method         */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   119
    UNPK_mkdir,              /* mkdir() method          */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   120
    UNPK_closeArchive,       /* closeArchive() method   */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   121
    UNPK_stat                /* stat() method           */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   122
};
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   123
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   124
#endif  /* defined PHYSFS_SUPPORTS_WAD */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   125
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   126
/* end of wad.c ... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   127