home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 24 / CD_ASCQ_24_0995.iso / vrac / deu53b9.zip / deu / source / d_wads.c < prev    next >
C/C++ Source or Header  |  1995-05-07  |  21KB  |  765 lines

  1. /*----------------------------------------------------------------------------*
  2.  | This file is part of DEU (Doom Editing Utilities), created by the DEU team:|
  3.  | Raphael Quinet, Brendon Wyber, Ted Vessenes and others.  See README.1ST or |
  4.  | the "about" dialog box for full credits.                                   |
  5.  |                                                                            |
  6.  | DEU is an open project: if you think that you can contribute, please join  |
  7.  | the DEU team.  You will be credited for any code (or ideas) included in    |
  8.  | the next version of the program.                                           |
  9.  |                                                                            |
  10.  | If you want to make any modifications and re-distribute them on your own,  |
  11.  | you must follow the conditions of the DEU license.  Read the file LICENSE  |
  12.  | in this directory or README.1ST in the top directory.  If do not have a    |
  13.  | copy of these files, you can request them from any member of the DEU team, |
  14.  | or by mail: Raphael Quinet, Rue des Martyrs 9, B-4550 Nandrin (Belgium).   |
  15.  |                                                                            |
  16.  | This program comes with absolutely no warranty.  Use it at your own risks! |
  17.  *----------------------------------------------------------------------------*
  18.  
  19.  D_WADS.C - WAD loading and saving routines
  20.  
  21. */
  22.  
  23. /* the includes */
  24. #include "deu.h"
  25. #include "d_main.h"
  26. #include "d_misc.h"
  27. #include "d_config.h"
  28. #include "d_wads.h"
  29.  
  30. /* global variables */
  31. WadPtr  WadFileList = NULL;      /* linked list of wad files */
  32. MDirPtr MasterDir   = NULL;      /* the master directory */
  33.  
  34.  
  35. /*
  36.    Open the main wad file, read in its directory and create the
  37.    master directory.
  38. */
  39.  
  40. void OpenMainWad(char *filename)
  41. {
  42.   MDirPtr lastp, newp;
  43.   UInt16  n;
  44.   WadPtr  wad;
  45.  
  46.   /* open the wad file */
  47.   printf("\nLoading main WAD file: %s...\n", filename);
  48.   wad = BasicWadOpen(filename);
  49.   if (strncmp(wad->type, "IWAD", 4))
  50.     ProgError("\"%s\" is not the main WAD file", filename);
  51.  
  52.   /* create the master directory */
  53.   lastp = NULL;
  54.   for (n = 0; n < wad->dirsize; n++)
  55.     {
  56.       newp = (MDirPtr) GetMemory(sizeof(struct MasterDirectory));
  57.       newp->next = NULL;
  58.       newp->wadfile = wad;
  59.       memcpy(&(newp->dir), &(wad->directory[n]), sizeof(struct Directory));
  60.       if (MasterDir)
  61.         lastp->next = newp;
  62.       else
  63.         MasterDir = newp;
  64.       lastp = newp;
  65.     }
  66.  
  67.   /* check version of the game */
  68.   if (FindMasterDir(MasterDir, "E2M1") != NULL)
  69.     DoomVersion = 1;
  70.   else if (FindMasterDir(MasterDir, "MAP28") != NULL)
  71.     DoomVersion = 2;
  72.   else
  73.     {
  74.       printf("   *--------------------------------------------*\n");
  75.       printf("   | Warning: you are using a SHAREWARE game.   |\n");
  76.       printf("   | You won't be allowed to save your changes. |\n");
  77.       printf("   | PLEASE REGISTER YOUR COPY OF THE GAME.     |\n");
  78.       printf("   *--------------------------------------------*\n");
  79.       /* If you change the next line, bad things will happen to you... */
  80.       DoomVersion = 0;
  81.     }
  82.   if (FindMasterDir(MasterDir, "M_HTIC") != NULL)
  83.     DoomVersion += 16;
  84. }
  85.  
  86.  
  87. /* Note from R.Q.:
  88.     This function should be re-written so that it doesn't use the master
  89.     directory, which will disappear from DEU.
  90.     Some parts of the code to update a directory may be transferred to the
  91.     BuildCompoundWad function.
  92. */
  93.  
  94. /*
  95.    Open a patch wad file, read in its directory and alter the master
  96.    directory.
  97. */
  98.  
  99. void OpenPatchWad(char *filename)
  100. {
  101.   WadPtr  wad;
  102.   MDirPtr mdir;
  103.   UInt16  n;
  104.   Int16   l;
  105.   char    entryname[9];
  106.  
  107. #ifdef DEU_DOS
  108.   strupr(filename);
  109. #endif
  110.  
  111.   /* ignore the file if it doesn't exist */
  112.   if (! Exists(filename))
  113.     {
  114.       printf("Warning: patch WAD file \"%s\" doesn't exist.  Ignored.\n", filename);
  115.       return;
  116.     }
  117.  
  118.   /* open the wad file */
  119.   if (Config.verbose == TRUE)
  120.     printf("Loading patch WAD file: %s...\n", filename);
  121.   wad = BasicWadOpen(filename);
  122.   /* Check if the file is a PWAD or DWAD (Hi Bernt!) */
  123.   if (strncmp(wad->type, "PWAD", 4) && strncmp(wad->type, "DWAD", 4))
  124.     ProgError("\"%s\" is not a patch WAD file", filename);
  125.  
  126.   /* alter the master directory */
  127.   /*! This should be changed - RQ */
  128.   l = 0;
  129.   for (n = 0; n < wad->dirsize; n++)
  130.     {
  131.       strncpy(entryname, wad->directory[n].name, 8);
  132.       entryname[8] = '\0';
  133.       if (l == 0)
  134.         {
  135.           mdir = FindMasterDir(MasterDir, wad->directory[n].name);
  136.           /* if this entry is not in the master directory, then add it */
  137.           if (mdir == NULL)
  138.             {
  139.               printf("   [Adding new entry %s]\n", entryname);
  140.               mdir = MasterDir;
  141.               while (mdir->next)
  142.                 mdir = mdir->next;
  143.               mdir->next = (MDirPtr) GetMemory(sizeof(struct MasterDirectory));
  144.               mdir = mdir->next;
  145.               mdir->next = NULL;
  146.             }
  147.           /* if this is a level, then copy this entry and the next 10 */
  148.           else if ((wad->directory[n].name[0] == 'E' && wad->directory[n].name[2] == 'M' && wad->directory[n].name[4] == '\0')
  149.                 || (wad->directory[n].name[0] == 'M' && wad->directory[n].name[1] == 'A' && wad->directory[n].name[2] == 'P' && wad->directory[n].name[5] == '\0'))
  150.             {
  151.               printf("   [Updating level %s]\n", entryname);
  152.               l = 10;
  153.             }
  154.           else
  155.             printf("   [Updating entry %s]\n", entryname);
  156.         }
  157.       else
  158.         {
  159.           mdir = mdir->next;
  160.           /* the level data should replace an existing level */
  161.           if (mdir == NULL || strncmp(mdir->dir.name, wad->directory[n].name, 8))
  162.             ProgError("\\%s\" is not an understandable PWAD file (error with %s)", filename, entryname);
  163.           l--;
  164.         }
  165.       mdir->wadfile = wad;
  166.       memcpy(&(mdir->dir), &(wad->directory[n]), sizeof(struct Directory));
  167.     }
  168. }
  169.  
  170.  
  171.  
  172. /*
  173.    Close all the wad files, deallocating the WAD file structures.
  174. */
  175.  
  176. void CloseWadFiles(void)
  177. {
  178.   WadPtr curw, nextw;
  179.   MDirPtr curd, nextd;
  180.  
  181.   /* close the wad files */
  182.   curw = WadFileList;
  183.   WadFileList = NULL;
  184.   while (curw)
  185.     {
  186.       nextw = curw->next;
  187.       fclose(curw->fileinfo);
  188.       FreeMemory(curw->directory);
  189.       FreeMemory(curw);
  190.       curw = nextw;
  191.     }
  192.  
  193.   /* delete the master directory */
  194.   curd = MasterDir;
  195.   MasterDir = NULL;
  196.   while (curd)
  197.     {
  198.       nextd = curd->next;
  199.       FreeMemory(curd);
  200.       curd = nextd;
  201.     }
  202. }
  203.  
  204.  
  205.  
  206. /*
  207.    Forget unused patch wad files.
  208. */
  209.  
  210. void CloseUnusedWadFiles(void)
  211. {
  212.   WadPtr curw, prevw;
  213.   MDirPtr mdir;
  214.  
  215.   prevw = NULL;
  216.   curw = WadFileList;
  217.   while (curw)
  218.     {
  219.       /* check if the wad file is used by a directory entry */
  220.       mdir = MasterDir;
  221.       while (mdir && mdir->wadfile != curw)
  222.         mdir = mdir->next;
  223.       if (mdir)
  224.         prevw = curw;
  225.       else
  226.         {
  227.           /* if this wad file is never used, close it */
  228.           if (prevw)
  229.             prevw->next = curw->next;
  230.           else
  231.             WadFileList = curw->next;
  232.           fclose(curw->fileinfo);
  233.           FreeMemory(curw->directory);
  234.           FreeMemory(curw);
  235.         }
  236.       curw = prevw->next;
  237.     }
  238. }
  239.  
  240.  
  241.  
  242. /*
  243.    Basic opening of WAD file and creation of node in Wad linked list.
  244. */
  245.  
  246. WadPtr BasicWadOpen(char *filename)
  247. {
  248.   WadPtr curw, prevw;
  249. #ifdef FAT_ENDIAN
  250.   int    i;
  251. #endif
  252.  
  253.   /* find the wad file in the wad file list */
  254.   prevw = WadFileList;
  255.   if (prevw)
  256.     {
  257.       curw = prevw->next;
  258.       while (curw && strcmp(filename, curw->filename))
  259.         {
  260.           prevw = curw;
  261.           curw = prevw->next;
  262.         }
  263.    }
  264.   else
  265.     curw = NULL;
  266.  
  267.   /* if this entry doesn't exist, add it to the WadFileList */
  268.   if (curw == NULL)
  269.     {
  270.       curw = (WadPtr) GetMemory(sizeof(struct WadFileInfo));
  271.       if (prevw == NULL)
  272.         WadFileList = curw;
  273.       else
  274.         prevw->next = curw;
  275.       curw->next = NULL;
  276.       curw->filename = filename;
  277.     }
  278.  
  279.   /* open the file */
  280.   if ((curw->fileinfo = fopen(filename, "rb")) == NULL)
  281.     {
  282.       if (!prevw)
  283.         {
  284.           WadFileList = NULL;
  285.         }
  286.       else
  287.         {
  288.           prevw->next = curw->next;
  289.         }
  290.       FreeMemory(curw);
  291.       ProgError("error opening \"%s\"", filename);
  292.     }
  293.   /* read in the WAD directory info */
  294.   BasicWadRead(curw, curw->type, 4L);
  295.   /* check if the file is the IWAD or a PWAD */
  296.   if (strncmp(curw->type + 1, "WAD", 3))
  297.     ProgError("\"%s\" is not a valid WAD file", filename);
  298.   WadReadInt32(curw, &curw->dirsize);
  299.   WadReadInt32(curw, &curw->dirstart);
  300.  
  301.   /* read in the WAD directory itself */
  302.   curw->directory = (DirPtr) GetMemory(sizeof(struct Directory) * curw->dirsize);
  303.   BasicWadSeek(curw, curw->dirstart);
  304.   BasicWadRead(curw, curw->directory, sizeof(struct Directory) * curw->dirsize);
  305. #ifdef FAT_ENDIAN
  306.   /* swap all integers read from the directory */
  307.   for (i = 0; i < curw->dirsize; i++)
  308.     {
  309.       curw->directory[i].start = (Int32) SwapInt32(curw->directory[i].start);
  310.       curw->directory[i].size = (Int32) SwapInt32(curw->directory[i].size);
  311.     }
  312. #endif
  313.  
  314.   /* all done */
  315.   return curw;
  316. }
  317.  
  318.  
  319.  
  320. /*
  321.    Read bytes from a file and store it into an address with error checking.
  322. */
  323.  
  324. void BasicWadRead(WadPtr wadfile, void huge *addr, long size)
  325. {
  326.   if (fread(addr, 1, size, wadfile->fileinfo) != size)
  327.     ProgError("error reading from \"%s\"", wadfile->filename);
  328. }
  329.  
  330.  
  331.  
  332. /*
  333.    Go to offset of wad file with error checking.
  334. */
  335.  
  336. void BasicWadSeek(WadPtr wadfile, long offset)
  337. {
  338.   if (fseek(wadfile->fileinfo, offset, 0))
  339.     ProgError("error reading from \"%s\"", wadfile->filename);
  340. }
  341.  
  342.  
  343.  
  344. /*
  345.    Find an entry in the master directory.
  346. */
  347.  
  348. MDirPtr FindMasterDir(MDirPtr from, char *name)
  349. {
  350.   while (from)
  351.     {
  352.       if (!strncmp(from->dir.name, name, 8))
  353.         break;
  354.       from = from->next;
  355.     }
  356.   return from;
  357. }
  358.  
  359.  
  360. /*
  361.    List the master directory.
  362. */
  363.  
  364. void ListMasterDirectory(FILE *file)
  365. {
  366.   char    dataname[9];
  367.   MDirPtr dir;
  368.   char    key;
  369.   Int16   lines = 3;
  370.  
  371.   dataname[8] = '\0';
  372.   fprintf(file, "The Master Directory\n");
  373.   fprintf(file, "====================\n\n");
  374.   fprintf(file, "NAME____  FILE________________  SIZE__  START____\n");
  375.   for (dir = MasterDir; dir; dir = dir->next)
  376.     {
  377.       strncpy(dataname, dir->dir.name, 8);
  378.       fprintf(file, "%-8s  %-20s  %6ld  x%08lx\n", dataname, dir->wadfile->filename, dir->dir.size, dir->dir.start);
  379.       if (file == stdout && lines++ > 21)
  380.         {
  381.           lines = 0;
  382.           printf("[Q to abort, any other key to continue]");
  383.           key = getchar();
  384.           printf("\r                                       \r");
  385.           if (key == 'Q' || key == 'q')
  386.             break;
  387.         }
  388.     }
  389. }
  390.  
  391.  
  392. /*
  393.    List the directory of a file.
  394. */
  395.  
  396. void ListFileDirectory(FILE *file, WadPtr wad)
  397. {
  398.   char   dataname[9];
  399.   char   key;
  400.   Int16  lines = 5;
  401.   UInt32 n;
  402.  
  403.   dataname[8] = '\0';
  404.   fprintf(file, "WAD File Directory\n");
  405.   fprintf(file, "==================\n\n");
  406.   fprintf(file, "Wad File: %s\n\n", wad->filename);
  407.   fprintf(file, "NAME____  SIZE__  START____  END______\n");
  408.   for (n = 0; n < wad->dirsize; n++)
  409.     {
  410.       strncpy(dataname, wad->directory[n].name, 8);
  411.       fprintf(file, "%-8s  %6ld  x%08lx  x%08lx\n", dataname, wad->directory[n].size, wad->directory[n].start, wad->directory[n].size + wad->directory[n].start - 1);
  412.       if (file == stdout && lines++ > 21)
  413.         {
  414.           lines = 0;
  415.           printf("[Q to abort, any other key to continue]");
  416.           key = getchar();
  417.           printf("\r                                       \r");
  418.           if (key == 'Q' || key == 'q')
  419.             break;
  420.         }
  421.     }
  422. }
  423.  
  424.  
  425. /* Note from R.Q. (Jan 95):
  426.     The following function should be replaced by a new BuildCompoundWad
  427.     function, which takes two arguments: the new file name and a list of
  428.     WadPtrs.  BuildCompoundWad will create a new file by copying all entries
  429.     from the WAD files given in the WadPtr list.  If the list contains the
  430.     WadPtr for the main WAD (IWAD), then a new IWAD will be rebuilt.
  431.     This new funtion will not use the master directory, so the entries will
  432.     have to be re-ordered according to the IWAD directory, with the _first_
  433.     WadPtr in the list taking precedence if some entries are duplicated.
  434. */
  435.  
  436. /*
  437.    Build a new wad file from master directory.
  438. */
  439.  
  440. void BuildNewMainWad(char *filename, Bool patchonly)
  441. {
  442.   FILE   *file;
  443.   UInt32  counter = 12;
  444.   MDirPtr cur;
  445.   UInt32  size;
  446.   UInt32  dirstart;
  447.   UInt32  dirnum;
  448.  
  449.   /* open the file and store signatures */
  450.   if (patchonly)
  451.     printf("Building a compound Patch Wad file \"%s\".\n", filename);
  452.   else
  453.     printf("Building a new Main Wad file \"%s\" (size approx 10000K)\n", filename);
  454.   if (FindMasterDir(MasterDir, "E2M4") == NULL && FindMasterDir(MasterDir, "MAP24") == NULL)
  455.     ProgError("You were warned: you are not allowed to do this.");
  456.   if ((file = fopen(filename, "wb")) == NULL)
  457.     ProgError("unable to open file \"%s\"", filename);
  458.   if (patchonly)
  459.     WriteBytes(file, "PWAD", 4);
  460.   else
  461.     WriteBytes(file, "IWAD", 4);
  462.   WriteInt32(file, &counter);      /* put true value in later */
  463.   WriteInt32(file, &counter);      /* put true value in later */
  464.  
  465.   /* output the directory data chuncks */
  466.   for (cur = MasterDir; cur; cur = cur->next)
  467.     {
  468.       if (patchonly && cur->wadfile == WadFileList)
  469.         continue;
  470.       size = cur->dir.size;
  471.       counter += size;
  472.       BasicWadSeek(cur->wadfile, cur->dir.start);
  473.       CopyBytes(file, cur->wadfile->fileinfo, size);
  474.       printf("Size: %ldK\r", counter / 1024);
  475.     }
  476.  
  477.   /* output the directory */
  478.   dirstart = counter;
  479.   counter = 12;
  480.   dirnum = 0;
  481.   for (cur = MasterDir; cur; cur = cur->next)
  482.     {
  483.       if (patchonly && cur->wadfile == WadFileList)
  484.         continue;
  485.       if (dirnum % 100 == 0)
  486.         printf("Outputting directory %04ld...\r", dirnum);
  487.       if (cur->dir.start)
  488.         WriteInt32(file, &counter);
  489.       else
  490.         WriteInt32(file, &(cur->dir.start));
  491.       WriteInt32(file, &(cur->dir.size));
  492.       WriteBytes(file, &(cur->dir.name), 8L);
  493.       counter += cur->dir.size;
  494.       dirnum++;
  495.     }
  496.  
  497.   /* fix up the number of entries and directory start information */
  498.   if (fseek(file, 4L, 0))
  499.     ProgError("error writing to file");
  500.   WriteInt32(file, &dirnum);
  501.   WriteInt32(file, &dirstart);
  502.  
  503.   /* close the file */
  504.   printf("                            \r");
  505.   fclose(file);
  506. }
  507.  
  508.  
  509. /*
  510.    Output bytes to a binary file with error checking.
  511. */
  512.  
  513. void WriteBytes(FILE *file, void huge *addr, long size)
  514. {
  515.   if (DoomVersion < 1)
  516.     return;
  517.   while (size > 0x8000)
  518.     {
  519.       if (fwrite(addr, 1, 0x8000, file) != 0x8000)
  520.         ProgError("error writing to file");
  521.       addr = (char huge *)addr + 0x8000;
  522.       size -= 0x8000;
  523.     }
  524.   if (fwrite(addr, 1, size, file) != size)
  525.     ProgError("error writing to file");
  526. }
  527.  
  528.  
  529.  
  530. /*
  531.    Copy bytes from a binary file to another with error checking.
  532. */
  533.  
  534. void CopyBytes(FILE *dest, FILE *source, long size)
  535. {
  536.   void huge *data;
  537.  
  538.   data = GetFarMemory(0x8000 + 2);
  539.   while (size > 0x8000)
  540.     {
  541.       if (DoomVersion > 0)
  542.         if (fread(data, 1, 0x8000, source) != 0x8000)
  543.           ProgError("error reading from file");
  544.       if (fwrite(data, 1, 0x8000, dest) != 0x8000)
  545.         ProgError("error writing to file");
  546.       size -= 0x8000;
  547.     }
  548.   if (DoomVersion > 0)
  549.     if (fread(data, 1, size, source) != size)
  550.       ProgError("error reading from file");
  551.   if (fwrite(data, 1, size, dest) != size)
  552.     ProgError("error writing to file");
  553.   FreeFarMemory(data);
  554. }
  555.  
  556.  
  557. /*
  558.    Dump a directory entry in hex.
  559. */
  560.  
  561. void DumpDirectoryEntry(FILE *file, char *entryname)
  562. {
  563.   MDirPtr entry;
  564.   char    dataname[9];
  565.   char    key;
  566.   int     lines = 5;
  567.   UInt32  n, c, i;
  568.   UInt8   buf[16];
  569.  
  570.   c = 0L;
  571.   entry = MasterDir;
  572.   while (entry)
  573.     {
  574.       if (!strnicmp(entry->dir.name, entryname, 8))
  575.         {
  576.           strncpy(dataname, entry->dir.name, 8);
  577.           dataname[8] = '\0';
  578.           fprintf(file, "Contents of entry %s (size = %ld bytes):\n", dataname, entry->dir.size);
  579.           BasicWadSeek(entry->wadfile, entry->dir.start);
  580.           n = 0L;
  581.           for (c = 0L; c < entry->dir.size; c += 16L)
  582.             {
  583.               fprintf(file, "%04lX: ", n);
  584.               for (i = 0L; i < 16L; i++)
  585.                 {
  586.                   BasicWadRead(entry->wadfile, &(buf[i]), 1);
  587.                   fprintf(file, " %02X", buf[i]);
  588.                   n++;
  589.                 }
  590.               fprintf(file, "   ");
  591.               for (i = 0L; i < 16L; i++)
  592.                 {
  593.                   if (buf[i] >= ' ')
  594.                     fprintf(file, "%c", buf[i]);
  595.                   else
  596.                     fprintf(file, " ");
  597.                 }
  598.               fprintf(file, "\n");
  599.               if (file == stdout && lines++ > 21)
  600.                 {
  601.                   lines = 0;
  602.                   printf("[%ld%% - Q to abort, S to skip this entry, any other key to continue]", n * 100 / entry->dir.size);
  603.                   key = getchar();
  604.                   printf("\r                                                                    \r");
  605.                   if (key == 'S' || key == 's')
  606.                     break;
  607.                   if (key == 'Q' || key == 'q')
  608.                     return;
  609.                 }
  610.             }
  611.         }
  612.       entry = entry->next;
  613.     }
  614.   if (! c)
  615.     {
  616.       printf("[Entry not in master directory]\n");
  617.       return;
  618.     }
  619. }
  620.  
  621.  
  622. /*
  623.    Save a directory entry to disk.
  624. */
  625.  
  626. void SaveDirectoryEntry(FILE *file, char *entryname)
  627. {
  628.   MDirPtr entry;
  629.   UInt32  counter;
  630.   UInt32  size;
  631.  
  632.   for (entry = MasterDir; entry; entry = entry->next)
  633.     if (!strnicmp(entry->dir.name, entryname, 8))
  634.       break;
  635.   if (entry)
  636.     {
  637.       WriteBytes(file, "PWAD", 4L);     /* PWAD file */
  638.       counter = 1L;
  639.       WriteInt32(file, &counter);       /* 1 entry */
  640.       counter = 12L;
  641.       WriteInt32(file, &counter);
  642.       counter = 28L;
  643.       WriteInt32(file, &counter);
  644.       size = entry->dir.size;
  645.       WriteInt32(file, &size);
  646.       WriteBytes(file, &(entry->dir.name), 8L);
  647.       BasicWadSeek(entry->wadfile, entry->dir.start);
  648.       CopyBytes(file, entry->wadfile->fileinfo, size);
  649.     }
  650.   else
  651.     {
  652.       printf("[Entry not in master directory]\n");
  653.       return;
  654.     }
  655. }
  656.  
  657.  
  658. /*
  659.    Save a directory entry to disk, without a PWAD header.
  660. */
  661.  
  662. void SaveEntryToRawFile(FILE *file, char *entryname)
  663. {
  664.   MDirPtr entry;
  665.  
  666.   for (entry = MasterDir; entry; entry = entry->next)
  667.     if (!strnicmp(entry->dir.name, entryname, 8))
  668.       break;
  669.   if (entry)
  670.     {
  671.       BasicWadSeek(entry->wadfile, entry->dir.start);
  672.       CopyBytes(file, entry->wadfile->fileinfo, entry->dir.size);
  673.     }
  674.   else
  675.     {
  676.       printf("[Entry not in master directory]\n");
  677.       return;
  678.     }
  679. }
  680.  
  681.  
  682. /*
  683.    Encapsulate a raw file in a PWAD file.
  684. */
  685.  
  686. void SaveEntryFromRawFile(FILE *file, FILE *raw, char *entryname)
  687. {
  688.   UInt32 counter;
  689.   Int32  size;
  690.   char   name8[8];
  691.  
  692.   for (counter = 0L; counter < 8L; counter++)
  693.     name8[counter] = '\0';
  694.   strncpy(name8, entryname, 8);
  695.   WriteBytes(file, "PWAD", 4L);     /* PWAD file */
  696.   counter = 1L;
  697.   WriteInt32(file, &counter);       /* 1 entry */
  698.   counter = 12L;
  699.   WriteInt32(file, &counter);
  700.   counter = 28L;
  701.   WriteInt32(file, &counter);
  702.   if (fseek(raw, 0L, SEEK_END) != 0)
  703.     ProgError("error reading from raw file");
  704.   size = ftell(raw);
  705.   if (size < 0L)
  706.     ProgError("error reading from raw file");
  707.   if (fseek(raw, 0L, SEEK_SET) != 0)
  708.     ProgError("error reading from raw file");
  709.   WriteInt32(file, (UInt32 *) &size);
  710.   WriteBytes(file, name8, 8L);
  711.   CopyBytes(file, raw, size);
  712. }
  713.  
  714.  
  715.  
  716. #ifdef FAT_ENDIAN
  717. UInt16 SwapInt16(UInt16 x)
  718. {
  719.   return ((x<<8) & 0xff00) | ((x>>8) & 0x00ff);
  720. }
  721.  
  722.  
  723. UInt32 SwapInt32(UInt32 x)
  724. {
  725.   return (((x << 24) & 0xff000000)
  726.           | ((x<< 8) & 0x00ff0000)
  727.           | ((x>> 8) & 0x0000ff00)
  728.           | ((x>>24) & 0x000000ff));
  729. }
  730.  
  731.  
  732. void WadReadInt16(WadPtr wadfile, UInt16 huge *x)
  733. {
  734.   BasicWadRead(wadfile, x, 2L);
  735.   *x = SwapInt16(*x);
  736. }
  737.  
  738.  
  739. void WadReadInt32(WadPtr wadfile, UInt32 huge *x)
  740. {
  741.   BasicWadRead(wadfile, x, 4L);
  742.   *x = SwapInt32(*x);
  743. }
  744.  
  745.  
  746. void WriteInt16(FILE *file, UInt16 huge *x)
  747. {
  748.   UInt16 n;
  749.  
  750.   n = SwapInt16(*x);
  751.   WriteBytes(file, &n, 2L);
  752. }
  753.  
  754.  
  755. void WriteInt32(FILE *file, UInt32 huge *x)
  756. {
  757.   UInt32 n;
  758.  
  759.   n = SwapInt32(*x);
  760.   WriteBytes(file, &n, 4L);
  761. }
  762. #endif /* FAT_ENDIAN */
  763.  
  764. /* end of file */
  765.