home *** CD-ROM | disk | FTP | other *** search
/ 4-Ever Doomed / 4-everdoomedcypresssoftware1994.iso / sharewar / jumble / wadfile.c < prev    next >
C/C++ Source or Header  |  1994-04-03  |  43KB  |  1,094 lines

  1. /*
  2.  *    WADFILE.C
  3.  *
  4.  *    Version 1.0.0
  5.  *
  6.  *    Abstract:
  7.  *     This module contains all the WADFILE processing routines for the
  8.  *     WadLib library.
  9.  *
  10.  *    History:
  11.  *     1.0.0    (March 31, 1994)
  12.  *
  13.  *  Author:
  14.  *     Michael McMahon
  15.  *
  16.  ****************************************************************************
  17.  * Wadfile Function Directory
  18.  *---------------------------------------------------------------------------
  19.  *Index: Name                  : Description
  20.  *---------------------------------------------------------------------------
  21.  * #1  : WadfileAddLump        : Add a lump to a Wadfile being created.
  22.  * #2  : WadfileClose           : Close file, flush cache, update WAD directory
  23.  * #3  : WadfileCopyEntry       : Copies a lump from one Wadfile to another.
  24.  * #4  : WadfileCopyMap        : Copies a map from one Wadfile to another.
  25.  * #5  : WadfileCreate           : Create WAD file and initialize Wadfile struct.
  26.  * #6  : WadfileGetDirInfo       : Read directory info into Wadfile structure.
  27.  * #7  : WadfileGetNextDirInfo : Move to next directory entry and read it in.
  28.  * #8  : WadfileGetPrevDirInfo : Move to last directory entry and read it in.
  29.  * #9  : WadfileInitialize       : One-time call, set up memory allocators.
  30.  * #10 : WadfileLumpClose       : Close lump inside WAD file, free its memory.
  31.  * #11 : WadfileLumpCopy       : Copy lump file from one Wadfile to another.
  32.  * #12 : WadfileLumpOpen       : Open lump at current directory position.
  33.  * #13 : WadfileOpen           : Open a WAD file and initialize Wadfile struct.
  34.  * #14 : WadfileSeek           : Find first dir entry with a search string.
  35.  * #15 : WadfileSeekMap        : Find map given episode and map. ExMy
  36.  ****************************************************************************
  37.  *
  38.  *  WADLIB SOFTWARE LICENSE AGREEMENT
  39.  *
  40.  *    1. GRANT OF LICENSE. Michael McMahon and his affiliations (collectively
  41.  *       the "AUTHOR") grant you (either an individual or an entity) the
  42.  *       non-exclusive, royalty-free right to use this library source code,
  43.  *       documentation, and sample code (collectively, the "SOFTWARE") for
  44.  *       any lawful purpose subject to the terms of this license.  By using the
  45.  *       SOFTWARE you are agreeing to be bound to all the terms of this license.
  46.  *
  47.  *    2. COPYRIGHT.  The SOFTWARE is Copyright (c) 1994, Michael McMahon,
  48.  *       PO Box 14807, San Luis Nabisco, CA 93406-4807 USA. All Rights Reserved
  49.  *       Worldwide.  You may not use, modify, or distribute the SOFTWARE except
  50.  *       as otherwise provided herein.
  51.  *
  52.  *    3. DECLARATION OF PUBLIC DOMAIN DISTRIBUTION AND USE. The distribution
  53.  *       and use of the SOFTWARE is hereby designated PUBLIC DOMAIN by the
  54.  *       the AUTHOR.    You may not sell, rent, or lease this SOFTWARE.  The
  55.  *       SOFTWARE may be reproduced verbatim in part or in full by any
  56.  *       reproduction means for any lawful purpose, and may also be subject to
  57.  *       the following agreement.
  58.  *
  59.  *    4. AGREEMENT FOR USE OF SOFTWARE. The AUTHOR grants you a non-exclusive,
  60.  *       royalty-free right to incorporate the SOFTWARE into any production for
  61.  *       any legal purpose as long as you agree
  62.  *        (a) to indemnify, hold harmless, and defend the AUTHOR from and against
  63.  *            any claims or lawsuits, including attorneys' fees, that arise or
  64.  *            result from the use or distribution of your software production; and
  65.  *        (b) no matter how much the SOFTWARE is modified, the AUTHOR owns the
  66.  *            copyright and this original, unmodified copyright notice remains
  67.  *            intact in the source code; and,
  68.  *        (c) the AUTHOR is not held responsible for fixing bugs or making
  69.  *            enhancements or changes to the SOFTWARE for any reason; and,
  70.  *        (d) the SOFTWARE is not redistributed if it is modified in any way; and,
  71.  *      (e) otherwise comply with the terms of this agreement; and,
  72.  *        (f) the AUTHOR is forgiven for making so many demands.
  73.  *
  74.  *     THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. THE
  75.  *     AUTHOR FURTHER DISCLAIMS ALL IMPLIED WARRANTIES, INCLUDING WITHOUT
  76.  *     LIMITATION ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR OF FITNESS
  77.  *     FOR A PARTICULAR PURPOSE.    THE ENTIRE RISK ARISING OUT OF THE USE
  78.  *     OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU.
  79.  *
  80.  *     The author can be reached at:
  81.  *      Michael McMahon
  82.  *      P.O. Box 14807
  83.  *      San Luis Nabisco, CA 93406-4807 USA
  84.  *      Internet: mmcmahon@oboe.calpoly.edu
  85.  *      [Bug reports, suggestions, success stories, etc. are welcome; tech
  86.  *       support, and other unnecessary two-way mail, is not]
  87.  */
  88.  
  89. #include <assert.h>
  90. #include <stdio.h>
  91. #include <string.h>
  92. #include <mem.h>
  93. #include "general.h"
  94. #include "wadfile.h"
  95.  
  96. /* Private wadfile variables */
  97. static int    wadfileInitialized=FALSE; /* Module doesn't work unless TRUE */
  98. static WadfileMalloc  wadfileMalloc;  /* User's allocate memory routine  */
  99. static WadfileFree      wadfileFree;      /* User's free memory routine      */
  100. static int wadfileNumAllocations;      /* Keeps track of the malloc's     */
  101.  
  102. /*------------------------- Private routines ------------------------------*/
  103.  
  104. /**[ Internal 1 of 2 ]****************************************************
  105.  *                                                                       *
  106.  *      wf_malloc                                                          *
  107.  *                                                                         *
  108.  * Desc:                                                                 *
  109.  *       This calls the user's memory allocation routine and updates       *
  110.  *       the 'wadfileNumAllocations' variable.                             *
  111.  *                                                                         *
  112.  * Def:                                                                  *
  113.  *       static void * wf_malloc(unsigned long size);                      *
  114.  *                                                                       *
  115.  * Parm:                                                                 *
  116.  *       size    Number of bytes to allocate.                              *
  117.  *                                                                         *
  118.  * Retn:                                                                 *
  119.  *       Pointer to allocated memory, or NULL if not enough memory.         *
  120.  *                                                                         *
  121.  * Notes:                                                                *
  122.  *       This is the gateway for the WADFILE routines to access the user's *
  123.  *       memory allocation routine. Don't call 'wadfileMalloc()' directly. *
  124.  *                                                                         *
  125.  *************************************************************************/
  126.  
  127. static void * wf_malloc(unsigned long size)
  128. {
  129.     void * result;
  130.  
  131.     /* Sanity check */
  132.     assert(wadfileMalloc != NULL);
  133.  
  134.     /* Allocate memory and bump wadfileNumAllocations if successful */
  135.     result = wadfileMalloc(size);
  136.     if (result != NULL)
  137.       wadfileNumAllocations++;
  138.  
  139.     return result;
  140. }
  141.  
  142. /**[ Internal 2 of 2 ]****************************************************
  143.  *                                                                       *
  144.  *    wf_free                                                            *
  145.  *                                                                       *
  146.  * Desc:                                                                 *
  147.  *     This calls the user's memory de-allocation routine and updates    *
  148.  *     the 'wadfileNumAllocations' variable.                             *
  149.  *                                                                       *
  150.  * Def:                                                                  *
  151.  *       static void wf_free(void * ptr);                                  *
  152.  *                                                                       *
  153.  * Parm:                                                                 *
  154.  *       ptr       Valid memory pointer that was allocated with wf_malloc.     *
  155.  *                                                                       *
  156.  * Retn:                                                                 *
  157.  *       None                                                              *
  158.  *                                                                         *
  159.  * Notes:                                                                *
  160.  *     This is the gateway for the WADFILE routines to access the user's *
  161.  *       memory deallocation routine. Don't call 'wadfileFree()' directly. *
  162.  *                                                                       *
  163.  *************************************************************************/
  164.  
  165. static void wf_free(void * ptr)
  166. {
  167.     /* Sanity check */
  168.     assert(wadfileFree != NULL);
  169.  
  170.     /* Bounds check -- wf_malloc doesn't change wadfileNumAllocations
  171.        with a NULL value, so wf_free behaves the same way with NULL. */
  172.     if (ptr == NULL) return;
  173.  
  174.     /* Free the memory and update counter */
  175.     wadfileFree(ptr);
  176.     wadfileNumAllocations--;
  177. }
  178.  
  179.  
  180. /*-------------------------- Public routines ------------------------------*/
  181.  
  182. /**[ #1 ]*****************************************************************
  183.  *                                                                         *
  184.  *      WadfileAddLump                                                     *
  185.  *                                                                         *
  186.  * Desc:                                                                 *
  187.  *       This writes a lump to a Wadfile being created, and adds a         *
  188.  *       directory entry associated with the lump.                         *
  189.  *                                                                         *
  190.  * Def:                                                                  *
  191.  *      int WadfileAddLump(Wadfile * wad, unsigned long size,              *
  192.  *                         char * name, char * data);                      *
  193.  *                                                                       *
  194.  * Parm:                                                                 *
  195.  *       wad       Wadfile to add the lump data to.                          *
  196.  *       size    Size of lump data in bytes.                                 *
  197.  *       name    Directory name of lump. IT MUST BE 8 CHARACTERS!          *
  198.  *       data    Pointer to lump data.                                     *
  199.  *                                                                         *
  200.  * Retn:                                                                 *
  201.  *       TRUE if the data is added successfully, FALSE otherwise.          *
  202.  *                                                                         *
  203.  * Notes:                                                                 *
  204.  *      If compiling for a 16-bit target, the maximum lump size is 64k.     *
  205.  *                                                                         *
  206.  *      'name' should consist of capital letters, numbers, and the under-  *
  207.  *      score character. If the text is less than eight characters, it     *
  208.  *      must be padded with zeroes. For example: "E1M1\0\0\0\0" is correct.*
  209.  *                                                                       *
  210.  *************************************************************************/
  211.  
  212. int WadfileAddLump(Wadfile * wad, unsigned long size, char * name, char * data)
  213. {
  214.     unsigned long location;
  215.     char * ptr;
  216.  
  217.     /* Make sure WadfileInitialize has been called */
  218.     assert(wadfileInitialized);
  219.  
  220.     /* Bounds check */
  221.     if (!(wad->flags & FLAG_WADFILE_OPEN)) return FALSE;
  222.     if (!(wad->flags & FLAG_WADFILE_WRITEONLY)) return FALSE;
  223.  
  224.     /* Bump up 'entryIndex' */
  225.     if (wad->entryIndex == INVALID_ENTRY)
  226.       wad->entryIndex = 0;
  227.     else
  228.       wad->entryIndex++;
  229.     if (wad->entryIndex >= wad->dirNumEntries) return FALSE;
  230.  
  231.     /* Copy data to 'dirCache' */
  232.     location = ftell(wad->wf);
  233.     ptr = &wad->dirCache[wad->entryIndex*SIZEOF_WAD_DIR_ENTRY];
  234.     memcpy(ptr, &location, SIZEOF_WAD_DIR_LOCATION);
  235.     ptr += SIZEOF_WAD_DIR_LOCATION;
  236.     memcpy(ptr, &size, SIZEOF_WAD_DIR_SIZE);
  237.     ptr += SIZEOF_WAD_DIR_SIZE;
  238.     memcpy(ptr, name, SIZEOF_WAD_DIR_NAME);
  239.  
  240.     /* Write data to Wadfile on disk */
  241.     if (size != 0)
  242.      fwrite(data, size, 1, wad->wf);
  243.  
  244.     return TRUE;
  245. }
  246.  
  247. /**[ #2 ]*****************************************************************
  248.  *                                                                         *
  249.  *      WadfileClose                                                         *
  250.  *                                                                         *
  251.  * Desc:                                                                 *
  252.  *       This closes a Wadfile and flushes its disk cache. If the lump is  *
  253.  *       open, it is closed and the lump memory is released.    If the         *
  254.  *       Wadfile is being created, the directory is written to disk and     *
  255.  *       the file header is updated before the Wadfile is closed.          *
  256.  *                                                                         *
  257.  * Def:                                                                  *
  258.  *       void WadfileClose(Wadfile * wad);                                 *
  259.  *                                                                         *
  260.  * Parm:                                                                 *
  261.  *       wad       The Wadfile to close.                                     *
  262.  *                                                                         *
  263.  * Retn:                                                                 *
  264.  *       None.                                                             *
  265.  *                                                                         *
  266.  *************************************************************************/
  267.  
  268. void WadfileClose(Wadfile * wad)
  269. {
  270.     uint32 size, location;
  271.  
  272.     /* Make sure WadfileInitialize has been called */
  273.     assert(wadfileInitialized);
  274.  
  275.     /* If the file is open, flush caches, close file and clear the open flag */
  276.     if (wad->flags & FLAG_WADFILE_OPEN)
  277.     {
  278.         /* If creating a file, write directory entries and fix header */
  279.         if (wad->flags & FLAG_WADFILE_WRITEONLY)
  280.         {
  281.             if (wad->entryIndex != INVALID_ENTRY)
  282.             {
  283.                /* Initialize variables */
  284.                size = wad->entryIndex + 1;
  285.                location = ftell(wad->wf);
  286.  
  287.                /* Write directory to disk */
  288.                fwrite(wad->dirCache, SIZEOF_WAD_DIR_ENTRY, size, wad->wf);
  289.  
  290.                /* Fix WAD header */
  291.                fseek(wad->wf, SIZEOF_WAD_SIGNATURE, SEEK_SET);
  292.                fwrite(&size, sizeof(size), 1, wad->wf);
  293.                fwrite(&location, sizeof(location), 1, wad->wf);
  294.  
  295.             }
  296.             else
  297.             {
  298.               /* Invalid Wad file, so destroy WAD Signature */
  299.               fseek(wad->wf, 0L, SEEK_SET);
  300.               size = 0;
  301.               fwrite(&size, SIZEOF_WAD_SIGNATURE, 1, wad->wf);
  302.             }
  303.         }
  304.  
  305.         /* Flush 'dirCache' */
  306.         if (wad->flags & FLAG_WADFILE_DIRCACHED)
  307.         {
  308.           wf_free(wad->dirCache);
  309.           wad->flags ^= FLAG_WADFILE_DIRCACHED;
  310.         }
  311.         if (wad->flags & FLAG_LUMP_OPEN)
  312.          WadfileLumpClose(wad);
  313.  
  314.         /* Close file */
  315.         fclose(wad->wf);
  316.         wad->flags ^= FLAG_WADFILE_OPEN;
  317.     }
  318. }
  319.  
  320. /**[ #3 ]*****************************************************************
  321.  *                                                                         *
  322.  *      WadfileCopyEntry                                                     *
  323.  *                                                                         *
  324.  * Desc:                                                                 *
  325.  *       This copies an arbitrary lump from an open Wadfile to a Wadfile     *
  326.  *       that is being created. Do not use 'WadfileLumpOpen' or            *
  327.  *       'WadfileLumpClose' to initialize and release the lump data; this  *
  328.  *       routine is self-contained and opens, copies, and closes the lump  *
  329.  *       data in one fell swoop.                                             *
  330.  *                                                                         *
  331.  * Def:                                                                  *
  332.  *       int WadfileCopyEntry(Wadfile * dest, char * destName,             *
  333.  *                            Wadfile * src,    char * srcName)              *
  334.  *                                                                       *
  335.  * Parm:                                                                 *
  336.  *       dest        A Wadfile that is being created.                      *
  337.  *       destName    The directory entry name for the new lump.             *
  338.  *     src         An existing Wadfile.                                  *
  339.  *       srcName       The directory entry name to search for and copy.      *
  340.  *                                                                       *
  341.  * Retn:                                                                 *
  342.  *       TRUE if lump is copied succesfully; FALSE otherwise.              *
  343.  *                                                                         *
  344.  * Notes:                                                                 *
  345.  *       On a 16-bit platform, this successfully copies lumps larger         *
  346.  *       than 64k.                                                         *
  347.  *                                                                         *
  348.  *************************************************************************/
  349.  
  350. int WadfileCopyEntry(Wadfile * dest, char * destName,
  351.                      Wadfile * src,  char * srcName)
  352. {
  353.     /* Sequentially search WAD directory for 'srcName' */
  354.     if (!WadfileSeek(src, srcName)) return FALSE;
  355.  
  356.     /* Copy lump from source to destination */
  357.     if (!WadfileLumpCopy(dest, destName, src)) return FALSE;
  358.  
  359.     return TRUE;
  360. }
  361.  
  362. /**[ #4 ]*****************************************************************
  363.  *                                                                         *
  364.  *      WadfileCopyMap                                                     *
  365.  *                                                                         *
  366.  * Desc:                                                                 *
  367.  *       This copies an arbitrary map from an open Wadfile to a Wadfile     *
  368.  *       that is being created. Do not use 'WadfileLumpOpen' or            *
  369.  *       'WadfileLumpClose' to initialize and release the lump data; this  *
  370.  *       routine is self-contained and opens, copies, and closes the lump  *
  371.  *       data in one fell swoop.                                             *
  372.  *                                                                         *
  373.  * Def:                                                                  *
  374.  *       int WadfileCopyMap(Wadfile * dest, int destEpisode, int destMap,  *
  375.  *                          Wadfile * src,  int srcEpisode,  int srcMap)     *
  376.  *                                                                       *
  377.  * Parm:                                                                 *
  378.  *       dest         A Wadfile that is being created.                     *
  379.  *       destEpisode    The new episode number for the map data.             *
  380.  *       destMap        The new map number for the map data.                 *
  381.  *       src            An existing Wadfile.                                 *
  382.  *       srcEpisode    The old episode number for the map data.             *
  383.  *       srcMap        The old map number for the map data.                 *
  384.  *                                                                       *
  385.  * Retn:                                                                 *
  386.  *       TRUE if map is copied succesfully; FALSE otherwise.                 *
  387.  *                                                                         *
  388.  * Notes:                                                                 *
  389.  *       On a 16-bit platform, this successfully copies lumps larger         *
  390.  *       than 64k.                                                         *
  391.  *                                                                         *
  392.  *************************************************************************/
  393.  
  394. int WadfileCopyMap(Wadfile * dest, int destEpisode, int destMap,
  395.                    Wadfile * src,  int srcEpisode,  int srcMap)
  396. {
  397.     int i;
  398.     char targetName[SIZEOF_WAD_DIR_NAME];
  399.  
  400.     /* Seek to map location, if possible */
  401.     if (!WadfileSeekMap(src, srcEpisode, srcMap)) return FALSE;
  402.  
  403.     /* Copy the source map to destination map */
  404.     if (!WadfileLumpOpen(src)) return FALSE;
  405.     sprintf(targetName, "E%dM%d\0\0\0\0", destEpisode, destMap);
  406.     if (!WadfileAddLump(dest, src->lumpSize, targetName, src->lumpData))
  407.      return FALSE;
  408.     if (!WadfileLumpClose(src)) return FALSE;
  409.  
  410.     /* Now that this is copied, go to next entry */
  411.     WadfileGetNextDirInfo(src);
  412.  
  413.     /* Write out all other sections of the map */
  414.     for (i=0; i<NUM_ENTRIES_PER_MAP-1; i++)
  415.     {
  416.         /* Copy lump from source to destination */
  417.         if (!WadfileLumpCopy(dest, src->entryName, src))
  418.          return FALSE;
  419.  
  420.         /* Go to next entry in the directory */
  421.         WadfileGetNextDirInfo(src);
  422.     }
  423.  
  424.     return TRUE;
  425. }
  426.  
  427. /**[ #5 ]*****************************************************************
  428.  *                                                                         *
  429.  *      WadfileCreate                                                      *
  430.  *                                                                         *
  431.  * Desc:                                                                 *
  432.  *       This initializes a Wadfile structure, and creates a WAD file on     *
  433.  *       disk.  This file can be either an IWAD or a PWAD file.             *
  434.  *                                                                         *
  435.  * Def:                                                                  *
  436.  *       int    WadfileCreate(Wadfile * wad, char * filename,                 *
  437.  *                          int type, int maxEntries);                     *
  438.  *                                                                       *
  439.  * Parm:                                                                 *
  440.  *       wad           The Wadfile to create.                                 *
  441.  *       filename    The filename (with path) to use.                      *
  442.  *       type        The file type, either IWAD or PWAD:                     *
  443.  *            TYPE_IWAD     Create an IWAD file.                             *
  444.  *            TYPE_PWAD     Create a PWAD file.                             *
  445.  *       maxEntries  The maximum number of directory entries that can be     *
  446.  *                   used in this Wadfile.                                 *
  447.  *                                                                         *
  448.  * Retn:                                                                 *
  449.  *       TRUE if the Wadfile is created successfully, FALSE otherwise.     *
  450.  *                                                                         *
  451.  * Notes:                                                                 *
  452.  *       If 'filename' exists on disk, the function fails. YOU must delete *
  453.  *       the file before calling this function.                             *
  454.  *                                                                         *
  455.  *       'filename' should have a ".WAD" extension.                        *
  456.  *                                                                         *
  457.  *       There is no reason to create an IWAD file.  You should always     *
  458.  *       create a PWAD file.                                                 *
  459.  *                                                                         *
  460.  *       Be liberal when choosing 'maxEntries'.  You have less RAM is you  *
  461.  *       choose too high, the program crashes if you choose too low. Each  *
  462.  *       entry takes 16 bytes of RAM. The registered DOOM has just over     *
  463.  *       2000 entries.                                                     *
  464.  *                                                                         *
  465.  *************************************************************************/
  466.  
  467. int  WadfileCreate(Wadfile * wad, char * filename, int type, int maxEntries)
  468. {
  469.     uint32 longint;
  470.     char   s[SIZEOF_WAD_SIGNATURE+1];
  471.  
  472.     /* Make sure WadfileInitialize has been called */
  473.     assert(wadfileInitialized);
  474.  
  475.     /* Bounds check */
  476.     if (filename == NULL) return FALSE;
  477.     if ((type != TYPE_IWAD) && (type != TYPE_PWAD)) return FALSE;
  478.     if (maxEntries <= 0) return FALSE;
  479.  
  480.     /* Make sure the memory allocation routines exist */
  481.     if (wadfileMalloc == NULL) return FALSE;
  482.  
  483.     /* Initialize WAD structure */
  484.     wad->flags = 0;
  485.     wad->dirNumEntries = maxEntries;
  486.     wad->entryIndex = INVALID_ENTRY;
  487.     wad->entryName[SIZEOF_WAD_DIR_NAME] = 0; /* Permanent end of string mark */
  488.     wad->dirCache = NULL;
  489.  
  490.     /* Make sure the file doesn't already exist */
  491.     wad->wf = fopen(filename, "rb");
  492.     if (wad->wf!=NULL) return FALSE;
  493.  
  494.     /* Create the file, return if error */
  495.     wad->wf = fopen(filename, "wb");
  496.     if (wad->wf==NULL) return FALSE;
  497.     wad->flags ^= FLAG_WADFILE_OPEN;
  498.     wad->flags ^= FLAG_WADFILE_WRITEONLY;
  499.  
  500.     /* Write signature to the Wadfile */
  501.     if (type==TYPE_IWAD)
  502.         strcpy(s, IWAD_SIGNATURE);
  503.     else
  504.         strcpy(s, PWAD_SIGNATURE);
  505.     s[SIZEOF_WAD_SIGNATURE] = 0;
  506.     fwrite(s, SIZEOF_WAD_SIGNATURE, 1, wad->wf);
  507.  
  508.     /* Write out dummy values for dir location and size as placeholders */
  509.     longint=0;
  510.     fwrite(&longint, sizeof(longint), 1, wad->wf);
  511.     fwrite(&longint, sizeof(longint), 1, wad->wf);
  512.  
  513.     /* Create the directory with 'maxEntries' number of entries */
  514.     wad->dirCache = wf_malloc(maxEntries*SIZEOF_WAD_DIR_ENTRY);
  515.     if (wad->dirCache == NULL)
  516.     {
  517.       WadfileClose(wad);
  518.       return FALSE;
  519.     }
  520.     wad->flags |= FLAG_WADFILE_DIRCACHED;
  521.  
  522.     return TRUE;
  523. }
  524.  
  525. /**[ #6 ]*****************************************************************
  526.  *                                                                         *
  527.  *      WadfileGetDirInfo                                                  *
  528.  *                                                                         *
  529.  * Desc:                                                                 *
  530.  *       This loads a specific Wadfile directory entry into a Wadfile      *
  531.  *       structure.                                                         *
  532.  *                                                                         *
  533.  * Def:                                                                  *
  534.  *       int WadfileGetDirInfo(Wadfile * wad, int entryIndex);             *
  535.  *                                                                         *
  536.  * Parm:                                                                 *
  537.  *       wad            The Wadfile structure to process.                     *
  538.  *       entryIndex    Directory index to load in.                          *
  539.  *                                                                         *
  540.  * Retn:                                                                 *
  541.  *       TRUE if entry found and loaded succesfully; FALSE otherwise.      *
  542.  *                                                                         *
  543.  *************************************************************************/
  544.  
  545. int WadfileGetDirInfo(Wadfile * wad, int entryIndex)
  546. {
  547.     /* Make sure WadfileInitialize has been called */
  548.     assert(wadfileInitialized);
  549.  
  550.     /* Bounds check */
  551.     if (entryIndex < 0) return FALSE;
  552.     if (!(wad->flags & FLAG_WADFILE_OPEN)) return FALSE;
  553.     if (entryIndex > wad->dirNumEntries) return FALSE;
  554.  
  555.     /* Copy info from memory or disk */
  556.     if (wad->flags & FLAG_WADFILE_DIRCACHED)
  557.     {
  558.      /* From memory cache */
  559.      memcpy(&wad->entryLocation, &wad->dirCache[entryIndex*SIZEOF_WAD_DIR_ENTRY], SIZEOF_WAD_DIR_ENTRY);
  560.     }
  561.     else
  562.     {
  563.     /* Seek to the correct directory entry and read it in from disk */
  564.     fseek(wad->wf, wad->dirLocation + SIZEOF_WAD_DIR_ENTRY*entryIndex, SEEK_SET);
  565.     fread(&wad->entryLocation, SIZEOF_WAD_DIR_ENTRY, 1, wad->wf);
  566.     }
  567.  
  568.     /* Update WAD structure */
  569.     wad->entryIndex = entryIndex;
  570.  
  571.     return TRUE;
  572. }
  573.  
  574. /**[ #7 ]*****************************************************************
  575.  *                                                                         *
  576.  *      WadfileGetNextDirInfo                                              *
  577.  *                                                                         *
  578.  * Desc:                                                                 *
  579.  *       This loads the next Wadfile directory entry into a Wadfile         *
  580.  *       structure.                                                         *
  581.  *                                                                         *
  582.  * Def:                                                                  *
  583.  *       int WadfileGetNextDirInfo(Wadfile * wad);                         *
  584.  *                                                                         *
  585.  * Parm:                                                                 *
  586.  *       wad            The Wadfile structure to process.                     *
  587.  *                                                                         *
  588.  * Retn:                                                                 *
  589.  *       TRUE if entry loaded succesfully; FALSE otherwise.                 *
  590.  *                                                                         *
  591.  * Notes:                                                                 *
  592.  *       This routine fails if you haven't called 'WadfileGetDirInfo' at   *
  593.  *       least once with this Wadfile variable.                             *
  594.  *                                                                         *
  595.  *************************************************************************/
  596.  
  597. int WadfileGetNextDirInfo(Wadfile * wad)
  598. {
  599.     /* Make sure WadfileInitialize has been called */
  600.     assert(wadfileInitialized);
  601.  
  602.     return WadfileGetDirInfo(wad, wad->entryIndex+1);
  603. }
  604.  
  605. /**[ #8 ]*****************************************************************
  606.  *                                                                         *
  607.  *      WadfileGetPrevDirInfo                                              *
  608.  *                                                                         *
  609.  * Desc:                                                                 *
  610.  *       This loads the previous Wadfile directory entry into a Wadfile     *
  611.  *       structure.                                                         *
  612.  *                                                                         *
  613.  * Def:                                                                  *
  614.  *       int WadfileGetPrevDirInfo(Wadfile * wad);                         *
  615.  *                                                                         *
  616.  * Parm:                                                                 *
  617.  *       wad            The Wadfile structure to process.                     *
  618.  *                                                                         *
  619.  * Retn:                                                                 *
  620.  *       TRUE if entry loaded succesfully; FALSE otherwise.                 *
  621.  *                                                                         *
  622.  * Notes:                                                                 *
  623.  *       This routine fails if you haven't called 'WadfileGetDirInfo' at   *
  624.  *       least once with this Wadfile variable.                             *
  625.  *                                                                         *
  626.  *************************************************************************/
  627.  
  628. int WadfileGetPrevDirInfo(Wadfile * wad)
  629. {
  630.     /* Make sure WadfileInitialize has been called */
  631.     assert(wadfileInitialized);
  632.  
  633.     return WadfileGetDirInfo(wad, wad->entryIndex-1);
  634. }
  635.  
  636.  
  637. /**[ #9 ]*****************************************************************
  638.  *                                                                         *
  639.  *      WadfileInitialize                                                  *
  640.  *                                                                         *
  641.  * Desc:                                                                 *
  642.  *       This initializes the Wadfile support and must be called before     *
  643.  *       any other Wadfile routines are called.                             *
  644.  *                                                                         *
  645.  * Def:                                                                  *
  646.  *       int WadfileInitialize(WadfileMalloc * wfm, WadfileFree * wff);     *
  647.  *                                                                       *
  648.  * Parm:                                                                 *
  649.  *       wfm       Malloc routine for Wadfile routines (can be NULL)         *
  650.  *       wff       Free memory routine for Wadfile routines (can be NULL)     *
  651.  *                                                                         *
  652.  * Retn:                                                                 *
  653.  *       TRUE if the memory routines are operational, FALSE otherwise.     *
  654.  *                                                                         *
  655.  * Notes:                                                                 *
  656.  *     Either both of the parameters are NULL or not. It is a fatal error  *
  657.  *     to specify one routine and not the other.                             *
  658.  *                                                                         *
  659.  *     Any time you want to specify different memory allocation routines     *
  660.  *     for the Wadfile library, just call this routine again. If there     *
  661.  *     are lingering allocations, the function will fail.                  *
  662.  *                                                                         *
  663.  *************************************************************************/
  664.  
  665. int WadfileInitialize(WadfileMalloc wfm, WadfileFree wff)
  666. {
  667.     /* Bounds check--vital enough to be asserts */
  668.     assert(((wfm==NULL) && (wff==NULL))||
  669.            ((wfm!=NULL) && (wff!=NULL)));
  670.  
  671.     /* See if we're getting re-initialized */
  672.     if (wadfileInitialized)
  673.     {
  674.       /* Any lingering allocations? */
  675.       if (wadfileNumAllocations)
  676.         wadfileInitialized = FALSE;
  677.       else
  678.       {
  679.         /* No? Re-initialize. */
  680.         wadfileMalloc = wfm;
  681.         wadfileFree   = wff;
  682.       }
  683.     }
  684.     else
  685.     {
  686.      /* Make sure the compiler understands the code */
  687.      assert(sizeof(int16) == 2);
  688.      assert(sizeof(uint16) == 2);
  689.      assert(sizeof(int32) == 4);
  690.      assert(sizeof(uint32) == 4);
  691.  
  692.      /* Initialize the memory handlers */
  693.      wadfileNumAllocations = 0;
  694.      wadfileMalloc = wfm;
  695.      wadfileFree   = wff;
  696.  
  697.      wadfileInitialized = TRUE;
  698.     }
  699.  
  700.     return wadfileInitialized;
  701. }
  702.  
  703. /**[ #10 ]****************************************************************
  704.  *                                                                         *
  705.  *      WadfileLumpClose                                                     *
  706.  *                                                                         *
  707.  * Desc:                                                                 *
  708.  *       This releases the memory allocated to the lump that is stored     *
  709.  *       in a Wadfile structure.    This memory is allocated and filled      *
  710.  *       by the 'WadfileLumpOpen' routine.                                 *
  711.  *                                                                         *
  712.  * Def:                                                                  *
  713.  *       int WadfileLumpClose(Wadfile * wad);                              *
  714.  *                                                                       *
  715.  * Parm:                                                                 *
  716.  *       wad            The Wadfile structure to process.                     *
  717.  *                                                                         *
  718.  * Retn:                                                                 *
  719.  *       TRUE if lump memory freed succesfully; FALSE otherwise.             *
  720.  *                                                                         *
  721.  *************************************************************************/
  722.  
  723. int WadfileLumpClose(Wadfile * wad)
  724. {
  725.     /* Make sure WadfileInitialize has been called */
  726.     assert(wadfileInitialized);
  727.  
  728.     /* Bounds check */
  729.     if (wadfileMalloc==NULL) return FALSE;
  730.     if (!(wad->flags & FLAG_LUMP_OPEN)) return FALSE;
  731.  
  732.     /* Deallocate the LUMP data */
  733.     if (wad->lumpSize != 0)
  734.      wf_free(wad->lumpData);
  735.  
  736.     /* Update Wadfile structure */
  737.     wad->flags ^= FLAG_LUMP_OPEN;
  738.  
  739.     return TRUE;
  740. }
  741.  
  742. /**[ #11 ]****************************************************************
  743.  *                                                                         *
  744.  *      WadfileLumpCopy                                                     *
  745.  *                                                                         *
  746.  * Desc:                                                                 *
  747.  *       This copies the lump data from an open Wadfile to a Wadfile that  *
  748.  *       is being created. Do not use 'WadfileLumpOpen' or                 *
  749.  *       'WadfileLumpClose' to initialize and release the lump data; this  *
  750.  *       routine is self-contained and opens, copies, and closes the lump  *
  751.  *       data in one fell swoop.                                             *
  752.  *                                                                         *
  753.  * Def:                                                                  *
  754.  *    int WadfileLumpCopy(Wadfile * dest, char * destName, Wadfile * src); *
  755.  *                                                                       *
  756.  * Parm:                                                                 *
  757.  *       dest        A Wadfile that is being created.                      *
  758.  *       destName    The directory entry name for the new lump.             *
  759.  *     src         An existing Wadfile.                                  *
  760.  *                                                                         *
  761.  * Retn:                                                                 *
  762.  *       TRUE if lump is copied succesfully; FALSE otherwise.              *
  763.  *                                                                         *
  764.  * Notes:                                                                 *
  765.  *       On a 16-bit platform, this successfully copies lumps larger         *
  766.  *       than 64k.                                                         *
  767.  *                                                                         *
  768.  *************************************************************************/
  769.  
  770. int WadfileLumpCopy(Wadfile * dest, char * destName, Wadfile * src)
  771. {
  772.     unsigned long allocSize;
  773.     unsigned long lumpCopySize;
  774.     unsigned long location;
  775.     char * ptr;
  776.  
  777.     /* Make sure WadfileInitialize has been called */
  778.     assert(wadfileInitialized);
  779.  
  780.     /* Bounds check */
  781.     if (wadfileMalloc==NULL) return FALSE;
  782.     if (!(dest->flags & FLAG_WADFILE_OPEN)) return FALSE;
  783.     if (!(src->flags & FLAG_WADFILE_OPEN)) return FALSE;
  784.     if (!(dest->flags & FLAG_WADFILE_WRITEONLY)) return FALSE;
  785.     if (src->flags & FLAG_WADFILE_WRITEONLY) return FALSE;
  786.     if (dest->flags & FLAG_LUMP_OPEN) return FALSE;
  787.     if (src->entryIndex == INVALID_ENTRY) return FALSE;
  788.     if (destName == NULL) return FALSE;
  789.  
  790.     /* Set LUMP variables */
  791.     dest->lumpLocation = src->entryLocation;
  792.     dest->lumpSize       = src->entrySize;
  793.     memcpy(dest->lumpName, destName, SIZEOF_WAD_DIR_NAME);
  794.     location = ftell(dest->wf);
  795.  
  796.     /* Seek to start of data to be read */
  797.     fseek(src->wf, src->entryLocation, SEEK_SET);
  798.  
  799.     /* Set up loop control variable */
  800.     lumpCopySize = dest->lumpSize;
  801.  
  802.     /* Do the copy */
  803.     while (lumpCopySize != 0)
  804.     {
  805.      /* Allocate a buffer */
  806.      if (lumpCopySize >= MALLOC_MAX)
  807.         allocSize = MALLOC_MAX;
  808.      else
  809.         allocSize = lumpCopySize;
  810.      dest->lumpData    = wf_malloc(allocSize);
  811.      if (dest->lumpData == NULL) return FALSE;
  812.  
  813.      /* Read LUMP data from 'src' and write to 'dest' */
  814.      fread(dest->lumpData, allocSize, 1, src->wf);
  815.      fwrite(dest->lumpData, allocSize, 1, dest->wf);
  816.  
  817.      /* Free the buffer */
  818.      wf_free(dest->lumpData);
  819.  
  820.      /* Update our byte count */
  821.      lumpCopySize  -= allocSize;
  822.     } /* while */
  823.  
  824.     /* Bump up 'entryIndex' */
  825.     if (dest->entryIndex == INVALID_ENTRY)
  826.       dest->entryIndex = 0;
  827.     else
  828.       dest->entryIndex++;
  829.     if (dest->entryIndex >= dest->dirNumEntries) return FALSE;
  830.  
  831.     /* Copy data to 'dirCache' */
  832.     ptr = &dest->dirCache[dest->entryIndex*SIZEOF_WAD_DIR_ENTRY];
  833.     memcpy(ptr, &location, SIZEOF_WAD_DIR_LOCATION);
  834.     ptr += SIZEOF_WAD_DIR_LOCATION;
  835.     memcpy(ptr, &dest->lumpSize, SIZEOF_WAD_DIR_SIZE);
  836.     ptr += SIZEOF_WAD_DIR_SIZE;
  837.     memcpy(ptr, dest->lumpName, SIZEOF_WAD_DIR_NAME);
  838.  
  839.     return TRUE;
  840. }
  841.  
  842. /**[ #12 ]****************************************************************
  843.  *                                                                         *
  844.  *      WadfileLumpOpen                                                     *
  845.  *                                                                         *
  846.  * Desc:                                                                 *
  847.  *       This allocates memory and reads in the lump associated with the     *
  848.  *       current directory entry in the Wadfile structure.  The memory     *
  849.  *       is released later on by using the 'WadfileLumpClose' routine.     *
  850.  *                                                                         *
  851.  * Def:                                                                  *
  852.  *       int WadfileLumpOpen(Wadfile * wad);                                 *
  853.  *                                                                       *
  854.  * Parm:                                                                 *
  855.  *       wad            The Wadfile structure to process.                     *
  856.  *                                                                         *
  857.  * Retn:                                                                 *
  858.  *       TRUE if lump allocated and read in succesfully; FALSE otherwise.  *
  859.  *                                                                         *
  860.  * Notes:                                                                 *
  861.  *       This routine fails if you haven't called 'WadfileGetDirInfo' at   *
  862.  *       least once with this Wadfile variable.                             *
  863.  *                                                                         *
  864.  *       If you're using a 16-bit compiler, the maximum lump size is 64k.  *
  865.  *       This function fails if the lump is too big.    Only 1 lump out of     *
  866.  *       2045 in the registered version of DOOM is >64kb. (E2M7 SIDEDEFS)  *
  867.  *       Use 'WadfileLumpCopy' to work around the 64k limitation.          *
  868.  *                                                                       *
  869.  *************************************************************************/
  870.  
  871. int WadfileLumpOpen(Wadfile * wad)
  872. {
  873.     /* Make sure WadfileInitialize has been called */
  874.     assert(wadfileInitialized);
  875.  
  876.     /* Bounds check */
  877.     if (wadfileMalloc==NULL) return FALSE;
  878.     if (!(wad->flags & FLAG_WADFILE_OPEN)) return FALSE;
  879.     if (wad->flags & FLAG_WADFILE_WRITEONLY) return FALSE;
  880.     if (wad->flags & FLAG_LUMP_OPEN) return FALSE;
  881.     if (wad->entryIndex == INVALID_ENTRY) return FALSE;
  882.  
  883.     /* Allocate memory for LUMP */
  884.     if (wad->entrySize != 0)
  885.     {
  886.      wad->lumpData = wf_malloc(wad->entrySize);
  887.      if (wad->lumpData == NULL) return FALSE;
  888.     }
  889.  
  890.     /* Set LUMP variables */
  891.     wad->lumpLocation = wad->entryLocation;
  892.     wad->lumpSize      = wad->entrySize;
  893.     memcpy(wad->lumpName, wad->entryName, SIZEOF_WAD_DIR_NAME);
  894.  
  895.     /* Read LUMP data from disk */
  896.     if (wad->lumpSize != 0)
  897.     {
  898.         fseek(wad->wf, wad->entryLocation, SEEK_SET);
  899.         fread(wad->lumpData, wad->lumpSize, 1, wad->wf);
  900.     }
  901.  
  902.     /* Update Wadfile structure */
  903.     wad->flags |= FLAG_LUMP_OPEN;
  904.  
  905.     return TRUE;
  906. }
  907.  
  908. /**[ #13 ]****************************************************************
  909.  *                                                                         *
  910.  *      WadfileOpen                                                         *
  911.  *                                                                       *
  912.  * Desc:                                                                 *
  913.  *       This opens a WAD file and initializes a Wadfile context.          *
  914.  *                                                                         *
  915.  * Def:                                                                  *
  916.  *     int WadfileOpen(Wadfile * wad, char * filename, int type);        *
  917.  *                                                                         *
  918.  * Parm:                                                                 *
  919.  *       wad               The Wadfile context                                 *
  920.  *       filename        The file name (including path) of the WAD file.     *
  921.  *       type            The type of WAD file to open:                     *
  922.  *               WANTIWAD  accept only IWAD files.                         *
  923.  *               WANTPWAD  accept only PWAD files.                         *
  924.  *               IWADPWAD  accept either IWAD or PWAD files.                 *
  925.  *                                                                         *
  926.  * Retn:                                                                 *
  927.  *       TRUE if the file exists and is open, FALSE otherwise.             *
  928.  *                                                                         *
  929.  *************************************************************************/
  930.  
  931. int WadfileOpen(Wadfile * wad, char * filename, int type)
  932. {
  933.     uint32 longint;
  934.     char   s[SIZEOF_WAD_SIGNATURE+1];
  935.  
  936.     /* Make sure WadfileInitialize has been called */
  937.     assert(wadfileInitialized);
  938.  
  939.     /* Initialize WAD structure */
  940.     wad->flags = 0;
  941.     wad->entryIndex = INVALID_ENTRY;
  942.     wad->entryName[SIZEOF_WAD_DIR_NAME] = 0; /* Permanent end of string mark */
  943.     wad->dirCache = NULL;
  944.  
  945.     /* Open the file, return if error */
  946.     wad->wf = fopen(filename, "rb");
  947.     if (wad->wf==NULL) return FALSE;
  948.     wad->flags ^= FLAG_WADFILE_OPEN;
  949.  
  950.     /* Read in and check the WAD file signature */
  951.     fread(s, SIZEOF_WAD_SIGNATURE, 1, wad->wf);
  952.     s[SIZEOF_WAD_SIGNATURE] = 0;
  953.     if (strcmp(s, IWAD_SIGNATURE) == 0)
  954.      wad->flags |= FLAG_WADFILE_IWAD;
  955.     else
  956.     if (strcmp(s, PWAD_SIGNATURE) != 0)
  957.      goto Exit_Error;
  958.  
  959.     /* Read in directory location and size */
  960.     fread(&longint, sizeof(longint), 1, wad->wf);
  961.     wad->dirNumEntries = longint;
  962.     fread(&longint, sizeof(longint), 1, wad->wf);
  963.     wad->dirLocation   = longint;
  964.  
  965.     /* Make sure the file type matches what the caller is asking for */
  966.     if (((type == WANTPWAD)&&(wad->flags & FLAG_WADFILE_IWAD)) ||
  967.         ((type == WANTIWAD)&&(!(wad->flags & FLAG_WADFILE_IWAD))))
  968.     {
  969.     Exit_Error:
  970.         WadfileClose(wad);
  971.         return FALSE;
  972.     }
  973.  
  974.     /* If memory allocation is available, try to cache the directory */
  975.     if (wadfileMalloc != NULL)
  976.     {
  977.         wad->dirCache = wf_malloc(wad->dirNumEntries*SIZEOF_WAD_DIR_ENTRY);
  978.         if (wad->dirCache != NULL)
  979.         {
  980.           wad->flags |= FLAG_WADFILE_DIRCACHED;
  981.           fseek(wad->wf, wad->dirLocation, SEEK_SET);
  982.           fread(wad->dirCache, wad->dirNumEntries*SIZEOF_WAD_DIR_ENTRY,
  983.                 1,wad->wf);
  984.         }
  985.     }
  986.  
  987.     return TRUE;
  988. }
  989.  
  990. /**[ #14 ]****************************************************************
  991.  *                                                                         *
  992.  *      WadfileSeek                                                         *
  993.  *                                                                         *
  994.  * Desc:                                                                 *
  995.  *       This routine does a linear search through the Wadfile's directory *
  996.  *       starting with the first directory entry and searching until it     *
  997.  *       finds its target or hits the end of the directory.                 *
  998.  *                                                                         *
  999.  * Def:                                                                  *
  1000.  *       int WadfileSeek(Wadfile * wad, char * targetName);                 *
  1001.  *                                                                       *
  1002.  * Parm:                                                                 *
  1003.  *       wad            The Wadfile structure to process.                     *
  1004.  *       targetName    The name of the target directory entry.              *
  1005.  *                                                                         *
  1006.  * Retn:                                                                 *
  1007.  *       TRUE if target was found succesfully; FALSE otherwise.             *
  1008.  *       If TRUE, then the Wadfile's 'entryIndex', 'entryName',            *
  1009.  *     'entrySize', and 'entryLocation' contain meaningful values.       *
  1010.  *                                                                         *
  1011.  * Notes:                                                                 *
  1012.  *       'targetName' can be less than 8 characters; that is, you do not   *
  1013.  *       have to pad it with zeroes, like in 'WadfileAddLump'.             *
  1014.  *                                                                         *
  1015.  *       See also 'WadfileSeekMap' if you are looking for a specific map.  *
  1016.  *                                                                       *
  1017.  *************************************************************************/
  1018.  
  1019. int WadfileSeek(Wadfile * wad, char * targetName)
  1020. {
  1021.     int i;
  1022.     char targetString[SIZEOF_WAD_DIR_NAME+1];
  1023.  
  1024.     /* Make sure WadfileInitialize has been called */
  1025.     assert(wadfileInitialized);
  1026.  
  1027.     /* Convert target name to a null-terminated string */
  1028.     strncpy(targetString, targetName, SIZEOF_WAD_DIR_NAME);
  1029.     targetString[SIZEOF_WAD_DIR_NAME] = '\0';
  1030.  
  1031.     /* Bounds Check */
  1032.     if (!(wad->flags & FLAG_WADFILE_OPEN)) return FALSE;
  1033.     if (targetString == NULL) return FALSE;     /* Too small */
  1034.     if (strlen(targetString)>SIZEOF_WAD_DIR_NAME) return FALSE;  /* Too big   */
  1035.  
  1036.     /* Begin linear search of the WAD directory */
  1037.     i=0;
  1038.     while ((i<wad->dirNumEntries)&&(strcmp(wad->entryName, targetString) !=0))
  1039.     {
  1040.         WadfileGetDirInfo(wad, i);
  1041.         i++;
  1042.     }
  1043.  
  1044.     return (i<wad->dirNumEntries);
  1045. }
  1046.  
  1047. /**[ #15 ]****************************************************************
  1048.  *                                                                         *
  1049.  *      WadfileSeekMap                                                     *
  1050.  *                                                                         *
  1051.  * Desc:                                                                 *
  1052.  *       This routine does a linear search through the Wadfile's directory *
  1053.  *       starting with the first directory entry and searching until it     *
  1054.  *       finds its target map or hits the end of the directory.             *
  1055.  *                                                                         *
  1056.  * Def:                                                                  *
  1057.  *       int WadfileSeekMap(Wadfile * wad, int episodeNum, int mapNum);     *
  1058.  *                                                                       *
  1059.  * Parm:                                                                 *
  1060.  *       wad           The Wadfile structure to process.                     *
  1061.  *       episodeNum  Episode to find. Valid range is 1...DOOM_LASTEPISODE. *
  1062.  *       mapNum       Map to find. Valid range is 1...DOOM_LASTMAP.         *
  1063.  *                                                                       *
  1064.  * Retn:                                                                 *
  1065.  *       TRUE if target was found succesfully; FALSE otherwise.             *
  1066.  *       If TRUE, then the Wadfile's 'entryIndex', 'entryName',            *
  1067.  *     'entrySize', and 'entryLocation' contain meaningful values.       *
  1068.  *                                                                         *
  1069.  * Notes:                                                                 *
  1070.  *       This routine uses 'WadfileSeek' as its search engine.  When you   *
  1071.  *       aren't looking for maps, use 'WadfileSeek'.                       *
  1072.  *                                                                       *
  1073.  *************************************************************************/
  1074.  
  1075. int WadfileSeekMap(Wadfile * wad, int episodeNum, int mapNum)
  1076. {
  1077.     char targetName[5];
  1078.  
  1079.     /* Make sure WadfileInitialize has been called */
  1080.     assert(wadfileInitialized);
  1081.  
  1082.     /* Bounds Check */
  1083.     if ((episodeNum < 0) || (episodeNum > DOOM_LASTEPISODE)) return FALSE;
  1084.     if ((mapNum < 0) || (mapNum > DOOM_LASTMAP)) return FALSE;
  1085.  
  1086.     /* Compose directory name */
  1087.     sprintf(targetName, "E%dM%d",episodeNum, mapNum);
  1088.  
  1089.     /* Sequentially search WAD directory for ExMy */
  1090.     return WadfileSeek(wad, targetName);
  1091. }
  1092.  
  1093.  
  1094.