home *** CD-ROM | disk | FTP | other *** search
/ Quake 'em / QUAKEEM.BIN / quake / programs / unwad2 / unwad2.c next >
Encoding:
C/C++ Source or Header  |  1996-07-19  |  9.3 KB  |  367 lines

  1. /*  UNWAD2.C
  2.     Scott Mitting of CircleA Entertainment (smitting@netusa1.net)
  3.     This is a program I made at the request of a user to hold him
  4.     over until I release the full version of EdQuake.
  5.     -= http://www.netusa1.net/~smitting/edquake/ =-
  6.     Feel free to use this code in anyways shape or form, and if
  7.     you want to credit me.  I used the qkspec31 file when neccessary,
  8.     (it's not a difficult format, but I wanted to save time).
  9.     I would appreciate an email telling me what you're working on
  10.     if you use my code though...I'm always looking for good quake
  11.     utils :)  Gamma correction and speed omptimizations have been
  12.     implemented.
  13.  
  14.     usage:  UNWAD2 -x <wad2file.wad> <file within wad>
  15.        extracts raw data
  16.         UNWAD2 -b <wad2file.wad> <file within wad>
  17.        writes a .bmp with the same name as the file in the wad2.
  18.         UNWAD2 -l <wad2file.wad>
  19.        lists files in a wad2
  20.         UNWAD2 -v <wad2file.wad> <file within wad>
  21.        views texture in 320x200x256
  22.         UNWAD2 -h
  23.        help
  24.  
  25.     Enjoy.
  26.     COMPILED WITH: Borland Turbo C++ v3.0
  27.     */
  28.  
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <alloc.h>
  32.  
  33. typedef struct
  34. {
  35.    char magic[4];             //should be WAD2
  36.    long num;                //number of entries
  37.    long offset;                //location of directory
  38. } wad2_t;
  39.  
  40. typedef struct
  41. {
  42.    long offset;                     // Position of the entry in WAD
  43.    long dsize;                      // Size of the entry in WAD file
  44.    long size;                       // Size of the entry in memory
  45.    char type;                       // type of entry
  46.    char cmprs;                      // Compression. 0 if none.
  47.    short dummy;                     // Not used
  48.    char name[16];                   // we use only first 8
  49. } wad2entry_t;
  50.  
  51. typedef struct
  52. {
  53.    char name[16];               // Name of the texture.
  54.    long width;                  // width of picture, must be a multiple of 8
  55.    long height;                 // height of picture, must be a multiple of 8
  56.    long offset1;                // offset to u_char Pix[width   * height]
  57.    long offset2;                // offset to u_char Pix[width/2 * height/2]
  58.    long offset4;                // offset to u_char Pix[width/4 * height/4]
  59.    long offset8;                // offset to u_char Pix[width/8 * height/8]
  60. } miptex_t;
  61.  
  62. typedef struct
  63. {    /* bmfh */
  64.     int    bfType;
  65.     long   bfSize;
  66.     int    bfReserved1;
  67.     int    bfReserved2;
  68.     long   bfOffBits;
  69.     long   biSize;
  70.     long    biWidth;
  71.     long    biHeight;
  72.     int     biPlanes;
  73.     int     biBitCount;
  74.     long    biCompression;
  75.     long    biSizeImage;
  76.     long    biXPelsPerMeter;
  77.     long    biYPelsPerMeter;
  78.     long    biClrUsed;
  79.     long    biClrImportant;
  80. } bmpheader_t;
  81.  
  82.  
  83. wad2_t wad2;                //wad file header
  84. wad2entry_t  wad2entry;            //wad file entry
  85. miptex_t miptex;            //mip texture
  86. FILE *wadptr;                //wad file pointer
  87. char pal[768];                //quake palette
  88.  
  89. unsigned char far *video_buffer = (unsigned char far *) 0xa0000000;
  90.  
  91. //prepares wad2 for use.
  92. void wad2open(char *filename)
  93. {
  94.    wadptr = fopen(filename, "rb");    //open file
  95.    if (!wadptr) return;            //check load result
  96.    fread(&wad2,12,1,wadptr);        //read header
  97.    wad2.magic[4] = 0;            //add ASCIIZ end of string
  98. }
  99.  
  100. //close wad2 file
  101. void wad2close()
  102. {
  103.    fclose(wadptr);                      //close file
  104. }
  105.  
  106. //checks to see if it loaded ok
  107. int wad2ok()
  108. {
  109.    if (!wadptr) return 0;        //verify pointer
  110.    return 1;
  111. }
  112.  
  113. void wad2getentry(int n)
  114. {
  115.    fseek(wadptr,wad2.offset+(n*32),0);        //set pointer
  116.    fread(&wad2entry,32,1,wadptr);                //read entry
  117. }
  118.  
  119. int wad2findfile(char *filename)
  120. {
  121.    int t;
  122.    if (!wad2ok()) return -1;
  123.    for (t = 0; t < wad2.num; t++)
  124.    {
  125.       wad2getentry(t);
  126.       //to port change to strcmp...(i=not case sensitive)
  127.       if (strcmpi(filename, wad2entry.name) == 0) t += 1000;
  128.    }
  129.    if (t < 1000) return -1;
  130.    t-=1001;
  131.    return t;
  132. }
  133.  
  134. void wad2getmip(int n)
  135. {
  136.    wad2getentry(n);                             //find offset
  137.    fseek(wadptr,wad2entry.offset,0);        //set pointer
  138.    fread(&miptex,40,1,wadptr);                //read mip header
  139. }
  140.  
  141. void wad2getpalette()
  142. {
  143.    FILE *p;
  144.    int t;
  145.    p = fopen("quake.pal","rb");
  146.    fseek(p, 0, 0);
  147.    for (t = 0; t < 768; t++)
  148.       pal[t] = fgetc(p);
  149.    fclose(p);
  150. }
  151.  
  152. void wad2list()
  153. {
  154.    int t;
  155.    for (t = 0; t < wad2.num; t++)
  156.    {
  157.       wad2getentry(t);
  158.       printf("%20s %10li 0x%08lx\n",
  159.         wad2entry.name,
  160.         wad2entry.dsize,
  161.         wad2entry.offset);
  162.    }
  163. }
  164.  
  165. void setvideomode(int mode)
  166. {
  167.    _AX = mode;
  168.    asm int 0x10
  169. }
  170.  
  171. #define PALETTE_MASK        0x3c6
  172. #define PALETTE_REGISTER_RD 0x3c7
  173. #define PALETTE_REGISTER_WR 0x3c8
  174. #define PALETTE_DATA        0x3c9
  175.  
  176. void setpal(unsigned char attr,unsigned char red, unsigned char green, unsigned char blue)
  177. {
  178.    outp(PALETTE_MASK,0xff);
  179.    outp(PALETTE_REGISTER_WR, attr);
  180.    outp(PALETTE_DATA,red);
  181.    outp(PALETTE_DATA,green);
  182.    outp(PALETTE_DATA,blue);
  183. }
  184.  
  185. void setquakepal()
  186. {
  187.    int t;
  188.    for (t = 0; t < 256; t++)
  189.       setpal(t,pal[t*3],pal[t*3+1],pal[t*3+2]);
  190. }
  191.  
  192. void putpixel(int x, int y, char c)
  193. {
  194.    video_buffer[(y<<8)+(y<<6)+x] = c;
  195. }
  196.  
  197. void wad2view(int n)
  198. {
  199.    int x, y;
  200.     if (n < 0) return;
  201.    wad2getmip(n);
  202.    fseek(wadptr,wad2entry.offset + miptex.offset1,0);
  203.    setvideomode(0x0013);
  204.    wad2getpalette();
  205.    setquakepal();
  206.    for (y = 0; y < miptex.height; y++)
  207.       for (x = 0; x < miptex.width; x++)
  208.      putpixel(x,y,fgetc(wadptr));
  209.    getch();
  210.    setvideomode(0x0003);
  211. }
  212.  
  213. void wad2savebmp(int n)
  214. {
  215.     bmpheader_t bmpfile;
  216.     FILE *out;
  217.     char *r;
  218.     long i, x, y;
  219.     if (n < 0) return;
  220.     wad2getmip(n);
  221.     fseek(wadptr,wad2entry.offset + miptex.offset1,0);
  222.     wad2getpalette();
  223.     bmpfile.bfType = 0x4d42; // 'BM'
  224.     bmpfile.bfSize = sizeof(bmpfile) + 1024 + (miptex.width * miptex.height);
  225.     bmpfile.bfReserved1=bmpfile.bfReserved2=0;
  226.     bmpfile.bfOffBits = 0x436;
  227.     bmpfile.biSize = 0x28; //this is crazy here!!!
  228.     bmpfile.biWidth = miptex.width;
  229.     bmpfile.biHeight = miptex.height;
  230.     bmpfile.biPlanes = 1;
  231.     bmpfile.biBitCount = 8;
  232.     bmpfile.biCompression = 0;
  233.     bmpfile.biSizeImage = 0;
  234.     bmpfile.biXPelsPerMeter = 0xec3; //==96 ppi (english)
  235.     bmpfile.biYPelsPerMeter = 0xec3;
  236.     bmpfile.biClrUsed = 0;
  237.     bmpfile.biClrImportant = 0;
  238.  
  239.     //set up bmp name
  240.     if ((i = strlen(miptex.name)) > 8) i = 8;
  241.     miptex.name[i] = '.';
  242.     miptex.name[i+1] = 'b';
  243.     miptex.name[i+2] = 'm';
  244.     miptex.name[i+3] = 'p';
  245.     miptex.name[i+4] = 0;
  246.  
  247.     out = fopen(miptex.name,"wb");
  248.     fwrite(&bmpfile, sizeof(bmpfile), 1, out);
  249.  
  250.     //0's for gamma.
  251.     for (i = 0; i < 256; i++)
  252.     {
  253.     fputc(pal[(i*3) + 2]<<2, out);
  254.     fputc(pal[(i*3) + 1]<<2, out);
  255.     fputc(pal[(i*3) + 0]<<2, out);
  256.     fputc(0, out);
  257.  
  258.     }
  259.    i = ftell(wadptr);
  260.    r = malloc(miptex.width);
  261.    for (y = miptex.height; y > 0; y--)
  262.    {
  263.       fseek(wadptr,i+(y*miptex.width),0);
  264.       fread(r,miptex.width,1,wadptr);
  265.       fwrite(r,miptex.width,1,out);
  266.    }
  267.    free(r);
  268.    fclose(out);
  269. }
  270.  
  271.  
  272. void wad2extract(int n)
  273. {
  274.    long t,qs;
  275.    FILE *p;
  276.    char *r;
  277.    if (n < 0) return;
  278.    r = malloc(1000);
  279.    wad2getentry(n);
  280.    p = fopen(wad2entry.name,"wb");
  281.    if (!p)
  282.    {
  283.       printf("Error opening output file.\n");
  284.       return;
  285.    }
  286.    printf("saving file...");
  287.    qs = (wad2entry.dsize / 1000);
  288.    for (t = 0; t < qs; t++)
  289.    {
  290.       fread(r,1000,1,wadptr);
  291.       fwrite(r,1000,1,p);
  292.    }
  293.    t = wad2entry.dsize - (qs * 1000);
  294.    fread(r,t,1,wadptr);
  295.    fwrite(r,t,1,p);
  296.    printf("done.\n");
  297.    fclose(p);
  298.    free(r);
  299. }
  300.  
  301.  
  302. //check out WINDOW03
  303. int main(int argc, char *argv[])
  304. {
  305.    printf("UNWAD2 v1.0  by Scott Mitting of CircleA (smitting@netusa1.net)\n");
  306.    printf("public domain. please distibute with source code\n");
  307.    printf("get EdQuake at http://www.netusa1.net/~smitting/edquake/\n");
  308.    printf("-h for help\n\n");
  309.    if (!strncmpi(argv[1],"-h",2))
  310.    {
  311.       printf("usage: UNWAD2  -[xblvh]  <wad2file> <internal file>\n");
  312.       printf("    x - extracts <internal file> from <wad2file>\n");
  313.       printf("      b - saves <internal file> to a bmp.\n");
  314.       printf("    l - lists contents of <wad2file> (use with |more)\n");
  315.       printf("    v - views <internal file>\n");
  316.       printf("    h - shows this help screen\n\n");
  317.    }
  318.    if (!strncmpi(argv[1],"-x",2))
  319.    {
  320.       wad2open(argv[2]);
  321.       printf("opening %s...\n",argv[2]);
  322.       if (!wad2ok())
  323.       {
  324.      printf("Error opening wad2 file\n");
  325.      return 0;
  326.       }
  327.       wad2extract(wad2findfile(argv[3]));
  328.       wad2close();
  329.    }
  330.    if (!strncmpi(argv[1],"-b",2))
  331.    {
  332.       wad2open(argv[2]);
  333.       printf("opening %s...\n",argv[2]);
  334.       if (!wad2ok())
  335.       {
  336.      printf("Error opening wad2 file\n");
  337.      return 0;
  338.       }
  339.       wad2savebmp(wad2findfile(argv[3]));
  340.       wad2close();
  341.    }
  342.    if (!strncmpi(argv[1],"-l",2))
  343.    {
  344.       wad2open(argv[2]);
  345.       printf("opening %s...\n",argv[2]);
  346.       if (!wad2ok())
  347.       {
  348.      printf("Error opening wad2 file\n");
  349.      return 0;
  350.       }
  351.       wad2list();
  352.       wad2close();
  353.    }
  354.    if (!strncmpi(argv[1],"-v",2))
  355.    {
  356.       wad2open(argv[2]);
  357.       printf("opening %s...\n",argv[2]);
  358.       if (!wad2ok())
  359.       {
  360.      printf("Error opening wad2 file\n");
  361.      return 0;
  362.       }
  363.       wad2view(wad2findfile(argv[3]));
  364.       wad2close();
  365.    }
  366.    return 0;
  367. }