home *** CD-ROM | disk | FTP | other *** search
/ The Complete Doom Accessory Pack 2 / TheCompleteDoomAccessoryPackVolumeII.iso / editors / bspwin / bsp.c next >
C/C++ Source or Header  |  1994-05-25  |  23KB  |  864 lines

  1. /*- BSP.C -------------------------------------------------------------------*
  2.  
  3.  Node builder for DOOM levels, still only version 0.9, so not totally finished
  4.  but, seems to be doing pretty well, for about a weeks work!
  5.  Credit to Raphael Quinet (Some of the code has been modified from DEU).
  6.  Also, the original idea for some of the techniques where also taken from the
  7.  comment at the bottom of OBJECTS.C in DEU, and the doc by Matt Fell about
  8.  the nodes.
  9.  
  10.  Also to Dylan Cuthbert, cos I am really shit at C, and maths.
  11.  And Giles Goddard for helping with the which side checker.
  12.  
  13.  Any inquiries to Colin Reed via DYL@CIX.COMPULINK.CO.UK
  14.  
  15.  Use this code for your own editors, but please credit me.
  16.  
  17.  (Windows code by Alex Korobka)
  18. *---------------------------------------------------------------------------*/
  19.  
  20. #include "bsp.h"
  21. #include "structs.h"
  22. #include "prottype.h"
  23.  
  24. #if defined (_Windows)
  25.  #include <windows.h>
  26.  #include <commdlg.h>
  27. #endif
  28.  
  29. /*- Global Vars ------------------------------------------------------------*/
  30.  
  31. FILE *infile,*outfile;
  32. char *testwad;
  33. char *outwad;
  34.  
  35. struct wad_header *wad = NULL;
  36. struct directory *direc = NULL;
  37. char rname[]="\0\0\0\0\0\0\0\0";
  38.  
  39. struct Thing *things;
  40. long num_things = 0;
  41. long things_start = 0;
  42.  
  43. struct Vertex *vertices;
  44. long num_verts = 0;
  45. long vertices_start = 0;
  46.  
  47. struct LineDef *linedefs;
  48. long num_lines = 0;
  49. long linedefs_start = 0;
  50.  
  51. struct SideDef *sidedefs;
  52. long num_sides = 0;
  53. long sidedefs_start = 0;
  54.  
  55. struct Sector *sectors;
  56. long num_sects = 0;
  57. long sectors_start = 0;
  58.  
  59. struct SSector *ssectors;
  60. long num_ssectors = 0;
  61. long ssectors_start = 0;
  62.  
  63. struct Pseg *psegs = NULL;
  64. long num_psegs = 0;
  65. long segs_start = 0;
  66.  
  67. struct Pnode *pnodes = NULL;
  68. long num_pnodes = 0;
  69. long pnode_indx = 0;
  70. long pnodes_start = 0;
  71.  
  72. struct Seg *tsegs = NULL;
  73. long num_tsegs = 0;
  74.  
  75. struct Node *nodelist = NULL;
  76. long num_nodes = 0;
  77.  
  78. long reject_start;
  79. long reject_size;
  80.  
  81. struct Block blockhead;
  82. short int *blockptrs;
  83. short int *blocklists=NULL;
  84. long blockptrs_size;
  85. long blockmap_size;
  86. long blockmap_start;
  87.  
  88. struct splitter sp;
  89.  
  90. short node_x;
  91. short node_y;
  92. short node_dx;
  93. short node_dy;
  94.  
  95. short lminx;
  96. short lmaxx;
  97. short lminy;
  98. short lmaxy;
  99.  
  100. short mapminx;
  101. short mapmaxx;
  102. short mapminy;
  103. short mapmaxy;
  104.  
  105. long psx,psy,pex,pey,pdx,pdy;
  106. long lsx,lsy,lex,ley;
  107.  
  108. unsigned char pcnt;
  109.  
  110. long fagcount = 0;
  111.  
  112. /*--------------------------------------------------------------------------*/
  113.  
  114. #include "makenode.c"
  115. #include "picknode.c"
  116. #include "funcs.c"
  117.  
  118. char      io1Buffer[256];
  119. char      io2Buffer[256];
  120.  
  121. #if defined (_Windows)    /* Windows specific variables */
  122.  
  123.  #define       WM_BSP      WM_USER+0x10
  124.  HCURSOR       hCursor;
  125.  HICON         hIcon;
  126.  HWND          hWnd;
  127.  MSG           wMsg;
  128.  char*         szFilter = "Patch WAD file(*.WAD)|*.WAD|All files(*.*)|*.*|";
  129. #endif
  130.  
  131.  
  132. /*- Main Program -----------------------------------------------------------*/
  133.  
  134.  
  135.  
  136.  
  137. int cdecl main()
  138. {
  139.     long dir_start = 12;                          /* Skip Pwad header*/
  140.     long dir_entries = 0;
  141.  
  142.     int n;
  143.     unsigned char *data;
  144.  
  145.     getcwd(io1Buffer,256);
  146.  
  147.     /* Following is required to force EasyWin to create window before we call Windows functions */
  148.     printf("DOOM node builder v1.1. Basic concept & code by Colin Reed\nPortions by Alex Korobka\n\n");
  149.  
  150.     #if defined (_Windows) /* Some dirty trick to get our window handle*/
  151.      PostMessage(HWND_BROADCAST,WM_BSP,0,0L);
  152.      WaitMessage();
  153.      PeekMessage(&wMsg,NULL,WM_BSP,WM_BSP,PM_NOREMOVE);
  154.      hWnd  = wMsg.hwnd;
  155.                    /* Customize standard EasyWin window */
  156.      SetWindowText(hWnd,(LPCSTR)"BSP 1.1 for Windows");
  157.      hIcon = LoadIcon(GetWindowWord(hWnd,GWW_HINSTANCE),"BspIcon");
  158.      SetClassWord(hWnd,GCW_HICON,(WORD)hIcon);
  159.     #endif
  160.  
  161.      printf("This Node builder was created from the basic theory stated in DEU5 (OBJECTS.C)\n\n\
  162. \Credits should go to :-\n\
  163. \Matt Fell      (matt.burnett@acebbs.com) for the Doom Specs.\n\
  164. \Raphael Quinet (quinet@montefiore.ulg.ac.be) for DEU and the original idea.\n\
  165. \Dylan Cuthbert (dyl@cix.compulink.co.uk) for allowing the public to get hold\n\
  166. \               of this program.\n\n");
  167.  
  168.      printf("Current directory\t\t%s\n",io1Buffer);
  169.  
  170.      #if defined (_Windows)
  171.       printf("Total memory available\t\t%lu\n",GetFreeSpace(NULL));
  172.       printf("Largest memory block\t\t%lu\n",GlobalCompact(NULL));
  173.  
  174.      for (n = 0; szFilter[n] != '\0'; n++) /* Set up filter string */
  175.       if (szFilter[n] == '|')  szFilter[n] = '\0';
  176.  
  177.      EnableMenuItem(GetSystemMenu(hWnd,FALSE),6,MF_BYPOSITION | MF_GRAYED);
  178.      #else
  179.       printf("Total memory available\t\t%lu\n",coreleft());
  180.      #endif
  181.  
  182.     if(!RetriveOpenFileName(io1Buffer))
  183.       ExitProgram(0);
  184.     testwad = io1Buffer;
  185.  
  186.     #if defined(_Windows)
  187.         hCursor = SetCursor(LoadCursor(NULL,IDC_WAIT));
  188.     #endif
  189.  
  190.     OpenWadFile(testwad);
  191.     GetThings();
  192.     GetLinedefs();
  193.     GetVertexes();
  194.     GetSidedefs();
  195.     GetSectors();
  196.  
  197.     #if defined(_Windows)
  198.         SetCursor(hCursor);
  199.     #endif
  200.  
  201.     num_tsegs = 0;
  202.     tsegs = CreateSegs();                                  /* Initially create segs*/
  203.  
  204.     FindLimits(tsegs);                                    /* Find limits of vertices*/
  205.     
  206.     mapminx = lminx;                                        /* store as map limits*/
  207.     mapmaxx = lmaxx;
  208.     mapminy = lminy;
  209.     mapmaxy = lmaxy;
  210.  
  211.     printf("\nMap goes from X (%d,%d) Y (%d,%d)\n",lminx,lmaxx,lminy,lmaxy);
  212.     
  213.     num_nodes = 0;
  214.     nodelist = CreateNode(tsegs);                        /* recursively create nodes*/
  215.     printf("\n%lu NODES created, with %lu SSECTORS.",num_nodes,num_ssectors);
  216.  
  217.     pnodes = GetMemory(sizeof(struct Pnode)*num_nodes);
  218.     num_pnodes = 0;
  219.     pnode_indx = 0;
  220.     ReverseNodes(nodelist);
  221.  
  222.     dir_entries++;                                            /* Skip level number*/
  223.  
  224.     things_start = dir_start;
  225.     dir_start = dir_start + (sizeof(struct Thing)*num_things);
  226.     direc[dir_entries].start = things_start;
  227.     direc[dir_entries].length = (sizeof(struct Thing)*num_things);
  228.     dir_entries++;
  229.     
  230.     linedefs_start = dir_start;
  231.     dir_start = dir_start + (sizeof(struct LineDef)*num_lines);
  232.     direc[dir_entries].start = linedefs_start;
  233.     direc[dir_entries].length = (sizeof(struct LineDef)*num_lines);
  234.     dir_entries++;
  235.     
  236.     sidedefs_start = dir_start;
  237.     dir_start = dir_start + (sizeof(struct SideDef)*num_sides);
  238.     direc[dir_entries].start = sidedefs_start;
  239.     direc[dir_entries].length = (sizeof(struct SideDef)*num_sides);
  240.     dir_entries++;
  241.     
  242.     printf("\nFound %lu used vertices\n",num_verts);
  243.     
  244.     vertices_start = dir_start;
  245.     dir_start = dir_start + (sizeof(struct Vertex)*num_verts);
  246.     direc[dir_entries].start = vertices_start;
  247.     direc[dir_entries].length = (sizeof(struct Vertex)*num_verts);
  248.     dir_entries++;
  249.     
  250.     segs_start = dir_start;
  251.     dir_start = dir_start + (sizeof(struct Pseg)*num_psegs);
  252.     direc[dir_entries].start = segs_start;
  253.     direc[dir_entries].length = (sizeof(struct Pseg)*num_psegs);
  254.     dir_entries++;
  255.     
  256.     ssectors_start = dir_start;
  257.     dir_start = dir_start + (sizeof(struct SSector)*num_ssectors);
  258.     direc[dir_entries].start = ssectors_start;
  259.     direc[dir_entries].length = (sizeof(struct SSector)*num_ssectors);
  260.     dir_entries++;
  261.     
  262.     pnodes_start = dir_start;
  263.     dir_start = dir_start + (sizeof(struct Pnode)*num_pnodes);
  264.     direc[dir_entries].start = pnodes_start;
  265.     direc[dir_entries].length = (sizeof(struct Pnode)*num_pnodes);
  266.     dir_entries++;
  267.     
  268.     sectors_start = dir_start;
  269.     dir_start = dir_start + (sizeof(struct Sector)*num_sects);
  270.     direc[dir_entries].start = sectors_start;
  271.     direc[dir_entries].length = (sizeof(struct Sector)*num_sects);
  272.     dir_entries++;
  273.  
  274.     reject_size = (num_sects*num_sects+7)/8;
  275.     data = calloc(reject_size,1);
  276.     reject_start = dir_start;
  277.     dir_start+=reject_size;
  278.     direc[dir_entries].start = reject_start;            /* Skip reject map*/
  279.     direc[dir_entries].length = reject_size;
  280.     dir_entries++;
  281.  
  282.     blockmap_size = CreateBlockmap();
  283.  
  284.     blockmap_start = dir_start;
  285.     dir_start = dir_start + (blockmap_size+blockptrs_size+8);
  286.     direc[dir_entries].start = blockmap_start;
  287.     direc[dir_entries].length = (blockmap_size+blockptrs_size+8);
  288.     dir_entries++;
  289.  
  290.     #if defined (_Windows)
  291.         MessageBeep(MB_ICONEXCLAMATION);
  292.     #else
  293.         sound(200);
  294.         delay(50);
  295.         nosound();
  296.     #endif
  297.  
  298.     if(!RetriveSaveFileName(io2Buffer))
  299.      outwad = "tmp.wad";
  300.     else
  301.      outwad = io2Buffer;
  302.  
  303.     if((outfile = fopen(outwad,"wb")) == NULL)
  304.         {
  305.          printf("\nError: Could not open output PWAD file %s", outwad);
  306.          ExitProgram(0);
  307.         }
  308.     #if defined(_Windows)
  309.             hCursor = SetCursor(LoadCursor(NULL,IDC_WAIT));
  310.         #endif
  311.     fwrite(wad,4,1,outfile);
  312.     fwrite(&dir_entries,sizeof(long),1,outfile);
  313.     fwrite(&dir_start,sizeof(long),1,outfile);
  314.     fwrite(things,(sizeof(struct Thing)*num_things),1,outfile);
  315.     fwrite(linedefs,(sizeof(struct LineDef)*num_lines),1,outfile);
  316.     fwrite(sidedefs,(sizeof(struct SideDef)*num_sides),1,outfile);
  317.     fwrite(vertices,(sizeof(struct Vertex)*num_verts),1,outfile);
  318.     fwrite(psegs,(sizeof(struct Pseg)*num_psegs),1,outfile);
  319.     fwrite(ssectors,(sizeof(struct SSector)*num_ssectors),1,outfile);
  320.     fwrite(pnodes,(sizeof(struct Pnode)*num_pnodes),1,outfile);
  321.     fwrite(sectors,(sizeof(struct Sector)*num_sects),1,outfile);
  322.     fwrite(data,reject_size,1,outfile);
  323.     fwrite(&blockhead,(sizeof(struct Block)),1,outfile);
  324.     fwrite(blockptrs,blockptrs_size,1,outfile);
  325.     fwrite(blocklists,blockmap_size,1,outfile);
  326.     fwrite(direc,(sizeof(struct directory)*wad->num_entries),1,outfile);
  327.     fclose(outfile);
  328.     #if defined(_Windows)
  329.         SetCursor(hCursor);
  330.         #endif
  331.     printf("\bCompleted blockmap building and saved PWAD as %s\n",outwad);
  332.     ExitProgram(0);
  333.         return 0;
  334. }
  335.  
  336. /*- initially creates all segs, one for each line def ----------------------*/
  337.  
  338. struct Seg *CreateSegs()
  339. {
  340.     struct Seg *cs = NULL;                    /* current and temporary Segs*/
  341.     struct Seg *ts = NULL;
  342.     struct Seg *fs = NULL;                    /* first Seg in list*/
  343.     
  344.     short    n,fv,tv;
  345.     int    dx,dy;
  346.  
  347.     printf("Creating Segs ..........\n");
  348.  
  349.     for(n=0; n < num_lines; n++)            /* step through linedefs and get side*/
  350.         {                                            /* numbers*/
  351.         fv = linedefs[n].start;
  352.         tv = linedefs[n].end;
  353.  
  354.         if(linedefs[n].sidedef1 != -1)
  355.             {                                                        /* create normal seg*/
  356.             ts = GetMemory( sizeof( struct Seg));        /* get mem for Seg*/
  357.             if(cs)
  358.                 {
  359.                 cs->next = ts;
  360.                 cs = ts;
  361.                 cs->next = NULL;
  362.                 }
  363.             else
  364.                 {
  365.                 fs = cs = ts;
  366.                 cs->next = NULL;
  367.                 }
  368.             cs->start = fv;
  369.             cs->end = tv;
  370. /*            printf("%d,%d\n",fv,tv);*/
  371.             dx = (vertices[tv].x-vertices[fv].x);
  372.             dy = (vertices[tv].y-vertices[fv].y);
  373.             cs->angle = ComputeAngle(dx,dy);
  374.             cs->linedef = n;
  375.             cs->dist = 0;
  376.             cs->flip = 0;
  377.             num_tsegs++;
  378.             }
  379.         if(linedefs[n].sidedef2 != -1)
  380.             {                                                        /* create flipped seg*/
  381.             ts = GetMemory( sizeof( struct Seg));        /* get mem for Seg*/
  382.             if(cs)
  383.                 {
  384.                 cs->next = ts;
  385.                 cs = ts;
  386.                 cs->next = NULL;
  387.                 }
  388.             else
  389.                 {
  390.                 fs = cs = ts;
  391.                 cs->next = NULL;
  392.                 }
  393.             cs->start = tv;
  394.             cs->end = fv;
  395.             dx = (vertices[fv].x-vertices[tv].x);
  396.             dy = (vertices[fv].y-vertices[tv].y);
  397.             cs->angle = ComputeAngle(dx,dy);
  398.             cs->linedef = n;
  399.             cs->dist = 0;
  400.             cs->flip = 1;
  401.             num_tsegs++;
  402.             }
  403.         }
  404.  
  405.     return fs;
  406. }
  407.  
  408. /*--------------------------------------------------------------------------*/
  409. /* Find limits from a list of segs, does this by stepping through the segs*/
  410. /* and comparing the vertices at both ends.*/
  411. /*--------------------------------------------------------------------------*/
  412.  
  413. void _fastcall FindLimits(struct Seg *ts)
  414. {
  415.     int n,minx,miny,maxx,maxy;
  416.     int fv,tv;
  417.  
  418.     minx = 32767;
  419.     maxx = -32767;
  420.     miny = 32767;
  421.     maxy = -32767;
  422.  
  423.     while(1)
  424.         {
  425.         fv = ts->start;
  426.         tv = ts->end;
  427. /*        printf("%d : %d,%d\n",n,vertices[n].x,vertices[n].y);*/
  428.         if(vertices[fv].x < minx) minx = vertices[fv].x;
  429.         if(vertices[fv].x > maxx) maxx = vertices[fv].x;
  430.         if(vertices[fv].y < miny) miny = vertices[fv].y;
  431.         if(vertices[fv].y > maxy) maxy = vertices[fv].y;
  432.         if(vertices[tv].x < minx) minx = vertices[tv].x;
  433.         if(vertices[tv].x > maxx) maxx = vertices[tv].x;
  434.         if(vertices[tv].y < miny) miny = vertices[tv].y;
  435.         if(vertices[tv].y > maxy) maxy = vertices[tv].y;
  436.         if(ts->next == NULL) break;
  437.         ts = ts->next;
  438.         }
  439.     lminx = minx;
  440.     lmaxx = maxx;
  441.     lminy = miny;
  442.     lmaxy = maxy;
  443. }
  444.  
  445. /*--------------------------------------------------------------------------*/
  446.  
  447. int SplitDist(struct Seg *ts)
  448. {
  449.     double t,dx,dy;
  450.     
  451.     dx = (double)(vertices[linedefs[ts->linedef].start].x)-(vertices[ts->start].x);
  452.     dy = (double)(vertices[linedefs[ts->linedef].start].y)-(vertices[ts->start].y);
  453.  
  454.     if(dx == 0 && dy == 0) printf("Trouble in SplitDist %f,%f\n",dx,dy);
  455.     t = sqrt((dx*dx) + (dy*dy));
  456.     return (int)t;
  457. }
  458.  
  459. /*- get the directory from a wad file --------------------------------------*/
  460.  
  461. void OpenWadFile(char *filename)
  462. {
  463.     struct directory *dir;
  464.  
  465.     long n;
  466.  
  467.     if((infile = fopen(filename,"rb")) == NULL)
  468.         {
  469.                  printf("\nError: Cannot find WAD file %s", filename);
  470.          ExitProgram(0);
  471.         }
  472.  
  473.     wad = GetMemory( sizeof( struct wad_header));
  474.     
  475.     fread(wad,sizeof( struct wad_header),1,infile);
  476.  
  477.     printf("%c%c%c%c input file\t\t\t%s. %lu dir entries at %lu.\n",
  478.         wad->type[0],wad->type[1],wad->type[2],wad->type[3],filename,
  479.         wad->num_entries,wad->dir_start);
  480.  
  481.     direc = dir = GetMemory( sizeof( struct directory) * wad->num_entries);
  482.     
  483.     fseek(infile,wad->dir_start,0);
  484.  
  485.     for(n = 0; n < wad->num_entries; n++)
  486.         {
  487.         fread(dir,sizeof( struct directory),1,infile);
  488. /*        Printname(dir);*/
  489. /*        printf(" of size %lu at %lu.\n",dir->length,dir->start);*/
  490.         dir++;
  491.         }
  492. }
  493.  
  494. /*- read the things from the wad file and place in 'things' ----------------*/
  495.  
  496. void GetThings(void)
  497. {
  498.     int n;
  499.  
  500.     n = FindDir("THINGS");
  501.     if(direc[n].length == 0) ProgError("Must have at least 1 thing");
  502.     num_things = (direc[n].length) / (sizeof( struct Thing));
  503. /*    printf("Allocating %lu bytes for %d things\n",direc[n].length,num_things);*/
  504.     things = GetMemory( direc[n].length);
  505.     fseek(infile,direc[n].start,0);
  506.     fread(things,direc[n].length,1,infile);
  507. }
  508.  
  509. /*- read the vertices from the wad file and place in 'vertices' ------------*/
  510.  
  511. void GetVertexes(void)
  512. {
  513.     struct Vertex *tmpv;
  514.     int n,i,t;
  515.     long used_verts;
  516.  
  517.     n = FindDir("VERTEXES");
  518.     if(direc[n].length == 0) ProgError("Couldn't find any Vertices");
  519.     fseek(infile,direc[n].start,0);
  520.     num_verts = (direc[n].length) / (sizeof( struct Vertex));
  521.     tmpv = GetMemory(sizeof(struct Vertex)*num_verts);
  522.     vertices = GetMemory(sizeof(struct Vertex)*num_verts);
  523.     fread(tmpv,direc[n].length,1,infile);
  524.  
  525.     used_verts = 0;
  526.     for(i=0;i<num_verts;i++)
  527.         {
  528.         if(Reference(i))
  529.             {
  530.             vertices[used_verts].x = tmpv[i].x;
  531.             vertices[used_verts].y = tmpv[i].y;
  532.             
  533.             for(t=0; t<num_lines; t++)
  534.                 {
  535.                 if(linedefs[t].start == i) linedefs[t].start = used_verts;
  536.                 if(linedefs[t].end == i) linedefs[t].end = used_verts;
  537.                 }
  538.             
  539.             used_verts++;
  540.             }
  541.         else
  542.             {
  543. /*            printf("Vertex [%d] not used.\n",i);*/
  544.             }
  545.         }
  546.     printf("Loaded %lu vertices, but %lu were unused.\n",num_verts,num_verts-used_verts);
  547.     num_verts = used_verts;
  548.     farfree(tmpv);
  549. }
  550.  
  551. /*--------------------------------------------------------------------------*/
  552.  
  553. int Reference(int vert_num)
  554. {
  555.     int n;
  556.  
  557.     for(n=0; n<num_lines; n++)
  558.         {
  559.         if(linedefs[n].start == vert_num || linedefs[n].end == vert_num) return 1;
  560.         }
  561.     return 0;
  562. }
  563.  
  564. /*- read the linedefs from the wad file and place in 'linedefs' ------------*/
  565.  
  566. void GetLinedefs(void)
  567. {
  568.     int n;
  569.  
  570.     n = FindDir("LINEDEFS");
  571.     if(direc[n].length == 0) ProgError("Couldn't find any Linedefs");
  572.     num_lines = (direc[n].length) / (sizeof( struct LineDef));
  573. /*    printf("Allocating %lu bytes for %d Linedefs\n",direc[n].length,num_lines);*/
  574.     linedefs = GetMemory( direc[n].length);
  575.     fseek(infile,direc[n].start,0);
  576.     fread(linedefs,direc[n].length,1,infile);
  577. }
  578.  
  579. /*- read the sidedefs from the wad file and place in 'sidedefs' ------------*/
  580.  
  581. void GetSidedefs(void)
  582. {
  583.     int n;
  584.  
  585.     n = FindDir("SIDEDEFS");
  586.     if(direc[n].length == 0) ProgError("Couldn't find any Sidedefs");
  587.     num_sides = (direc[n].length) / (sizeof( struct SideDef));
  588. /*    printf("Allocating %lu bytes for %d Sidedefs\n",direc[n].length,num_sides);*/
  589.     sidedefs = GetMemory( direc[n].length);
  590.     fseek(infile,direc[n].start,0);
  591.     fread(sidedefs,direc[n].length,1,infile);
  592. }
  593.  
  594. /*- read the sectors from the wad file and place in 'sectors' ------------*/
  595.  
  596. void GetSectors(void)
  597. {
  598.     int n;
  599.  
  600.     n = FindDir("SECTORS");
  601.     num_sects = (direc[n].length) / (sizeof( struct Sector));
  602. /*    printf("Allocating %lu bytes for %d Sectors\n",direc[n].length,num_sects);*/
  603.     sectors = GetMemory( direc[n].length);
  604.     fseek(infile,direc[n].start,0);
  605.     fread(sectors,direc[n].length,1,infile);
  606. }
  607.  
  608. /*- find the offset into the directory of a resource -----------------------*/
  609.  
  610. int FindDir(char *name)
  611. {
  612.     struct directory *dir;
  613.     int n;
  614.  
  615.     dir = direc;
  616.  
  617.     for(n=0; n< wad->num_entries; n++)
  618.         {
  619.         strncpy(rname,dir->name,8);
  620.         if(strcmp(rname,name) == 0) return n;
  621.         dir++;
  622.         }
  623.     ProgError( "Cannot find %s", name);
  624.     return 0;
  625. }
  626.  
  627. /*- print a resource name by copying 8 chars into rname and printing this --*/
  628.  
  629. void Printname(struct directory *dir)
  630. {
  631.     strncpy(rname,dir->name,8);
  632.     printf("%-8s",rname);
  633. }
  634.  
  635. /*- Create blockmap --------------------------------------------------------*/
  636.  
  637. long CreateBlockmap()
  638. {
  639.     long blockoffs = 0;
  640.     int x,y,n;
  641.     int blocknum = 0;
  642.  
  643.     blockhead.minx = mapminx&-8;
  644.     blockhead.miny = mapminy&-8;
  645.     blockhead.xblocks = ((mapmaxx - (mapminx&-8)) / 128) + 1;
  646.     blockhead.yblocks = ((mapmaxy - (mapminy&-8)) / 128) + 1; 
  647.     
  648.     blockptrs_size = (blockhead.xblocks*blockhead.yblocks)*2;
  649.     blockptrs = GetMemory(blockptrs_size);
  650.  
  651.     for(y=0;y<blockhead.yblocks;y++)
  652.         {
  653.         for(x=0;x<blockhead.xblocks;x++)
  654.             {
  655.             progress();
  656.  
  657.             blockptrs[blocknum]=(blockoffs+4+(blockptrs_size/2));
  658.             
  659.             blocklists = ResizeMemory(blocklists,((blockoffs+1)*2));
  660.             blocklists[blockoffs++]=0;
  661.             for(n=0;n<num_lines;n++)
  662.                 {
  663.                 if(IsLineDefInside(n,(blockhead.minx+(x*128)),(blockhead.miny+(y*128)),(blockhead.minx+(x*128))+127,(blockhead.miny+(y*128))+127))
  664.                     {
  665. /*                    printf("found line %d in block %d\n",n,blocknum);*/
  666.                     blocklists = ResizeMemory(blocklists,((blockoffs+1)*2));
  667.                     blocklists[blockoffs++]=n;
  668.                     }
  669.                 }
  670.             blocklists = ResizeMemory(blocklists,((blockoffs+1)*2));
  671.             blocklists[blockoffs++]=-1;
  672.             
  673.             blocknum++;
  674.             }
  675.         }
  676.     return blockoffs*2;
  677. }
  678.  
  679. /*--------------------------------------------------------------------------*/
  680.  
  681. int IsLineDefInside(int ldnum, int xmin, int ymin, int xmax, int ymax )
  682. {
  683.    int x1 = vertices[ linedefs[ ldnum].start].x;
  684.    int y1 = vertices[ linedefs[ ldnum].start].y;
  685.    int x2 = vertices[ linedefs[ ldnum].end].x;
  686.    int y2 = vertices[ linedefs[ ldnum].end].y;
  687.     
  688.     int outcode1,outcode2,t;
  689.  
  690.     while(1)
  691.         {
  692.         outcode1=0;
  693.         if(y1>ymax) outcode1|=1;
  694.         if(y1<ymin) outcode1|=2;
  695.         if(x1>xmax) outcode1|=4;
  696.         if(x1<xmin) outcode1|=8;
  697.         outcode2=0;
  698.         if(y2>ymax) outcode2|=1;
  699.         if(y2<ymin) outcode2|=2;
  700.         if(x2>xmax) outcode2|=4;
  701.         if(x2<xmin) outcode2|=8;
  702.         if( outcode1&outcode2 ) return FALSE;
  703.         if(((outcode1==0)&&(outcode2==0))) return TRUE;
  704.  
  705.         if(!(outcode1&15))
  706.             {
  707.             t=outcode1; 
  708.             outcode1=outcode2;
  709.             outcode2=t;
  710.             t=x1;x1=x2;x2=t;
  711.             t=y1;y1=y2;y2=t;
  712.             }
  713.         if(outcode1&1)
  714.             {
  715.             x1=x1+(x2-x1)*(ymax-y1)/(y2-y1);
  716.             y1=ymax;
  717.             }
  718.         else
  719.             {
  720.             if(outcode1&2)
  721.                 {
  722.                 x1=x1+(x2-x1)*(ymin-y1)/(y2-y1);
  723.                 y1=ymin;
  724.                 }
  725.             else
  726.                 {
  727.                 if(outcode1&4)
  728.                     {
  729.                     y1=y1+(y2-y1)*(xmax-x1)/(x2-x1);
  730.                     x1=xmax;
  731.                     }
  732.                 else
  733.                     {
  734.                     if(outcode1&8)
  735.                         {
  736.                         y1=y1+(y2-y1)*(xmin-x1)/(x2-x1);
  737.                         x1=xmin;
  738.                         }
  739.                     }
  740.                 }
  741.             }
  742.         }
  743. }
  744.  
  745. /*--------------------------------------------------------------------------*/
  746.  
  747. void ReverseNodes(struct Node *tn)
  748. {
  749.     if((tn->chright & 0x8000) == 0)
  750.         {
  751.         ReverseNodes(tn->nextr);
  752.         tn->chright = tn->nextr->node_num;
  753.         }
  754.     if((tn->chleft & 0x8000) == 0)
  755.         {
  756.         ReverseNodes(tn->nextl);
  757.         tn->chleft = tn->nextl->node_num;
  758.         }
  759.     pnodes[pnode_indx].x = tn->x;
  760.     pnodes[pnode_indx].y = tn->y;
  761.     pnodes[pnode_indx].dx = tn->dx;
  762.     pnodes[pnode_indx].dy = tn->dy;
  763.     pnodes[pnode_indx].maxy1 = tn->maxy1;
  764.     pnodes[pnode_indx].miny1 = tn->miny1;
  765.     pnodes[pnode_indx].minx1 = tn->minx1;
  766.     pnodes[pnode_indx].maxx1 = tn->maxx1;
  767.     pnodes[pnode_indx].maxy2 = tn->maxy2;
  768.     pnodes[pnode_indx].miny2 = tn->miny2;
  769.     pnodes[pnode_indx].minx2 = tn->minx2;
  770.     pnodes[pnode_indx].maxx2 = tn->maxx2;
  771.     pnodes[pnode_indx].chright = tn->chright;
  772.     pnodes[pnode_indx].chleft = tn->chleft;
  773.     pnode_indx++;
  774.     tn->node_num = num_pnodes++;
  775. }
  776.  
  777. /*--------------------------------------------------------------------------*/
  778.  
  779. void progress()
  780. {
  781.     char *s="/-\\|/-\\|";
  782.  
  783.     if((pcnt&15) == 0)
  784.         {
  785.         printf("\b%c",s[((pcnt)/16)&7]);
  786.         fflush(stdout);
  787.         }
  788.     pcnt++;
  789.  #if defined( _Windows )                 /* Check for pending messages */
  790.     while(TRUE)
  791.          {
  792.       if(PeekMessage( &wMsg,NULL,0,0,PM_REMOVE))
  793.        {
  794.          if(wMsg.message == WM_SYSCOMMAND && wMsg.wParam == SC_CLOSE)
  795.            continue;   /* prevent from closing while building WAD */
  796.          TranslateMessage(&wMsg);
  797.          DispatchMessage(&wMsg);
  798.        }
  799.       else
  800.            return;         /* continue processing        */
  801.          }
  802.  #endif
  803. }
  804.  
  805. int RetriveOpenFileName(char* buffer)
  806. {
  807. #if defined ( _Windows)
  808.  OPENFILENAME  ofn;
  809.  /* Set all structure members to zero. */
  810.  memset(&ofn, 0, sizeof(OPENFILENAME));
  811.  
  812.  buffer[0]='\0';
  813.  ofn.lStructSize = sizeof(OPENFILENAME);
  814.  ofn.hwndOwner = NULL;
  815.  ofn.lpstrFilter = szFilter;
  816.  ofn.nFilterIndex = 1;
  817.  ofn.lpstrFile= (LPSTR)buffer;
  818.  ofn.nMaxFile = 255;
  819.  ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
  820.  return GetOpenFileName(&ofn);
  821. #else
  822.  printf("Input WAD file\t\t\t");
  823.  gets(buffer);
  824.  if(buffer[0] == '\0') return 0;
  825.  return 1;
  826. #endif
  827. }
  828.  
  829. int RetriveSaveFileName(char* buffer)
  830. {
  831. #if defined (_Windows)
  832.  OPENFILENAME ofn;
  833.  
  834.  memset(&ofn, 0, sizeof(OPENFILENAME));
  835.  /* Initialize the OPENFILENAME members. */
  836.  
  837.  buffer[0] = '\0';
  838.  ofn.lStructSize = sizeof(OPENFILENAME);
  839.  ofn.lpstrFilter = szFilter;
  840.  ofn.lpstrFile= (LPSTR)buffer;
  841.  ofn.nMaxFile = 255;
  842.  ofn.Flags = OFN_OVERWRITEPROMPT;
  843.  return GetSaveFileName(&ofn);
  844. #else
  845.  printf("\bOutput WAD file\t\t\t");
  846.  gets(buffer);
  847.  if(buffer[0] == '\0') return 0;
  848.  return 1;
  849. #endif
  850. }
  851.  
  852. void ExitProgram(int eCode)
  853. {
  854.  #if defined (_Windows)
  855.      EnableMenuItem(GetSystemMenu(hWnd,FALSE),6,MF_BYPOSITION | MF_ENABLED);
  856.      printf("Press any key to quit...");
  857.      while(!kbhit());
  858.      PostMessage(hWnd,WM_CLOSE,0,0L);    /* Shutdown our window*/
  859.  #endif
  860.      exit(eCode);
  861. }
  862.  
  863. /*- end of file ------------------------------------------------------------*/
  864.