home *** CD-ROM | disk | FTP | other *** search
/ Late Night VRML 2.0 with Java CD-ROM / code.zip / Ch13 / qar.java < prev    next >
Text File  |  1997-01-14  |  3KB  |  69 lines

  1. // Quake archive file class
  2.  
  3. // Written by Bernie Roehl, October 1996
  4.  
  5. // Based on the Quake Specs 3.2 document
  6.  
  7. import java.io.*;
  8. import quake.*;
  9.  
  10. public class qar {
  11.         public static void main(String[] args) throws IOException {
  12.                 if (args.length < 1) {
  13.                         System.err.println("Usage: qar cmd [filename [names [...]]]");
  14.                         System.exit(1);
  15.                 }
  16.                 String cmd = args[0];
  17.                 String filename = (args.length > 1) ? args[1] : "pak0.pak";
  18.                 RandomAccessFile quakefile = new RandomAccessFile(filename, "r");
  19.                 if (quakefile.readInt() != 0x5041434B) {
  20.                         System.err.println("missing signature");
  21.                         System.exit(2);
  22.                 }
  23.                 int diroffset = swap32(quakefile.readInt());
  24.                 int dirsize = swap32(quakefile.readInt());
  25.                 int n_direntries = dirsize / 64;  // 64 byte per directory entry
  26.                 quakefile.seek(diroffset);
  27.                 String prefix = "";
  28.                 if (args.length > 2)
  29.                         prefix = args[2];
  30.                 for (int i = 0; i < n_direntries; ++i) {
  31.                         byte[] fname = new byte[0x38];
  32.                         quakefile.read(fname);
  33.                         String subfilename = new String(fname, 0);
  34.                         int zerobyte = subfilename.indexOf(0);
  35.                         if (zerobyte >= 0)
  36.                                 subfilename = subfilename.substring(0, zerobyte);
  37.                         int offset = swap32(quakefile.readInt());
  38.                         int size = swap32(quakefile.readInt());
  39.                         if (cmd.charAt(0) == 't') {
  40.                                 if (subfilename.startsWith(prefix))
  41.                                         System.out.println(size + " " + subfilename);
  42.                         }
  43.                         else if (subfilename.startsWith(prefix)) {
  44.                                 System.out.println("Extracting " + subfilename);
  45.                                 FileOutputStream out = new FileOutputStream(subfilename);
  46.                                 long savedpos = quakefile.getFilePointer();
  47.                                 quakefile.seek(offset);
  48.                                 byte[] buffer = new byte[1024];
  49.                                 do {
  50.                                         int n = quakefile.read(buffer);
  51.                                         out.write(buffer, 0, n);
  52.                                         size -= n;
  53.                                 } while (size > 0);
  54.                                 quakefile.seek(savedpos);
  55.                         }
  56.                 }
  57.         }
  58.  
  59.         static int swap32(int value) {
  60.                 return
  61.                        ((value >> 24) & 0x000000FF) +
  62.                        ((value >> 8)  & 0x0000FF00) +
  63.                        ((value << 8)  & 0x00FF0000) +
  64.                        ((value << 24) & 0xFF000000);
  65.         }
  66.  
  67. }
  68.  
  69.