home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the DOOM Gurus / TricksOfTheDoomGurus.iso / editors / nodenav / nodenav.cpp < prev    next >
Text File  |  1994-03-26  |  12KB  |  380 lines

  1. //
  2. //      NODE Navigator v0.8
  3. //
  4. //      Source for Watcom C++32 compiler
  5. //
  6. //      Frank Palazzolo
  7. //      palazzol@msen.com
  8. //
  9. //      Comments and enhancements are welcome!!!
  10. //
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <conio.h>
  16. #include <ctype.h>
  17.  
  18. #include <graph.h>
  19.  
  20. #include "nodenav.h"
  21.  
  22. #define min(a,b)  (((a) < (b)) ? (a) : (b))
  23. #define max(a,b)  (((a) > (b)) ? (a) : (b))
  24.  
  25. FILE    *fp;
  26. unsigned long int stack_ptr;
  27.  
  28. enum {BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, WHITE,
  29.         GRAY, LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENTA,
  30.         YELLOW, BRIGHTWHITE};
  31.  
  32. #define LIGHTYELLOW    YELLOW
  33.  
  34. int main(int argc, char *argv[])
  35. {
  36.  
  37.         char filename[80];
  38.         char mission[80];
  39.  
  40.         if (argc < 2) {
  41.            printf("Usage: %s mission \[wadfile\]\n",argv[0]);
  42.            exit(-1);
  43.         } else { if (argc == 2) 
  44.                       strcpy(filename, "DOOM.WAD");
  45.                  else
  46.                       strcpy(filename, strupr(argv[2]));
  47.         }
  48.  
  49.         strcpy(mission, strupr(argv[1]));
  50.  
  51.         DIRENTRYTYPE *seek_entry(DIRENTRYTYPE *,char *);
  52.         int read_linedefs(LINEDEFTYPE *, DIRENTRYTYPE *);
  53.         int read_sidedefs(SIDEDEFTYPE *, DIRENTRYTYPE *);
  54.         int read_vertices(VERTEXTYPE *, DIRENTRYTYPE *);
  55.         int read_segments(SEGMENTTYPE *, DIRENTRYTYPE *);
  56.         int read_ssectors(SSECTORTYPE *, DIRENTRYTYPE *);
  57.         int read_nodes(NODETYPE *, DIRENTRYTYPE *);
  58.         int read_sectors(SECTORTYPE *, DIRENTRYTYPE *);
  59.  
  60.         HEADERTYPE wadheader;
  61.  
  62.         DIRENTRYTYPE direntry;
  63.         LINEDEFTYPE *linedefs;
  64.         SIDEDEFTYPE *sidedefs;
  65.         VERTEXTYPE *vertices;
  66.         SEGMENTTYPE *segments;
  67.         SSECTORTYPE *ssectors;
  68.         NODETYPE *nodes;
  69.         SECTORTYPE *sectors;
  70.  
  71.         int num_linedefs = 0;
  72.         int num_sidedefs = 0;
  73.         int num_vertices = 0;
  74.         int num_segments = 0;
  75.         int num_ssectors = 0;
  76.         int num_nodes = 0;
  77.         int num_sectors = 0;
  78.  
  79.         if ((fp = fopen(filename,"rb")) == NULL) {
  80.                 fprintf(stderr,"No %s file found\n",filename);
  81.                 return(-1);
  82.         }
  83.  
  84.         fread(&wadheader, sizeof(wadheader), 1, fp);
  85.  
  86.         printf("File ID: %c%c%c%c\n",wadheader.type[0],wadheader.type[1],
  87.                 wadheader.type[2],wadheader.type[3]);
  88.         printf("# of Directory entries: %ld\n",wadheader.num_dir_entries);
  89.  
  90.         if (fseek(fp,wadheader.dirpointer,SEEK_SET))
  91.                 fprintf(stderr,"Directory Seek Failed!\n");
  92.  
  93.         if (seek_entry(&direntry,mission) == NULL) {
  94.                 printf("Could not find %s in %s\n",mission,filename);
  95.                 return(-1);
  96.         } else
  97.                 printf("Found %s...\n",mission);
  98.  
  99.         if (seek_entry(&direntry,"LINEDEFS") == NULL) return(-1);
  100.         else
  101.                 linedefs = (LINEDEFTYPE *)malloc(direntry.length);
  102.                 num_linedefs = read_linedefs(linedefs, &direntry);
  103.  
  104.         printf("Read in %d linedefs...\n",num_linedefs);
  105.  
  106.         if (seek_entry(&direntry,"SIDEDEFS") == NULL) return(-1);
  107.         else
  108.                 sidedefs = (SIDEDEFTYPE *)malloc(direntry.length);
  109.                 num_sidedefs = read_sidedefs(sidedefs, &direntry);
  110.  
  111.         printf("Read in %d sidedefs...\n",num_sidedefs);
  112.  
  113.         if (seek_entry(&direntry,"VERTEXES") == NULL) return(-1);
  114.         else
  115.                 vertices = (VERTEXTYPE *)malloc(direntry.length);
  116.                 num_vertices = read_vertices(vertices, &direntry);
  117.  
  118.         printf("Read in %d vertices...\n",num_vertices);
  119.  
  120.         if (seek_entry(&direntry,"SEGS\0\0\0\0") == NULL) return(-1);
  121.         else
  122.                 segments = (SEGMENTTYPE *)malloc(direntry.length);
  123.                 num_segments = read_segments(segments, &direntry);
  124.  
  125.         printf("Read in %d segments...\n",num_segments);        
  126.  
  127.         if (seek_entry(&direntry,"SSECTORS") == NULL) return(-1);
  128.         else
  129.                 ssectors = (SSECTORTYPE *)malloc(direntry.length);
  130.                 num_ssectors = read_ssectors(ssectors, &direntry);
  131.  
  132.         printf("Read in %d ssectors...\n",num_ssectors);
  133.  
  134.         if (seek_entry(&direntry,"NODES\0\0\0") == NULL) return(-1);
  135.         else
  136.                 nodes = (NODETYPE *)malloc(direntry.length);
  137.                 num_nodes = read_nodes(nodes, &direntry);
  138.  
  139.         printf("Read in %d nodes...\n",num_nodes);
  140.  
  141.         if (seek_entry(&direntry,"SECTORS\0") == NULL) return(-1);
  142.         else
  143.                 sectors = (SECTORTYPE *)malloc(direntry.length);
  144.                 num_sectors = read_sectors(sectors, &direntry);
  145.  
  146.         printf("Read in %d sectors...\n",num_sectors);
  147.  
  148.         int i;
  149.         unsigned short int j;
  150.  
  151.         int key = 0;
  152.  
  153.         short int max_x, max_y, min_x, min_y, mid_x, mid_y;
  154.         float scale_x, scale_y, scale;
  155.         char L_type, R_type;
  156.         unsigned short int up_node[600];
  157.  
  158.         up_node[num_nodes-1] = num_nodes-1;
  159.  
  160.         for(i=0;i<num_nodes;i++) {
  161.                 if (!(nodes[i].left_child & 0x8000))
  162.                         up_node[nodes[i].left_child] = i;
  163.                 if (!(nodes[i].right_child & 0x8000))
  164.                         up_node[nodes[i].right_child] = i;
  165.         }
  166.  
  167.         _setvideomode( _VRES16COLOR);
  168.  
  169.         j = num_nodes - 1;
  170.         while (key != 'Q') {
  171.  
  172.            _clearscreen(_GCLEARSCREEN);
  173.  
  174.         min_x = min(min(nodes[j].left_x_upper,nodes[j].left_x_lower),
  175.                       min(nodes[j].right_x_upper,nodes[j].right_x_lower));
  176.  
  177.         min_y = min(min(nodes[j].left_y_upper,nodes[j].left_y_lower),
  178.                       min(nodes[j].right_y_upper,nodes[j].right_y_lower));
  179.  
  180.         max_x = max(max(nodes[j].left_x_upper,nodes[j].left_x_lower),
  181.                       max(nodes[j].right_x_upper,nodes[j].right_x_lower));
  182.  
  183.         max_y = max(max(nodes[j].left_y_upper,nodes[j].left_y_lower),
  184.                       max(nodes[j].right_y_upper,nodes[j].right_y_lower));
  185.  
  186.         mid_x = (min_x + max_x) / 2;
  187.         mid_y = (min_y + max_y) / 2;
  188.  
  189.         scale_x = ((float)320 / (float)(max_x - mid_x)) * (float)0.90;
  190.         scale_y = ((float)240 / (float)(max_y - mid_y)) * (float)0.90;
  191.  
  192.         if (scale_x < scale_y) {
  193.            scale = scale_x;
  194.         } else {
  195.            scale = scale_y;
  196.         } /* endif */
  197.  
  198.              _setcolor(GRAY);
  199.            for (i=0;i<num_linedefs;i++) {
  200.               _moveto((vertices[linedefs[i].from_vertex].x-mid_x)*scale+320,
  201.                         (vertices[linedefs[i].from_vertex].y-mid_y)*(-scale)+240);
  202.               _lineto((vertices[linedefs[i].to_vertex].x-mid_x)*scale+320,
  203.                         (vertices[linedefs[i].to_vertex].y-mid_y)*(-scale)+240);
  204.         } 
  205.  
  206.      _setcolor(RED);
  207.      _rectangle(_GBORDER,(nodes[j].left_x_upper-mid_x)*scale+320,
  208.                         (nodes[j].left_y_upper-mid_y)*(-scale)+240,
  209.                         (nodes[j].left_x_lower-mid_x)*scale+320,
  210.                         (nodes[j].left_y_lower-mid_y)*(-scale)+240);
  211.      _setcolor(BLUE);
  212.      _rectangle(_GBORDER,(nodes[j].right_x_upper-mid_x)*scale+320,
  213.                         (nodes[j].right_y_upper-mid_y)*(-scale)+240,
  214.                         (nodes[j].right_x_lower-mid_x)*scale+320,
  215.                         (nodes[j].right_y_lower-mid_y)*(-scale)+240);
  216.      _setcolor(GREEN);
  217.      _moveto((nodes[j].x-mid_x)*scale+320,
  218.               (nodes[j].y-mid_y)*(-scale)+240);
  219.      _lineto((nodes[j].x+nodes[j].dx-mid_x)*scale+320,
  220.               (nodes[j].y+nodes[j].dy-mid_y)*(-scale)+240);
  221.         
  222.      _settextposition(1,1);
  223.  
  224.         if(nodes[j].left_child & 0x8000)
  225.            L_type = 'S';
  226.         else
  227.            L_type = 'N';
  228.         if(nodes[j].right_child & 0x8000)
  229.            R_type = 'S';
  230.         else
  231.            R_type = 'N';
  232.  
  233.         printf("NodeNav v0.8            N:%#04x     %c:%#04hx   %c:%#04hx",j,
  234.            L_type,nodes[j].left_child & 0x7fff,R_type,nodes[j].right_child & 0x7fff);
  235.         fflush(stdout);
  236.         key = toupper(getch());
  237.         if (key == 'L' && L_type == 'N')
  238.                 j = nodes[j].left_child;
  239.         if (key == 'R' && R_type == 'N')
  240.                 j = nodes[j].right_child;
  241.         if (key == 'U')
  242.                 j = up_node[j];
  243.      }
  244.         _setvideomode( _DEFAULTMODE);
  245.         return(0);
  246. }
  247.  
  248.  
  249. DIRENTRYTYPE *seek_entry(DIRENTRYTYPE *entry, char *name) {
  250.  
  251.         DIRENTRYTYPE *val = NULL;
  252.  
  253.         while(!feof(fp) && (val == NULL)) {
  254.                 fread(entry, sizeof(DIRENTRYTYPE),1,fp);
  255.                 if (!strncmp((char *)entry->name,name,strlen(name)))
  256.                         val = entry;
  257.         }
  258.         return(val);
  259. }
  260.  
  261. int read_linedefs(LINEDEFTYPE *ldarray, DIRENTRYTYPE *entry) {
  262.  
  263.         unsigned long int j;
  264.  
  265.         stack_ptr = ftell(fp);
  266.         fseek(fp,entry->startaddr,SEEK_SET);
  267.  
  268.         for(j=0;j<entry->length/sizeof(LINEDEFTYPE);j++)
  269.         {
  270.                 fread(&ldarray[j],sizeof(LINEDEFTYPE),1,fp);
  271.         }
  272.  
  273.         fseek(fp,stack_ptr,SEEK_SET);
  274.         return (entry->length/sizeof(LINEDEFTYPE));
  275. }
  276.  
  277. int read_sidedefs(SIDEDEFTYPE *sdarray, DIRENTRYTYPE *entry) {
  278.  
  279.         unsigned long int j;
  280.  
  281.         stack_ptr = ftell(fp);
  282.         fseek(fp,entry->startaddr,SEEK_SET);
  283.  
  284.         for(j=0;j<entry->length/sizeof(SIDEDEFTYPE);j++)
  285.         {
  286.                 fread(&sdarray[j],sizeof(SIDEDEFTYPE),1,fp);
  287.         }
  288.  
  289.         fseek(fp,stack_ptr,SEEK_SET);
  290.         return (entry->length/sizeof(SIDEDEFTYPE));
  291.  
  292. }
  293.  
  294. int read_vertices(VERTEXTYPE *vtarray, DIRENTRYTYPE *entry) {
  295.  
  296.         unsigned long int j;
  297.  
  298.         stack_ptr = ftell(fp);
  299.         fseek(fp,entry->startaddr,SEEK_SET);
  300.  
  301.         for(j=0;j<entry->length/sizeof(VERTEXTYPE);j++)
  302.         {
  303.                 fread(&vtarray[j],sizeof(VERTEXTYPE),1,fp);
  304.         }
  305.  
  306.         fseek(fp,stack_ptr,SEEK_SET);
  307.         return (entry->length/sizeof(VERTEXTYPE));
  308.  
  309. }
  310.  
  311. int read_segments(SEGMENTTYPE *smarray, DIRENTRYTYPE *entry) {
  312.  
  313.         unsigned long int j;
  314.  
  315.         stack_ptr = ftell(fp);
  316.         fseek(fp,entry->startaddr,SEEK_SET);
  317.  
  318.         for(j=0;j<entry->length/sizeof(SEGMENTTYPE);j++)
  319.         {
  320.                 fread(&smarray[j],sizeof(SEGMENTTYPE),1,fp);
  321.         }
  322.  
  323.         fseek(fp,stack_ptr,SEEK_SET);
  324.         return (entry->length/sizeof(SEGMENTTYPE));
  325.  
  326. }
  327.  
  328. int read_ssectors(SSECTORTYPE *ssarray, DIRENTRYTYPE *entry) {
  329.  
  330.         unsigned long int j;
  331.  
  332.         stack_ptr = ftell(fp);
  333.         fseek(fp,entry->startaddr,SEEK_SET);
  334.  
  335.         for(j=0;j<entry->length/sizeof(SSECTORTYPE);j++)
  336.         {
  337.                 fread(&ssarray[j],sizeof(SSECTORTYPE),1,fp);
  338.         }
  339.  
  340.         fseek(fp,stack_ptr,SEEK_SET);
  341.         return (entry->length/sizeof(SSECTORTYPE));
  342.  
  343. }
  344.  
  345. int read_nodes(NODETYPE *noarray, DIRENTRYTYPE *entry) {
  346.  
  347.         unsigned long int j;
  348.  
  349.         stack_ptr = ftell(fp);
  350.         fseek(fp,entry->startaddr,SEEK_SET);
  351.  
  352.         for(j=0;j<entry->length/sizeof(NODETYPE);j++)
  353.         {
  354.                 fread(&noarray[j],sizeof(NODETYPE),1,fp);
  355.         }
  356.  
  357.         fseek(fp,stack_ptr,SEEK_SET);
  358.         return (entry->length/sizeof(NODETYPE));
  359.  
  360. }
  361.  
  362. int read_sectors(SECTORTYPE *starray, DIRENTRYTYPE *entry) {
  363.  
  364.         unsigned long int j;
  365.  
  366.         stack_ptr = ftell(fp);
  367.         fseek(fp,entry->startaddr,SEEK_SET);
  368.  
  369.         for(j=0;j<entry->length/sizeof(SECTORTYPE);j++)
  370.         {
  371.                 fread(&starray[j],sizeof(SECTORTYPE),1,fp);
  372.         }
  373.  
  374.         fseek(fp,stack_ptr,SEEK_SET);
  375.         return (entry->length/sizeof(SECTORTYPE));
  376.  
  377. }
  378.  
  379.  
  380.