home *** CD-ROM | disk | FTP | other *** search
/ Toolkit for DOOM / DOOMTOOL.ISO / editors / dme301.zip / SOURCE.ZIP / WAD.C < prev   
C/C++ Source or Header  |  1994-07-25  |  19KB  |  793 lines

  1. /*
  2.     This is a DMapEdit source code module.  Though it is copyrighted, you
  3.     may modify it and use it for your own personal use, meaning that new
  4.     modified code and anything derived from it (such as exe files) doesn't
  5.     get distributed to anyone, unless you get my permission first.  Code
  6.     from this file, or code based on ideas from this file may be used with
  7.     other programs, provided that you give credit for it in the source code,
  8.     documentation, and 'about' windows or screens, if one exists, for the
  9.     programs using it.  Giving credit means something like this:
  10.  
  11.     Code from DMapEdit was used in this program
  12.  
  13.                               or
  14.  
  15.     Some code for this program was based on ideas presented in DMapEdit
  16.  
  17.     Whatever.  Just be sure to mention "DMapEdit" in such a way that it's
  18.     self-evident how it was useful to the new program, and be sure to have
  19.     "DMapEdit is a trademark of Jason Hoffoss" in the docs.  That's all..
  20. */
  21.  
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include "dme.h"
  25. #include "dme2.h"
  26.  
  27. int entry_num;
  28.  
  29. int open_wad(char *name, char *fmode)
  30. {
  31.     fp = fopen(name, fmode);
  32.     if (!fp)
  33.         return -1;
  34.  
  35.     if (verify_wad())
  36.         fatal_error("WAD file corrupt");
  37.  
  38.     fread(&entry_count, 4, 1, fp);
  39.     dir_size = entry_count;
  40.     fread(&dir_ptr, 4, 1, fp);
  41.     fseek(fp, dir_ptr, SEEK_SET);
  42.     return entry_num = 0;
  43. }
  44.  
  45. int open_wad_seek(char *fmode, char *entry)
  46. {
  47.     if (editing_pwad)
  48.     {
  49.         if (open_wad(pwad, fmode))
  50.             fatal_error("open_wad_seek() can't find PWAD");
  51.         if (!wad_seek(entry))
  52.             return 0;
  53.     }
  54.     open_wad(iwad, fmode);
  55.     return wad_seek(entry);
  56. }
  57.  
  58. int open_wad_seekto(char *fmode, char *entry)
  59. {
  60.     if (open_wad_seek(fmode, entry))
  61.         return -1;
  62.     fseek(fp, entry_ptr, SEEK_SET);
  63.     return 0;
  64. }
  65.  
  66. int open_iwad_seek(char *fmode, char *entry)
  67. {
  68.     open_wad(iwad, fmode);
  69.     return wad_seek(entry);
  70. }
  71.  
  72. /* open pwad or iwad and position file pointer to map header */
  73.  
  74. void open_wad_seek_map(char *fmode, int which)
  75. {
  76.     static char header[5];
  77.  
  78.     sprintf(header, "E%dM%d", episode, mission);
  79.  
  80.     if (which)
  81.         which = open_iwad_seek(fmode, header);
  82.     else
  83.         which = open_wad_seek(fmode, header);
  84.  
  85.     if (which)
  86.         fatal_error("\"%s\" not found in IWAD", header);
  87.  
  88.     return;
  89. }
  90.  
  91. int wad_seek(char *entry)
  92. {
  93.     struct
  94.     {
  95.         long ptr;
  96.         long len;
  97.         char fname[8];
  98.     } dir;
  99.  
  100.     while (entry_count--)
  101.     {
  102.         if (!fread(&dir, sizeof(dir), 1, fp))
  103.             dir_error();
  104.         if (!cmp_entry(entry, dir.fname))
  105.         {
  106.             entry_ptr = dir.ptr;
  107.             entry_len = dir.len;
  108.             return 0;
  109.         }
  110.         entry_num++;
  111.     }
  112.     return -1;
  113. }
  114.  
  115. void load_pwad_startup(void)
  116. {
  117.     char maps[27];
  118.     int i, temp;
  119.  
  120.     struct
  121.     {
  122.         long ptr;
  123.         long len;
  124.         char fname[8];
  125.     } dir;
  126.  
  127.     if (!editing_pwad)
  128.     {
  129.         load_wad_map(1);
  130.         return;
  131.     }
  132.  
  133.     for (i=0; i<27; i++)
  134.         maps[i] = 0;
  135.  
  136.     if (open_wad(pwad, "rb"))
  137.         fatal_error("Can't open \"%s\"", pwad);
  138.  
  139.     for (i=0; i<dir_size; i++)
  140.     {
  141.         if (!fread(&dir, sizeof(dir), 1, fp))
  142.             dir_error();
  143.         if (dir.len)
  144.             continue;
  145.         if (dir.fname[0] != 'E')
  146.             continue;
  147.         if (dir.fname[2] != 'M')
  148.             continue;
  149.         if (dir.fname[4])
  150.             continue; /* at this point, we know it's a map header */
  151.         temp = (dir.fname[1] - '1') * 9 + (dir.fname[3] - '1');
  152.         if (temp > 26)
  153.             dir_error(); /* just in case, cause you never know */
  154.         maps[temp] = 1;
  155.     }
  156.     fclose(fp);
  157.  
  158.     if (!maps[episode*9 + mission])
  159.         for (i=0; i<27; i++)
  160.             if (maps[i])
  161.             {
  162.                 episode = i / 9 + 1;
  163.                 mission = i % 9 + 1;
  164.         }
  165.     load_wad_map(0);
  166.     return;
  167. }
  168.  
  169. void load_wad_map(int which) /* load map info from wad file */
  170. {
  171.     int i;
  172.  
  173.     struct {
  174.         long ptr;
  175.         long len;
  176.         char fname[8];
  177.     } dir[10];
  178.  
  179.     clear_map();
  180.     window_text("Loading map from WAD file, please wait..\n", 1);
  181.     open_wad_seek_map("rb", which);
  182.     fread(dir, 16, 10, fp);
  183.     for (i=0; i<10; i++)
  184.         if (cmp_entry(dir[i].fname, subfiles[i]))
  185.             dir_error();
  186.  
  187.     things = get_farmem(dir[0].len, "Things");
  188.     t_size = t_max = dir[0].len / sizeof(struct t_struct);
  189.     fseek(fp, dir[0].ptr, SEEK_SET);
  190.     if (far_read(things, dir[0].len))
  191.         rd_error();
  192.  
  193.     linedefs = get_farmem(dir[1].len, "Linedefs");
  194.     l_size = l_max = dir[1].len / sizeof(struct l_struct);
  195.     fseek(fp, dir[1].ptr, SEEK_SET);
  196.     if (far_read(linedefs, dir[1].len))
  197.         rd_error();
  198.  
  199.     sidedefs = get_farmem(dir[2].len, "Sidedefs");
  200.     s_size = s_max = dir[2].len / sizeof(struct s_struct);
  201.     fseek(fp, dir[2].ptr, SEEK_SET);
  202.     if (far_read(sidedefs, dir[2].len))
  203.         rd_error();
  204.  
  205.     vertexes = get_farmem(dir[3].len, "Vertexes");
  206.     v_size = v_max = dir[3].len / sizeof(struct v_struct);
  207.     fseek(fp, dir[3].ptr, SEEK_SET);
  208.     if (far_read(vertexes, dir[3].len))
  209.         rd_error();
  210.  
  211.     segs = get_farmem(dir[4].len, "Segments");
  212.     seg_size = seg_max = dir[4].len / sizeof(struct seg_struct);
  213.     fseek(fp, dir[4].ptr, SEEK_SET);
  214.     if (far_read(segs, dir[4].len))
  215.         rd_error();
  216.  
  217.     ssectors = get_farmem(dir[5].len, "Sub Sectors");
  218.     ss_size = ss_max = dir[5].len / sizeof(struct ss_struct);
  219.     fseek(fp, dir[5].ptr, SEEK_SET);
  220.     if (far_read(ssectors, dir[5].len))
  221.         rd_error();
  222.  
  223.     nodes = get_farmem(dir[6].len, "Nodes");
  224.     n_size = n_max = dir[6].len / sizeof(struct n_struct);
  225.     fseek(fp, dir[6].ptr, SEEK_SET);
  226.     if (far_read(nodes, dir[6].len))
  227.         rd_error();
  228.  
  229.     sectors = get_farmem(dir[7].len, "Sectors");
  230.     sec_size = sec_max = dir[7].len / sizeof(struct sec_struct);
  231.     fseek(fp, dir[7].ptr, SEEK_SET);
  232.     if (far_read(sectors, dir[7].len))
  233.         rd_error();
  234.  
  235.     reject = get_farmem(r_size = dir[8].len, "Reject bitmap");
  236.     fseek(fp, dir[8].ptr, SEEK_SET);
  237.     if (far_read(reject, r_size))
  238.         rd_error();
  239.  
  240.     blockmap = get_farmem(b_size = dir[9].len, "Blockmap");
  241.     fseek(fp, dir[9].ptr, SEEK_SET);
  242.     if (far_read(blockmap, b_size))
  243.         rd_error();
  244.  
  245.     fclose(fp);
  246.     center_map();
  247.     return;
  248. }
  249.  
  250. void save_to_wad(int get_name) /* save map info to a pwad file */
  251. {
  252.     char header[5], name[9];
  253.     int i;
  254.  
  255.     struct {
  256.         long ptr;
  257.         long len;
  258.         char fname[8];
  259.     } dir[10];
  260.  
  261.     fix_wadname(pwad);
  262.     strcat(pwad, ".WAD");
  263.     if (get_name || !editing_pwad)
  264.         if (get_wadname("Save", "to"))
  265.             return;
  266.  
  267.     if (open_wad(pwad, "rb+"))
  268.     {
  269.         make_new_wad(); /* it's a new pwad */
  270.         return;
  271.     }
  272.  
  273.     sprintf(header, "E%dM%d", episode, mission);
  274.     if (wad_seek(header))
  275.     {
  276.         remake_wad(1); /* it's a new map in existing pwad */
  277.         return;
  278.     }
  279.  
  280.     if (fread(dir, 16, 10, fp) != 10)
  281.         rd_error();
  282.     for (i=0; i<10; i++)
  283.         if (cmp_entry(dir[i].fname, subfiles[i]))
  284.             dir_error();
  285.  
  286.     if ((long) t_size * sizeof(things[0]) == dir[0].len &&
  287.         (long) l_size * sizeof(linedefs[0]) == dir[1].len &&
  288.         (long) s_size * sizeof(sidedefs[0]) == dir[2].len &&
  289.         (long) v_size * sizeof(vertexes[0]) == dir[3].len &&
  290.         (long) seg_size * sizeof(segs[0]) == dir[4].len &&
  291.         (long) ss_size * sizeof(ssectors[0]) == dir[5].len &&
  292.         (long) n_size * sizeof(nodes[0]) == dir[6].len &&
  293.         (long) sec_size * sizeof(sectors[0]) == dir[7].len &&
  294.         r_size == dir[8].len &&
  295.         b_size == dir[9].len) /* size hasn't changed, just overwrite old */
  296.     {
  297.         window_text("Saving map to WAD file, please wait..\n", 1);
  298.         fseek(fp, dir[0].ptr, SEEK_SET);
  299.         if (far_write(things, dir[0].len))
  300.             wr_error();
  301.  
  302.         fseek(fp, dir[1].ptr, SEEK_SET);
  303.         if (far_write(linedefs, dir[1].len))
  304.             wr_error();
  305.  
  306.         fseek(fp, dir[2].ptr, SEEK_SET);
  307.         if (far_write(sidedefs, dir[2].len))
  308.             wr_error();
  309.  
  310.         fseek(fp, dir[3].ptr, SEEK_SET);
  311.         if (far_write(vertexes, dir[3].len))
  312.             wr_error();
  313.  
  314.         fseek(fp, dir[4].ptr, SEEK_SET);
  315.         if (far_write(segs, dir[4].len))
  316.             wr_error();
  317.  
  318.         fseek(fp, dir[5].ptr, SEEK_SET);
  319.         if (far_write(ssectors, dir[5].len))
  320.             wr_error();
  321.  
  322.         fseek(fp, dir[6].ptr, SEEK_SET);
  323.         if (far_write(nodes, dir[6].len))
  324.             wr_error();
  325.  
  326.         fseek(fp, dir[7].ptr, SEEK_SET);
  327.         if (far_write(sectors, dir[7].len))
  328.             wr_error();
  329.  
  330.         fseek(fp, dir[8].ptr, SEEK_SET);
  331.         if (far_write(reject, dir[8].len))
  332.             wr_error();
  333.  
  334.         fseek(fp, dir[9].ptr, SEEK_SET);
  335.         if (far_write(blockmap, dir[9].len))
  336.             wr_error();
  337.  
  338.         rewind(fp);
  339.         fputc('P', fp); /* this informs doom that this wad is modified */
  340.         fclose(fp);
  341.         draw_map();
  342.         return;
  343.     }
  344.     remake_wad(0);
  345.     return;
  346. }
  347.  
  348. void make_new_wad(void)
  349. {
  350.     char buffer[256], *ident = "PWAD";
  351.     int i, j;
  352.     long offset;
  353.  
  354.     struct {
  355.         long ptr;
  356.         long len;
  357.         char fname[8];
  358.     } dir[11];
  359.  
  360.     sprintf(buffer,
  361.         "\"%s\" does not exist!  Do you want to\n"
  362.         "create this new WAD file?\n\n"
  363.         "[ Yes ]\t", pwad);
  364.     window_text(buffer, 1);
  365.     i = window_check();
  366.     draw_map();
  367.     await_release();
  368.     if (i != -2)
  369.         return;
  370.  
  371.     window_text("Creating new WAD file, please wait..\n", 1);
  372.  
  373.     fp = fopen(pwad, "wb");
  374.     if (!fp)
  375.         fatal_error("Can't create PWAD");
  376.  
  377.     dir[1].len = (long) t_size * sizeof(things[0]);
  378.     dir[2].len = (long) l_size * sizeof(linedefs[0]);
  379.     dir[3].len = (long) s_size * sizeof(sidedefs[0]);
  380.     dir[4].len = (long) v_size * sizeof(vertexes[0]);
  381.     dir[5].len = (long) seg_size * sizeof(segs[0]);
  382.     dir[6].len = (long) ss_size * sizeof(ssectors[0]);
  383.     dir[7].len = (long) n_size * sizeof(nodes[0]);
  384.     dir[8].len = (long) sec_size * sizeof(sectors[0]);
  385.     dir[9].len = r_size;
  386.     dir[10].len = b_size;
  387.     offset = 12L;
  388.  
  389.     sprintf(buffer, "E%dM%d", episode, mission);
  390.     buffer[5] = buffer[6] = buffer[7] = 0;
  391.     for (i=0; i<8; i++)
  392.         dir[0].fname[i] = buffer[i];
  393.     dir[0].ptr = dir[0].len = 0L;
  394.     for (i=1; i<11; i++)
  395.     {
  396.         for (j=0; j<8; j++)
  397.             if (!(dir[i].fname[j] = subfiles[i-1][j]))
  398.                 break;
  399.         while (j<8)
  400.             dir[i].fname[j++] = 0;
  401.         dir[i].ptr = offset;
  402.         offset += dir[i].len;
  403.     }
  404.  
  405.     if (!fwrite(ident, 4, 1, fp))
  406.         goto error;
  407.     if (fwrite_long(11L)) /* 11 entries in this new WAD file */
  408.         goto error;
  409.     if (!fwrite(&offset, 4, 1, fp))
  410.         goto error;
  411.  
  412.     if (far_write(things, dir[1].len))
  413.         goto error;
  414.     if (far_write(linedefs, dir[2].len))
  415.         goto error;
  416.     if (far_write(sidedefs, dir[3].len))
  417.         goto error;
  418.     if (far_write(vertexes, dir[4].len))
  419.         goto error;
  420.     if (far_write(segs, dir[5].len))
  421.         goto error;
  422.     if (far_write(ssectors, dir[6].len))
  423.         goto error;
  424.     if (far_write(nodes, dir[7].len))
  425.         goto error;
  426.     if (far_write(sectors, dir[8].len))
  427.         goto error;
  428.     if (far_write(reject, r_size))
  429.         goto error;
  430.     if (far_write(blockmap, b_size))
  431.         goto error;
  432.  
  433.     if (fwrite(dir, 16, 11, fp) != 11) /* write out directory structure */
  434.         goto error;
  435.     fclose(fp);
  436.     draw_map();
  437.     return;
  438.  
  439. error:
  440.     fclose(fp);
  441.     error("Failed on write to \"%s\"", pwad);
  442.     draw_map();
  443.     return;
  444. }
  445.  
  446. int remake_wad(int add)
  447. {
  448.     char buffer[4096], name2[13], *ident = "PWAD";
  449.     int i, j, cur_entry, xx, yy;
  450.     long len, new_ptr;
  451.  
  452.     struct {
  453.         long ptr;
  454.         long len;
  455.         char fname[8];
  456.     } far *dir, temp;
  457.  
  458.     window_text("Rebuilding WAD file, please wait..\n\n\n\n", 1);
  459.     yy = win.top + 19;
  460.     xx = draw_time_graph(yy);
  461.  
  462.     fseek(fp, dir_ptr, SEEK_SET); /* position to start of dir structure */
  463.     len = dir_size;
  464.     dir = get_farmem(dir_size * 16, "Wad directory");
  465.     for (i=0; i<len; i++) /* and get it */
  466.     {
  467.         if (!fread(&temp, 16, 1, fp))
  468.         {
  469.             free_farmem(dir, "Wad directory");
  470.             dir_error();
  471.         }
  472.         dir[i] = temp;
  473.     }
  474.     if (add)
  475.     {
  476.        entry_num = dir_size;
  477.         dir_size += 11;
  478.         sprintf(buffer, "E%dM%d", episode, mission);
  479.         buffer[5] = buffer[6] = buffer[7] = 0;
  480.         for (i=0; i<8; i++)
  481.             dir[len].fname[i] = buffer[i];
  482.         dir[len].ptr = dir[len].len = 0L;
  483.         for (i=1; i<11; i++)
  484.             for (j=0; j<8; j++)
  485.                 dir[len+i].fname[j] = subfiles[i-1][j];
  486.     }
  487.  
  488.     fp2 = fopen("wad.dme", "wb"); /* make destination wad */
  489.     if (!fp2)
  490.     {
  491.         error("Can't create backup WAD file");
  492.         goto gen_error;
  493.     }
  494.  
  495.     if (!fwrite(ident, 4, 1, fp2))
  496.         goto write_error;
  497.     if (!fwrite(&dir_size, 4, 1, fp2))
  498.         goto write_error;
  499.     if (!fwrite(&dir_ptr, 4, 1, fp2))
  500.         goto write_error;
  501.  
  502.     new_ptr = 12; /* current file offset */
  503.     for (cur_entry=0; cur_entry<dir_size; cur_entry++)
  504.     {
  505.         for (i=0; i<8; i++)
  506.             if (!(buffer[i] = dir[cur_entry].fname[i]))
  507.                 break;
  508.         while (i<8)
  509.             buffer[i++] = 0;
  510.         buffer[8] = 0;
  511.         erase_text(win.left + 108, win.top + 34, 8);
  512.         text(win.left + 140 - strlen(buffer)*4, win.top + 34, buffer);
  513.  
  514.         if (cur_entry == entry_num)
  515.         {
  516.             cur_entry++;
  517.  
  518.             len = (long) t_size * sizeof(things[0]);
  519.             if (write_wad_entry("THINGS", things, len, dir[cur_entry].fname))
  520.                 goto gen_error;
  521.             dir[cur_entry].ptr = new_ptr;
  522.             dir[cur_entry].len = len;
  523.             new_ptr += len;
  524.             cur_entry++;
  525.  
  526.             len = (long) l_size * sizeof(linedefs[0]);
  527.             if (write_wad_entry("LINEDEFS", linedefs, len, dir[cur_entry].fname))
  528.                 goto gen_error;
  529.             dir[cur_entry].ptr = new_ptr;
  530.             dir[cur_entry].len = len;
  531.             new_ptr += len;
  532.             cur_entry++;
  533.  
  534.             len = (long) s_size * sizeof(sidedefs[0]);
  535.             if (write_wad_entry("SIDEDEFS", sidedefs, len, dir[cur_entry].fname))
  536.                 goto gen_error;
  537.             dir[cur_entry].ptr = new_ptr;
  538.             dir[cur_entry].len = len;
  539.             new_ptr += len;
  540.             cur_entry++;
  541.  
  542.             len = (long) v_size * sizeof(vertexes[0]);
  543.             if (write_wad_entry("VERTEXES", vertexes, len, dir[cur_entry].fname))
  544.                 goto gen_error;
  545.             dir[cur_entry].ptr = new_ptr;
  546.             dir[cur_entry].len = len;
  547.             new_ptr += len;
  548.             cur_entry++;
  549.  
  550.             len = (long) seg_size * sizeof(segs[0]);
  551.             if (write_wad_entry("SEGS", segs, len, dir[cur_entry].fname))
  552.                 goto gen_error;
  553.             dir[cur_entry].ptr = new_ptr;
  554.             dir[cur_entry].len = len;
  555.             new_ptr += len;
  556.             cur_entry++;
  557.  
  558.             len = (long) ss_size * sizeof(ssectors[0]);
  559.             if (write_wad_entry("SSECTORS", ssectors, len, dir[cur_entry].fname))
  560.                 goto gen_error;
  561.             dir[cur_entry].ptr = new_ptr;
  562.             dir[cur_entry].len = len;
  563.             new_ptr += len;
  564.             cur_entry++;
  565.  
  566.             len = (long) n_size * sizeof(nodes[0]);
  567.             if (write_wad_entry("NODES", nodes, len, dir[cur_entry].fname))
  568.                 goto gen_error;
  569.             dir[cur_entry].ptr = new_ptr;
  570.             dir[cur_entry].len = len;
  571.             new_ptr += len;
  572.             cur_entry++;
  573.  
  574.             len = (long) sec_size * sizeof(sectors[0]);
  575.             if (write_wad_entry("SECTORS", sectors, len, dir[cur_entry].fname))
  576.                 goto gen_error;
  577.             dir[cur_entry].ptr = new_ptr;
  578.             dir[cur_entry].len = len;
  579.             new_ptr += len;
  580.             cur_entry++;
  581.  
  582.             if (write_wad_entry("REJECT", reject, (long) r_size,
  583.                 dir[cur_entry].fname))
  584.                     goto gen_error;
  585.             dir[cur_entry].ptr = new_ptr;
  586.             dir[cur_entry].len = r_size;
  587.             new_ptr += r_size;
  588.             cur_entry++;
  589.  
  590.             if (write_wad_entry("BLOCKMAP", blockmap, (long) b_size,
  591.                 dir[cur_entry].fname))
  592.                 goto gen_error;
  593.             dir[cur_entry].ptr = new_ptr;
  594.             dir[cur_entry].len = b_size;
  595.             new_ptr += b_size;
  596.             continue;
  597.         }
  598.         if (!dir[cur_entry].ptr || !dir[cur_entry].len)
  599.             continue; /* not a real subfile; only a marker */
  600.         fseek(fp, dir[cur_entry].ptr, SEEK_SET);
  601.         len = dir[cur_entry].len;
  602.  
  603.         while (len > 4096) /* transfer subfile to new wad */
  604.         {
  605.             if (fread(buffer, 1, 4096, fp) != 4096)
  606.             {
  607.                 free_farmem(dir, "Wad directory");
  608.                 rd_error();
  609.             }
  610.             if (fwrite(buffer, 1, 4096, fp2) != 4096)
  611.                 goto write_error;
  612.             len -= 4096;
  613.         }
  614.  
  615.         if (fread(buffer, 1, len, fp) != len)
  616.         {
  617.             free_farmem(dir, "Wad directory");
  618.             rd_error();
  619.         }
  620.         if (fwrite(buffer, 1, len, fp2) != len)
  621.             goto write_error;
  622.         dir[cur_entry].ptr = new_ptr;
  623.         new_ptr += dir[cur_entry].len;
  624.         time_graph(cur_entry, dir_size, xx, yy);
  625.     }
  626.     fclose(fp);
  627.     for (i=0; i<dir_size; i++)
  628.     {
  629.         temp = dir[i];
  630.         if (!fwrite(&temp, 16, 1, fp2))
  631.             goto write_error;
  632.     }
  633.     fclose(fp2);
  634.  
  635.     fp = fopen("wad.dme", "rb+");
  636.     fseek(fp, 8L, SEEK_SET);
  637.     if (!fwrite(&new_ptr, 4, 1, fp))
  638.         goto write_error;
  639.     fclose(fp);
  640.     free_farmem(dir, "Wad directory");
  641.  
  642.     if (backup)
  643.     {
  644.         strcpy(buffer, pwad);
  645.         strcpy(buffer+(strlen(buffer)-3), "bak"); /* change extention */
  646.         unlink(buffer);
  647.         rename(pwad, buffer);
  648.     } else {
  649.         unlink(pwad);
  650.     }
  651.     rename("wad.dme", pwad);
  652.     unlink("wad.dme");
  653.  
  654.     draw_map();
  655.     return 0;
  656.  
  657. write_error:
  658.     error("Failed on write to backup WAD file");
  659.  
  660. gen_error:
  661.     free_farmem(dir, "Wad directory");
  662.     return -1;
  663. }
  664.  
  665. void find_doom_wad(void)
  666. {
  667.     char header[5];
  668.     int found, i, j, len;
  669.     long dir_ptr;
  670.  
  671.     struct
  672.     {
  673.         long ptr;
  674.         long len;
  675.         char fname[8];
  676.     } dir;
  677.  
  678.     len = strlen(iwad);
  679.     while (len--)
  680.         if (iwad[len] == '/')
  681.             iwad[len] = '\\';
  682.  
  683.     if ((len = strlen(iwad)) && iwad[len-1] != ':')
  684.     {
  685.         if (iwad[len-1] != '\\')
  686.         {
  687.             if ((fp = fopen(iwad, "rb")) != NULL)
  688.             {
  689.                 if (verify_wad())
  690.                     fatal_error("WAD file corrupt");
  691.                 return;
  692.             }
  693.             iwad[len++] = '\\';
  694.             iwad[len] = 0;
  695.         }
  696.     }
  697.  
  698.     iwad[51] = 0;
  699.     strcat(iwad, "doom.wad");
  700.     if ((fp = fopen(iwad, "rb")) == NULL)
  701.     {
  702.         strcpy(iwad+(strlen(iwad)-4), "1.wad");
  703.         if ((fp = fopen(iwad, "rb")) == NULL)
  704.             fatal_error("Can't open Doom WAD file");
  705.     }
  706.  
  707.     if (verify_wad())
  708.         fatal_error("WAD file corrupt");
  709.  
  710.     fread(&entry_count, 4, 1, fp);
  711.     dir_size = entry_count;
  712.     fread(&dir_ptr, 4, 1, fp);
  713.     fseek(fp, dir_ptr, SEEK_SET);
  714.  
  715.     sw_doom = 0;
  716.     for (i=1; i<4; i++) /* to be totally sure, why not check them all? */
  717.         for (j=1; j<10; j++) /* note we assume all headers are in order */
  718.         {
  719.             sprintf(header, "E%dM%d", i, j);
  720.             if (wad_seek(header))
  721.                 sw_doom = 1;
  722.         }
  723.     fclose(fp);
  724.     return;
  725. }
  726.  
  727. int far_read(char huge *farptr, long len) /* read to a far location */
  728. {
  729.     char buffer[4096];
  730.     int i;
  731.  
  732.     if (!len) return 0;
  733.     while (len > 4096)
  734.     {
  735.         if (fread(buffer, 1, 4096, fp) != 4096)
  736.             return -1;
  737.         for (i=0; i<4096; i++, farptr++)
  738.             *farptr = buffer[i];
  739.         len -= 4096;
  740.     }
  741.  
  742.     if (fread(buffer, 1, len, fp) != len)
  743.         return -1;
  744.     for (i=0; i<len; i++, farptr++)
  745.         *farptr = buffer[i];
  746.     return 0;
  747. }
  748.  
  749. long fread_long(void)
  750. {
  751.     long integer;
  752.  
  753.     if (!fread(&integer, sizeof(integer), 1, fp))
  754.         return -1;
  755.     return integer;
  756. }
  757.  
  758. int fwrite_long(long integer)
  759. {
  760.     if (!fwrite(&integer, 4, 1, fp))
  761.         return -1;
  762.     return 0;
  763. }
  764.  
  765. int cmp_entry(char *look_for, char far *entry) /* compare wad entry name */
  766. { /* strcpy won't work, because if entry is 8 chars long, it won't end */
  767.     int i; /* with a zero */
  768.  
  769.     for (i=0; i<8; i++)
  770.     {
  771.         if (!*look_for) return 0;
  772.         if (*look_for >= 'a' && *look_for <= 'z')
  773.             *look_for -= 32;
  774.         if (*entry >= 'a' && *entry <= 'z')
  775.             *entry -= 32;
  776.  
  777.         if (*look_for++ != *entry++) return 1;
  778.     }
  779.     return 0;
  780. }
  781.  
  782. int verify_wad(void) /* make sure this is a wad file */
  783. {
  784.     char str[4];
  785.  
  786.     fread(&str, 1, 4, fp);
  787.     if (str[0] != 'I' && str[0] != 'P' && str[0] != 'T') return 1;
  788.     if (str[1] != 'W') return 2;
  789.     if (str[2] != 'A') return 3;
  790.     if (str[3] != 'D') return 4;
  791.     return 0;
  792. }
  793.