home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 5257 / source.7z / ps3_neptunia_mk2.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2012-04-05  |  87.0 KB  |  2,571 lines

  1. #include "xentax.h"
  2. #include "x_file.h"
  3. #include "x_findfile.h"
  4. #include "x_stream.h"
  5. #include "x_dds.h"
  6. #include "x_smc.h"
  7. #include "x_lwo.h"
  8. #include "ps3_neptunia_mk2.h"
  9.  
  10. #define X_SYSTEM PS3
  11. #define X_GAME   NEPTUNIA_MK2
  12.  
  13. namespace X_SYSTEM { namespace X_GAME {
  14.  
  15. struct point2D {
  16.  real32 x;
  17.  real32 y;
  18. };
  19.  
  20. struct point3D {
  21.  real32 x, y, z;
  22. };
  23.  
  24. struct triangle3D {
  25.  uint32 a;
  26.  uint32 b;
  27.  uint32 c;
  28. };
  29.  
  30. struct TEXTUREINFO {
  31.  unsigned int data1;
  32.  unsigned int data2;
  33.  unsigned int data3;
  34.  unsigned int data4;
  35.  unsigned int data5;
  36.  unsigned int data6;
  37.  unsigned int data7;
  38.  unsigned int data8;
  39. };
  40.  
  41. class extractor {
  42.  private :
  43.   std::string pathname;
  44.  private :
  45.   std::ifstream ifile;
  46.   std::ofstream dfile;
  47.   bool debug;
  48.  private :
  49.   std::deque<std::string> string_table;
  50.   std::deque<TEXTUREINFO> texture_info;
  51.  private :
  52.   std::deque<point3D> points;
  53.   std::deque<point3D> normal;
  54.   std::deque<point2D> uvdata;
  55.  private :
  56.   bool processTID(const std::string& filename);
  57.   bool processISM(const std::string& filename);
  58.  private :
  59.   bool clearISM(void);
  60.   bool processXXX(uint32 offset, uint32 parent, uint32 caller);
  61.   bool processX03(uint32 offset, uint32 parent, uint32 caller); // R node (scene) (0x04, 0x05 children)
  62.   bool processX04(uint32 offset, uint32 parent, uint32 caller); // C node (scene) (0x4C, 0x4D, 0x5B children)
  63.   bool processX05(uint32 offset, uint32 parent, uint32 caller); // C node (scene) (0x5B, 0x5C children)
  64.   bool processX0A(uint32 offset, uint32 parent, uint32 caller); // C node (geometry) (0x46, 0x59, 0x6E children)
  65.   bool processX0B(uint32 offset, uint32 parent, uint32 caller); // R node (geometry) (0x0A children)
  66.   bool processX0D(uint32 offset, uint32 parent, uint32 caller); // C node (attributes) (0x6C children)
  67.   bool processX0F(uint32 offset, uint32 parent, uint32 caller); // TODO: motion
  68.   bool processX21(uint32 offset, uint32 parent, uint32 caller); // R node (string table) (no children)
  69.   bool processX2D(uint32 offset, uint32 parent, uint32 caller); // C node (texture node) (no children)
  70.   bool processX2E(uint32 offset, uint32 parent, uint32 caller); // R node (texture list) (0x2D children)
  71.   bool processX30(uint32 offset, uint32 parent, uint32 caller); // C node (skinning) (0x44 children)
  72.   bool processX31(uint32 offset, uint32 parent, uint32 caller); // C node (skinning) (0x30 children)
  73.   bool processX32(uint32 offset, uint32 parent, uint32 caller); // R node (skinning) (0x31 children)
  74.   bool processX34(uint32 offset, uint32 parent, uint32 caller); // TODO: motion
  75.   bool processX44(uint32 offset, uint32 parent, uint32 caller); // C node (skinning) (no children)
  76.   bool processX45(uint32 offset, uint32 parent, uint32 caller); // C node (geometry) (no children)
  77.   bool processX46(uint32 offset, uint32 parent, uint32 caller); // C node (geometry) (0x45, 0x6E children)
  78.   bool processX4B(uint32 offset, uint32 parent, uint32 caller); // C node (materials) (no children)
  79.   bool processX4C(uint32 offset, uint32 parent, uint32 caller); // C node (scene) (0x4B children)
  80.   bool processX4D(uint32 offset, uint32 parent, uint32 caller); // C node (scene) (0x4B children)
  81.   bool processX50(uint32 offset, uint32 parent, uint32 caller);
  82.   bool processX59(uint32 offset, uint32 parent, uint32 caller); // C node (geometry) (no children)
  83.   bool processX5B(uint32 offset, uint32 parent, uint32 caller); // C node (transforms) (no children)
  84.   bool processX5C(uint32 offset, uint32 parent, uint32 caller); // C node (scene) (no children)
  85.   bool processX61(uint32 offset, uint32 parent, uint32 caller); // R node (attributes) (0x0D children)
  86.   bool processX62(uint32 offset, uint32 parent, uint32 caller); // R node (0x63 children)
  87.   bool processX63(uint32 offset, uint32 parent, uint32 caller); // C node (0x65 children)
  88.   bool processX65(uint32 offset, uint32 parent, uint32 caller); // C node (no children)
  89.   bool processX6A(uint32 offset, uint32 parent, uint32 caller); // C node (0x6B children)
  90.   bool processX6B(uint32 offset, uint32 parent, uint32 caller); // C node (no children, 0x6B children)
  91.   bool processX6C(uint32 offset, uint32 parent, uint32 caller); // C node (0x6A children)
  92.   bool processX6E(uint32 offset, uint32 parent, uint32 caller); // C node (geometry) (no children)
  93.  public :
  94.   bool extract(void);
  95.  public :
  96.   extractor(const char* pn) : pathname(pn), debug(false) {}
  97.  ~extractor() {}
  98. };
  99.  
  100. };};
  101.  
  102. namespace X_SYSTEM { namespace X_GAME {
  103.  
  104. bool extractor::extract(void)
  105. {
  106.  using namespace std;
  107.  bool doTID = false;
  108.  bool doISM = true;
  109.  debug = true;
  110.  
  111.  if(doTID) {
  112.     cout << "STAGE 1" << endl;
  113.     cout << "Processing TID files..." << endl;
  114.     deque<string> filelist;
  115.     BuildFilenameList(filelist, "tid", pathname.c_str());
  116.     for(size_t i = 0; i < filelist.size(); i++) {
  117.         cout << "Processing file " << (i + 1) << " of " << filelist.size() << ": " << filelist[i] << "." << endl;
  118.         if(!processTID(filelist[i])) return false;
  119.        }
  120.     cout << endl;
  121.    }
  122.  
  123.  if(doISM) {
  124.     cout << "STAGE 2" << endl;
  125.     cout << "Processing ISM files..." << endl;
  126.     deque<string> filelist;
  127.     BuildFilenameList(filelist, "ism2", pathname.c_str());
  128.     for(size_t i = 0; i < filelist.size(); i++) {
  129.         cout << "Processing file " << (i + 1) << " of " << filelist.size() << ": " << filelist[i] << "." << endl;
  130.         if(!processISM(filelist[i])) return false;
  131.        }
  132.     cout << endl;
  133.    }
  134.  
  135.  return true;
  136. }
  137.  
  138. bool extractor::processTID(const std::string& filename)
  139. {
  140.  // open file
  141.  using namespace std;
  142.  ifstream ifile(filename.c_str(), ios::binary);
  143.  if(!ifile) return error("Could not open TID file.");
  144.  
  145.  // filesize
  146.  ifile.seekg(0, ios::end);
  147.  size_t filesize = (size_t)ifile.tellg();
  148.  ifile.seekg(0, ios::beg);
  149.  
  150.  // create output filename
  151.  string ofname = GetPathnameFromFilename(filename);
  152.  ofname += GetShortFilenameWithoutExtension(filename);
  153.  ofname += ".dds";
  154.  
  155.  // texture types
  156.  const unsigned int T_TYPE0 = 0x54494413; // uncompressed
  157.  const unsigned int T_TYPE1 = 0x54494481; // DXT1/DXT5
  158.  const unsigned int T_TYPE2 = 0x54494483; // uncompressed
  159.  const unsigned int T_TYPE3 = 0x54494487; // uncompressed (scrambled)
  160.  const unsigned int T_TYPE4 = 0x54494489; // DXT1/DXT5 (upside down)
  161.  const unsigned int T_TYPE5 = 0x54494491; // DXT1/DXT5 (toon_shadow)
  162.  const unsigned int T_TYPE6 = 0x54494493; // uncompressed
  163.  const unsigned int T_TYPE7 = 0x54494497; // uncompressed (scrambled)
  164.  const unsigned int T_TYPE8 = 0x54494499; // DXT1/DXT5 (mipmapped)
  165.  const unsigned int T_TYPE9 = 0x5449449B; // uncompressed (upside down)
  166.  
  167.  // uncompressed RGBA mask types
  168.  const unsigned int MASK_B = 0xFF000000;
  169.  const unsigned int MASK_G = 0x00FF0000;
  170.  const unsigned int MASK_R = 0x0000FF00;
  171.  const unsigned int MASK_A = 0x000000FF;
  172.  
  173.  // read magic
  174.  uint32 magic = BE_read_uint32(ifile);
  175.  if(ifile.fail()) return error("Read error.");
  176.  
  177.  // test magic
  178.  switch(magic) {
  179.    case(T_TYPE0) : break;
  180.    case(T_TYPE1) : break;
  181.    case(T_TYPE2) : break;
  182.    case(T_TYPE3) : break;
  183.    case(T_TYPE4) : break;
  184.    case(T_TYPE5) : break;
  185.    case(T_TYPE6) : break;
  186.    case(T_TYPE7) : break;
  187.    case(T_TYPE8) : break;
  188.    case(T_TYPE9) : break;
  189.    default : return error("Unknown TID file type.");
  190.   }
  191.  
  192.  // read filesize
  193.  uint32 head01 = BE_read_uint32(ifile);
  194.  if(magic == T_TYPE0 || magic == T_TYPE2 || magic == T_TYPE3 || magic == T_TYPE6 || magic == T_TYPE7) {
  195.     if(head01 != filesize) return error("Read versus actual filesizes do not match.");
  196.    }
  197.  
  198.  // read offset to texture data
  199.  uint32 head02 = BE_read_uint32(ifile);
  200.  if(head02 == 0) return error("Invalid head02.");
  201.  
  202.  // read number of files (always 1)
  203.  uint32 head03 = BE_read_uint32(ifile);
  204.  if(head03 != 1) return error("Invalid head03.");
  205.  
  206.  // TYPE 0
  207.  static uint32 index = 0;
  208.  if(magic == T_TYPE0)
  209.    {
  210.     char name[32];
  211.     BE_read_array(ifile, &name[0], 32);
  212.  
  213.     uint32 head04 = BE_read_uint32(ifile); // 64
  214.     uint32 head05 = BE_read_uint32(ifile); // dx
  215.     uint32 head06 = BE_read_uint32(ifile); // dy
  216.     uint32 head07 = BE_read_uint32(ifile); // bpp (32)
  217.     uint32 head08 = BE_read_uint16(ifile); // 1
  218.     uint32 head09 = BE_read_uint16(ifile); // 1
  219.     uint32 head10 = BE_read_uint32(ifile); // 0
  220.     uint32 head11 = BE_read_uint32(ifile); // size of image data
  221.     uint32 head12 = BE_read_uint32(ifile); // 128
  222.     if(head04 != 0x40) return error("TID TYPE 0 unexpected value. Expecting 0x40.");
  223.     if(head07 != 0x20) return error("TID TYPE 0 unexpected value. Expecting 0x20.");
  224.     if(head08 != 0x01) return error("TID TYPE 0 unexpected value. Expecting 0x01.");
  225.     if(head09 != 0x01) return error("TID TYPE 0 unexpected value. Expecting 0x01.");
  226.     if(head10 != 0x00) return error("TID TYPE 0 unexpected value. Expecting 0x00.");
  227.     if(head12 != 0x80) return error("TID TYPE 0 unexpected value. Expecting 0x80.");
  228.  
  229.     // create DDS header
  230.     DDS_HEADER ddsh;
  231.     CreateUncompressedDDSHeader(head05, head06, 0, MASK_R, MASK_G, MASK_B, MASK_A, FALSE, &ddsh);
  232.  
  233.     // read DDS data
  234.     ifile.seekg(head02);
  235.     boost::shared_array<char> data(new char[head11]);
  236.     ifile.read(data.get(), head11);
  237.  
  238.     // save DDS data
  239.     ofstream ofile(ofname.c_str(), ios::binary);
  240.     if(!ofile) return error("Failed to create DDS file.");
  241.     ofile.write("DDS ", 4);
  242.     ofile.write((char*)&ddsh, sizeof(ddsh));
  243.     ofile.write(data.get(), head11);
  244.    }
  245.  else if(magic == T_TYPE1)
  246.    {
  247.     uint32 head04 = BE_read_uint32(ifile); // ??
  248.     uint32 head05 = BE_read_uint32(ifile); // ??
  249.     uint32 head06 = BE_read_uint32(ifile); // ?? 
  250.     uint32 head07 = BE_read_uint32(ifile); // ??
  251.  
  252.     // read filename
  253.     char name[32];
  254.     BE_read_array(ifile, &name[0], 32);
  255.  
  256.     uint32 head08 = BE_read_uint32(ifile); // 0x60
  257.     uint32 head09 = BE_read_uint32(ifile); // dx
  258.     uint32 head10 = BE_read_uint32(ifile); // dy
  259.     uint32 head11 = BE_read_uint32(ifile); // 0x00
  260.     uint32 head12 = BE_read_uint16(ifile); // 0x01
  261.     uint32 head13 = BE_read_uint16(ifile); // 0x01
  262.     uint32 head14 = BE_read_uint32(ifile); // 0x00
  263.     uint32 head15 = BE_read_uint32(ifile); // size of image data
  264.     uint32 head16 = BE_read_uint32(ifile); // 0x80
  265.     uint32 head17 = BE_read_uint32(ifile); // 0x04
  266.     uint32 head18 = BE_read_uint32(ifile); // compression
  267.     uint32 head19 = BE_read_uint32(ifile); // 0x1000
  268.     uint32 head20 = BE_read_uint32(ifile); // 0x00
  269.     if(head08 != 0x60) return error("TID TYPE 1 unexpected value. Expecting 0x60.");
  270.     if(head11 != 0x00) return error("TID TYPE 1 unexpected value. Expecting 0x00.");
  271.     if(head12 != 0x01) return error("TID TYPE 1 unexpected value. Expecting 0x01.");
  272.     if(head13 != 0x01) return error("TID TYPE 1 unexpected value. Expecting 0x01.");
  273.     if(head14 != 0x00) return error("TID TYPE 1 unexpected value. Expecting 0x00.");
  274.     if(head16 != 0x80) return error("TID TYPE 1 unexpected value. Expecting 0x80.");
  275.     if(head17 != 0x04) return error("TID TYPE 1 unexpected value. Expecting 0x04.");
  276.     if(head20 != 0x00) return error("TID TYPE 1 unexpected value. Expecting 0x00.");
  277.  
  278.     // create DDS header
  279.     DDS_HEADER ddsh;
  280.     if(head18 == 0x31545844) CreateDXT1Header(head09, head10, 0, FALSE, &ddsh);
  281.     else if(head18 == 0x35545844) CreateDXT5Header(head09, head10, 0, FALSE, &ddsh);
  282.     else return error("Unknown compression type.");
  283.  
  284.     // read DDS data
  285.     ifile.seekg(head02);
  286.     boost::shared_array<char> data(new char[head15]);
  287.     ifile.read(data.get(), head15);
  288.  
  289.     // save DDS data
  290.     ofstream ofile(ofname.c_str(), ios::binary);
  291.     if(!ofile) return error("Failed to create DDS file.");
  292.     ofile.write("DDS ", 4);
  293.     ofile.write((char*)&ddsh, sizeof(ddsh));
  294.     ofile.write(data.get(), head15);
  295.    }
  296.  else if(magic == T_TYPE2)
  297.    {
  298.     uint32 head04 = BE_read_uint32(ifile); // 0x01
  299.     uint32 head05 = BE_read_uint32(ifile); // 0x20
  300.     uint32 head06 = BE_read_uint32(ifile); // 0x00
  301.     uint32 head07 = BE_read_uint32(ifile); // 0x00
  302.  
  303.     // read filename
  304.     char name[32];
  305.     BE_read_array(ifile, &name[0], 32);
  306.  
  307.     uint32 head08 = BE_read_uint32(ifile); // 0x60
  308.     uint32 head09 = BE_read_uint32(ifile); // dx
  309.     uint32 head10 = BE_read_uint32(ifile); // dy
  310.     uint32 head11 = BE_read_uint32(ifile); // 0x20
  311.     uint32 head12 = BE_read_uint16(ifile); // 0x01
  312.     uint32 head13 = BE_read_uint16(ifile); // 0x01
  313.     uint32 head14 = BE_read_uint32(ifile); // 0x00
  314.     uint32 head15 = BE_read_uint32(ifile); // size of image data
  315.     uint32 head16 = BE_read_uint32(ifile); // 0x80
  316.  
  317.     // create DDS header
  318.     DDS_HEADER ddsh;
  319.     CreateUncompressedDDSHeader(head09, head10, 0, MASK_R, MASK_G, MASK_B, MASK_A, FALSE, &ddsh);
  320.  
  321.     // read DDS data
  322.     ifile.seekg(head02);
  323.     boost::shared_array<char> data(new char[head15]);
  324.     ifile.read(data.get(), head15);
  325.  
  326.     // save DDS data
  327.     ofstream ofile(ofname.c_str(), ios::binary);
  328.     if(!ofile) return error("Failed to create DDS file.");
  329.     ofile.write("DDS ", 4);
  330.     ofile.write((char*)&ddsh, sizeof(ddsh));
  331.     ofile.write(data.get(), head15);
  332.    }
  333.  else if(magic == T_TYPE3)
  334.    {
  335.     uint32 head04 = BE_read_uint32(ifile); // 0x01
  336.     uint32 head05 = BE_read_uint32(ifile); // 0x20
  337.     uint32 head06 = BE_read_uint32(ifile); // 0x00
  338.     uint32 head07 = BE_read_uint32(ifile); // 0x00
  339.  
  340.     // read filename
  341.     char name[32];
  342.     BE_read_array(ifile, &name[0], 32);
  343.  
  344.     uint32 head08 = BE_read_uint32(ifile); // 0x60
  345.     uint32 head09 = BE_read_uint32(ifile); // dx
  346.     uint32 head10 = BE_read_uint32(ifile); // dy
  347.     uint32 head11 = BE_read_uint32(ifile); // 0x20
  348.     uint32 head12 = BE_read_uint16(ifile); // 0x01
  349.     uint32 head13 = BE_read_uint16(ifile); // 0x01
  350.     uint32 head14 = BE_read_uint32(ifile); // 0x00
  351.     uint32 head15 = BE_read_uint32(ifile); // size of image data
  352.     uint32 head16 = BE_read_uint32(ifile); // 0x80
  353.  
  354.     // create DDS header
  355.     DDS_HEADER ddsh;
  356.     CreateUncompressedDDSHeader(head09, head10, 0, MASK_R, MASK_G, MASK_B, MASK_A, FALSE, &ddsh);
  357.  
  358.     // read DDS data
  359.     ifile.seekg(head02);
  360.     boost::shared_array<char> data(new char[head15]);
  361.     boost::shared_array<char> copy(new char[head15]);
  362.     ifile.read(data.get(), head15);
  363.  
  364.     // deswizzle
  365.     for(uint32 r = 0; r < head10; r++) {
  366.         for(uint32 c = 0; c < head09; c++) {
  367.             uint32 morton = array_to_morton(r, c);
  368.             uint32 copy_position = 4*r*head09 + 4*c;
  369.             uint32 data_position = 4*morton;
  370.             copy[copy_position++] = data[data_position + 0]; // b
  371.             copy[copy_position++] = data[data_position + 1]; // g
  372.             copy[copy_position++] = data[data_position + 2]; // r
  373.             copy[copy_position++] = data[data_position + 3]; // a
  374.            }
  375.        }
  376.  
  377.     // save DDS data
  378.     ofstream ofile(ofname.c_str(), ios::binary);
  379.     if(!ofile) return error("Failed to create DDS file.");
  380.     ofile.write("DDS ", 4);
  381.     ofile.write((char*)&ddsh, sizeof(ddsh));
  382.     ofile.write(copy.get(), head15);
  383.    }
  384.  else if(magic == T_TYPE4)
  385.    {
  386.     uint32 head04 = BE_read_uint32(ifile); // 0x01
  387.     uint32 head05 = BE_read_uint32(ifile); // 0x20
  388.     uint32 head06 = BE_read_uint32(ifile); // 0x00
  389.     uint32 head07 = BE_read_uint32(ifile); // 0x00
  390.  
  391.     // read filename
  392.     char name[32];
  393.     BE_read_array(ifile, &name[0], 32);
  394.  
  395.     uint32 head08 = BE_read_uint32(ifile); // 0x60
  396.     uint32 head09 = BE_read_uint32(ifile); // dx
  397.     uint32 head10 = BE_read_uint32(ifile); // dy
  398.     uint32 head11 = BE_read_uint32(ifile); // 0x00
  399.     uint32 head12 = BE_read_uint16(ifile); // 0x01
  400.     uint32 head13 = BE_read_uint16(ifile); // 0x01
  401.     uint32 head14 = BE_read_uint32(ifile); // 0x00
  402.     uint32 head15 = BE_read_uint32(ifile); // size of image data
  403.     uint32 head16 = BE_read_uint32(ifile); // 0x80
  404.     uint32 head17 = BE_read_uint32(ifile); // 0x04
  405.     uint32 head18 = BE_read_uint32(ifile); // compression
  406.     uint32 head19 = BE_read_uint32(ifile); // 0x1000
  407.     uint32 head20 = BE_read_uint32(ifile); // 0x00
  408.  
  409.     // create DDS header
  410.     DDS_HEADER ddsh;
  411.     if(head18 == 0x31545844) CreateDXT1Header(head09, head10, 0, FALSE, &ddsh);
  412.     else if(head18 == 0x35545844) CreateDXT5Header(head09, head10, 0, FALSE, &ddsh);
  413.     else return error("Unknown compression type.");
  414.  
  415.     // read DDS data
  416.     ifile.seekg(head02);
  417.     boost::shared_array<char> data(new char[head15]);
  418.     ifile.read(data.get(), head15);
  419.  
  420.     // save DDS data
  421.     ofstream ofile(ofname.c_str(), ios::binary);
  422.     if(!ofile) return error("Failed to create DDS file.");
  423.     ofile.write("DDS ", 4);
  424.     ofile.write((char*)&ddsh, sizeof(ddsh));
  425.     ofile.write(data.get(), head15);
  426.    }
  427.  else if(magic == T_TYPE5)
  428.    {
  429.     uint32 head04 = BE_read_uint32(ifile); // 0x01
  430.     uint32 head05 = BE_read_uint32(ifile); // 0x20
  431.     uint32 head06 = BE_read_uint32(ifile); // 0x00
  432.     uint32 head07 = BE_read_uint32(ifile); // 0x00
  433.  
  434.     // read filename
  435.     char name[32];
  436.     BE_read_array(ifile, &name[0], 32);
  437.  
  438.     uint32 head08 = BE_read_uint32(ifile); // 0x60
  439.     uint32 head09 = BE_read_uint32(ifile); // dx
  440.     uint32 head10 = BE_read_uint32(ifile); // dy
  441.     uint32 head11 = BE_read_uint32(ifile); // 0x00
  442.     uint32 head12 = BE_read_uint16(ifile); // 0x01
  443.     uint32 head13 = BE_read_uint16(ifile); // 0x02 (different)
  444.     uint32 head14 = BE_read_uint32(ifile); // 0x00
  445.     uint32 head15 = BE_read_uint32(ifile); // size of image data
  446.     uint32 head16 = BE_read_uint32(ifile); // 0x80
  447.     uint32 head17 = BE_read_uint32(ifile); // 0x04
  448.     uint32 head18 = BE_read_uint32(ifile); // compression
  449.     uint32 head19 = BE_read_uint32(ifile); // ????
  450.     uint32 head20 = BE_read_uint32(ifile); // 0x00
  451.  
  452.     // create DDS header
  453.     DDS_HEADER ddsh;
  454.     if(head18 == 0x31545844) CreateDXT1Header(head09, head10, 0, FALSE, &ddsh);
  455.     else if(head18 == 0x35545844) CreateDXT5Header(head09, head10, 0, FALSE, &ddsh);
  456.     else return error("Unknown compression type.");
  457.  
  458.     // read DDS data
  459.     ifile.seekg(head02);
  460.     boost::shared_array<char> data(new char[head15]);
  461.     ifile.read(data.get(), head15);
  462.  
  463.     // save DDS data
  464.     ofstream ofile(ofname.c_str(), ios::binary);
  465.     if(!ofile) return error("Failed to create DDS file.");
  466.     ofile.write("DDS ", 4);
  467.     ofile.write((char*)&ddsh, sizeof(ddsh));
  468.     ofile.write(data.get(), head15);
  469.    }
  470.  else if(magic == T_TYPE6)
  471.    {
  472.     uint32 head04 = BE_read_uint32(ifile); // 0x01
  473.     uint32 head05 = BE_read_uint32(ifile); // 0x20
  474.     uint32 head06 = BE_read_uint32(ifile); // 0x00
  475.     uint32 head07 = BE_read_uint32(ifile); // 0x00
  476.  
  477.     // read filename
  478.     char name[32];
  479.     BE_read_array(ifile, &name[0], 32);
  480.  
  481.     uint32 head08 = BE_read_uint32(ifile); // 0x60
  482.     uint32 head09 = BE_read_uint32(ifile); // dx
  483.     uint32 head10 = BE_read_uint32(ifile); // dy
  484.     uint32 head11 = BE_read_uint32(ifile); // 0x20
  485.     uint32 head12 = BE_read_uint16(ifile); // 0x01
  486.     uint32 head13 = BE_read_uint16(ifile); // 0x01
  487.     uint32 head14 = BE_read_uint32(ifile); // 0x00
  488.     uint32 head15 = BE_read_uint32(ifile); // size of image data
  489.     uint32 head16 = BE_read_uint32(ifile); // 0x80
  490.     // some extra data at 0x78 (0x0101)
  491.  
  492.     // create DDS header
  493.     DDS_HEADER ddsh;
  494.     CreateUncompressedDDSHeader(head09, head10, 0, MASK_R, MASK_G, MASK_B, MASK_A, FALSE, &ddsh);
  495.  
  496.     // read DDS data
  497.     ifile.seekg(head02);
  498.     boost::shared_array<char> data(new char[head15]);
  499.     ifile.read(data.get(), head15);
  500.  
  501.     // save DDS data
  502.     ofstream ofile(ofname.c_str(), ios::binary);
  503.     if(!ofile) return error("Failed to create DDS file.");
  504.     ofile.write("DDS ", 4);
  505.     ofile.write((char*)&ddsh, sizeof(ddsh));
  506.     ofile.write(data.get(), head15);
  507.    }
  508.  else if(magic == T_TYPE7)
  509.    {
  510.     uint32 head04 = BE_read_uint32(ifile); // 0x01
  511.     uint32 head05 = BE_read_uint32(ifile); // 0x20
  512.     uint32 head06 = BE_read_uint32(ifile); // 0x00
  513.     uint32 head07 = BE_read_uint32(ifile); // 0x00
  514.  
  515.     // read filename
  516.     char name[32];
  517.     BE_read_array(ifile, &name[0], 32);
  518.  
  519.     uint32 head08 = BE_read_uint32(ifile); // 0x60
  520.     uint32 head09 = BE_read_uint32(ifile); // dx
  521.     uint32 head10 = BE_read_uint32(ifile); // dy
  522.     uint32 head11 = BE_read_uint32(ifile); // 0x20
  523.     uint32 head12 = BE_read_uint16(ifile); // 0x01
  524.     uint32 head13 = BE_read_uint16(ifile); // 0x01
  525.     uint32 head14 = BE_read_uint32(ifile); // 0x00
  526.     uint32 head15 = BE_read_uint32(ifile); // size of image data
  527.     uint32 head16 = BE_read_uint32(ifile); // 0x80
  528.  
  529.     // create DDS header
  530.     DDS_HEADER ddsh;
  531.     CreateUncompressedDDSHeader(head09, head10, 0, MASK_R, MASK_G, MASK_B, MASK_A, FALSE, &ddsh);
  532.  
  533.     // read DDS data
  534.     ifile.seekg(head02);
  535.     boost::shared_array<char> data(new char[head15]);
  536.     boost::shared_array<char> copy(new char[head15]);
  537.     ifile.read(data.get(), head15);
  538.  
  539.     // deswizzle
  540.     for(uint32 r = 0; r < head10; r++) {
  541.         for(uint32 c = 0; c < head09; c++) {
  542.             uint32 morton = array_to_morton(r, c);
  543.             uint32 copy_position = 4*r*head09 + 4*c;
  544.             uint32 data_position = 4*morton;
  545.             copy[copy_position++] = data[data_position + 0]; // b
  546.             copy[copy_position++] = data[data_position + 1]; // g
  547.             copy[copy_position++] = data[data_position + 2]; // r
  548.             copy[copy_position++] = data[data_position + 3]; // a
  549.            }
  550.        }
  551.  
  552.     // save DDS data
  553.     ofstream ofile(ofname.c_str(), ios::binary);
  554.     if(!ofile) return error("Failed to create DDS file.");
  555.     ofile.write("DDS ", 4);
  556.     ofile.write((char*)&ddsh, sizeof(ddsh));
  557.     ofile.write(copy.get(), head15);
  558.    }
  559.  else if(magic == T_TYPE8)
  560.    {
  561.     uint32 head04 = BE_read_uint32(ifile); // 0x01
  562.     uint32 head05 = BE_read_uint32(ifile); // 0x20
  563.     uint32 head06 = BE_read_uint32(ifile); // 0x00
  564.     uint32 head07 = BE_read_uint32(ifile); // 0x00
  565.  
  566.     // read filename
  567.     char name[32];
  568.     BE_read_array(ifile, &name[0], 32);
  569.  
  570.     uint32 head08 = BE_read_uint32(ifile); // 0x60
  571.     uint32 head09 = BE_read_uint32(ifile); // dx
  572.     uint32 head10 = BE_read_uint32(ifile); // dy
  573.     uint32 head11 = BE_read_uint32(ifile); // 0x00
  574.     uint32 head12 = BE_read_uint16(ifile); // 0x01
  575.     uint32 head13 = BE_read_uint16(ifile); // 0x05 (different)
  576.     uint32 head14 = BE_read_uint32(ifile); // 0x00
  577.     uint32 head15 = BE_read_uint32(ifile); // size of image data
  578.     uint32 head16 = BE_read_uint32(ifile); // 0x80
  579.     uint32 head17 = BE_read_uint32(ifile); // 0x04
  580.     uint32 head18 = BE_read_uint32(ifile); // compression
  581.     uint32 head19 = BE_read_uint32(ifile); // ????
  582.     uint32 head20 = BE_read_uint32(ifile); // 0x00
  583.  
  584.     // create DDS header
  585.     DDS_HEADER ddsh;
  586.     if(head18 == 0x31545844) CreateDXT1Header(head09, head10, 1, FALSE, &ddsh);
  587.     else if(head18 == 0x35545844) CreateDXT5Header(head09, head10, 1, FALSE, &ddsh);
  588.     else return error("Unknown compression type.");
  589.  
  590.     // read DDS data
  591.     ifile.seekg(head02);
  592.     boost::shared_array<char> data(new char[head15]);
  593.     ifile.read(data.get(), head15);
  594.  
  595.     // save DDS data
  596.     ofstream ofile(ofname.c_str(), ios::binary);
  597.     if(!ofile) return error("Failed to create DDS file.");
  598.     ofile.write("DDS ", 4);
  599.     ofile.write((char*)&ddsh, sizeof(ddsh));
  600.     ofile.write(data.get(), head15);
  601.    }
  602.  else if(magic == T_TYPE9)
  603.    {
  604.     uint32 head04 = BE_read_uint32(ifile); // 0x01
  605.     uint32 head05 = BE_read_uint32(ifile); // 0x20
  606.     uint32 head06 = BE_read_uint32(ifile); // 0x00
  607.     uint32 head07 = BE_read_uint32(ifile); // 0x00
  608.  
  609.     // read filename
  610.     char name[32];
  611.     BE_read_array(ifile, &name[0], 32);
  612.  
  613.     uint32 head08 = BE_read_uint32(ifile); // 0x60
  614.     uint32 head09 = BE_read_uint32(ifile); // dx
  615.     uint32 head10 = BE_read_uint32(ifile); // dy
  616.     uint32 head11 = BE_read_uint32(ifile); // 0x20
  617.     uint32 head12 = BE_read_uint16(ifile); // 0x01
  618.     uint32 head13 = BE_read_uint16(ifile); // 0x01
  619.     uint32 head14 = BE_read_uint32(ifile); // 0x00
  620.     uint32 head15 = BE_read_uint32(ifile); // size of image data
  621.     uint32 head16 = BE_read_uint32(ifile); // 0x80
  622.  
  623.     // create DDS header
  624.     DDS_HEADER ddsh;
  625.     CreateUncompressedDDSHeader(head09, head10, 0, MASK_R, MASK_G, MASK_B, MASK_A, FALSE, &ddsh);
  626.  
  627.     // read DDS data
  628.     ifile.seekg(head02);
  629.     boost::shared_array<char> data(new char[head15]);
  630.     ifile.read(data.get(), head15);
  631.  
  632.     // save DDS data
  633.     ofstream ofile(ofname.c_str(), ios::binary);
  634.     if(!ofile) return error("Failed to create DDS file.");
  635.     ofile.write("DDS ", 4);
  636.     ofile.write((char*)&ddsh, sizeof(ddsh));
  637.     ofile.write(data.get(), head15);
  638.    }
  639.  
  640.  return true;
  641. }
  642.  
  643. bool extractor::processISM(const std::string& filename)
  644. {
  645.  // clear previous
  646.  clearISM();
  647.  
  648.  // open file
  649.  using namespace std;
  650.  ifile.open(filename.c_str(), ios::binary);
  651.  if(!ifile) return error("Could not open ISM2 file.");
  652.  
  653.  // filesize
  654.  ifile.seekg(0, ios::end);
  655.  size_t filesize = (size_t)ifile.tellg();
  656.  ifile.seekg(0, ios::beg);
  657.  
  658.  // paths
  659.  string savepath = GetPathnameFromFilename(filename);
  660.  string shrtname = GetShortFilenameWithoutExtension(filename);
  661.  
  662.  // debug file
  663.  string dfname = savepath;
  664.  dfname += shrtname;
  665.  dfname += ".txt";
  666.  if(debug) dfile.open(dfname.c_str());
  667.  
  668.  // read header
  669.  uint32 head01 = BE_read_uint32(ifile); // magic
  670.  uint32 head02 = BE_read_uint32(ifile); // ???
  671.  uint32 head03 = BE_read_uint32(ifile); // ???
  672.  uint32 head04 = BE_read_uint32(ifile); // 0x0
  673.  uint32 head05 = BE_read_uint32(ifile); // filesize
  674.  uint32 head06 = BE_read_uint32(ifile); // number of root sections
  675.  uint32 head07 = BE_read_uint32(ifile); // 0x0
  676.  uint32 head08 = BE_read_uint32(ifile); // 0x0
  677.  
  678.  // read root section information
  679.  struct ROOTSECTION { uint32 v1, v2; };
  680.  deque<ROOTSECTION> rsdata;
  681.  for(uint32 i = 0; i < head06; i++) {
  682.      ROOTSECTION rs;
  683.      rs.v1 = BE_read_uint32(ifile);
  684.      rs.v2 = BE_read_uint32(ifile);
  685.      if(debug) dfile << "section[" << i << "] = (" << rs.v1 << ", " << rs.v2 << ")" << endl;
  686.      rsdata.push_back(rs);
  687.     }
  688.  if(debug) dfile << endl;
  689.  
  690.  // process root section offsets
  691.  for(size_t i = 0; i < rsdata.size(); i++)
  692.     {
  693.      // move to section
  694.      ifile.seekg(rsdata[i].v2);
  695.      if(ifile.fail()) return error("Seek failure.");
  696.  
  697.      // read signature
  698.      uint32 signature = BE_read_uint32(ifile);
  699.      if(!processXXX(rsdata[i].v2, 0, 0)) return false;
  700.     }
  701.  
  702.  // create simple model container
  703.  SIMPLEMODELCONTAINER smc;
  704.  smc.vbuffer.flags = 0;
  705.  smc.vbuffer.elem = 0;
  706.  smc.vbuffer.name = "";
  707.  
  708.  // assign points
  709.  if(points.size()) {
  710.     smc.vbuffer.flags |= VERTEX_POSITION;
  711.     smc.vbuffer.elem = points.size();
  712.     smc.vbuffer.name = "model"; // reassign
  713.     smc.vbuffer.data.reset(new SMC_VERTEX[smc.vbuffer.elem]);
  714.     for(uint32 i = 0; i < smc.vbuffer.elem; i++) {
  715.         smc.vbuffer.data[i].vx = points[i].x;
  716.         smc.vbuffer.data[i].vy = points[i].y;
  717.         smc.vbuffer.data[i].vz = points[i].z;
  718.        }
  719.    }
  720.  
  721.  // save LWO
  722.  return SaveLWO(savepath.c_str(), shrtname.c_str(), smc);
  723. }
  724.  
  725. bool extractor::clearISM(void)
  726. {
  727.  // clear model
  728.  points.clear();
  729.  normal.clear();
  730.  uvdata.clear();
  731.  
  732.  // clear ISM data
  733.  texture_info.clear();
  734.  string_table.clear();
  735.  
  736.  // clear file handles
  737.  ifile.close();
  738.  dfile.close();
  739.  
  740.  return true;
  741. }
  742.  
  743. bool extractor::processXXX(uint32 offset, uint32 parent, uint32 caller)
  744. {
  745.  // move to offset
  746.  using namespace std;
  747.  ifile.seekg(offset);
  748.  if(ifile.fail()) return error("Seek failure.");
  749.  
  750.  // read signature
  751.  uint32 type = BE_read_uint32(ifile);
  752.  if(ifile.fail()) return error("Read failure.");
  753.  
  754.  // process signature
  755.  switch(type) {
  756.    case(0x03) : return processX03(offset, parent, caller);
  757.    case(0x04) : return processX04(offset, parent, caller);
  758.    case(0x05) : return processX05(offset, parent, caller);
  759.    case(0x0A) : return processX0A(offset, parent, caller);
  760.    case(0x0B) : return processX0B(offset, parent, caller);
  761.    case(0x0D) : return processX0D(offset, parent, caller);
  762.    case(0x0F) : return processX0F(offset, parent, caller);
  763.    case(0x21) : return processX21(offset, parent, caller);
  764.    case(0x2D) : return processX2D(offset, parent, caller);
  765.    case(0x2E) : return processX2E(offset, parent, caller);
  766.    case(0x30) : return processX30(offset, parent, caller);
  767.    case(0x31) : return processX31(offset, parent, caller);
  768.    case(0x32) : return processX32(offset, parent, caller);
  769.    case(0x34) : return processX34(offset, parent, caller);
  770.    case(0x44) : return processX44(offset, parent, caller);
  771.    case(0x45) : return processX45(offset, parent, caller);
  772.    case(0x46) : return processX46(offset, parent, caller);
  773.    case(0x4B) : return processX4B(offset, parent, caller);
  774.    case(0x4C) : return processX4C(offset, parent, caller);
  775.    case(0x4D) : return processX4D(offset, parent, caller);
  776.    case(0x50) : return processX50(offset, parent, caller);
  777.    case(0x59) : return processX59(offset, parent, caller);
  778.    case(0x5B) : return processX5B(offset, parent, caller);
  779.    case(0x5C) : return processX5C(offset, parent, caller);
  780.    case(0x61) : return processX61(offset, parent, caller);
  781.    case(0x62) : return processX62(offset, parent, caller);
  782.    case(0x63) : return processX63(offset, parent, caller);
  783.    case(0x65) : return processX65(offset, parent, caller);
  784.    case(0x6A) : return processX6A(offset, parent, caller);
  785.    case(0x6B) : return processX6B(offset, parent, caller);
  786.    case(0x6C) : return processX6C(offset, parent, caller);
  787.    case(0x6E) : return processX6E(offset, parent, caller);
  788.    default : {
  789.         stringstream ss;
  790.         ss << "Unknown section 0x" << hex << type << dec << "." << endl;
  791.         return error(ss.str().c_str());
  792.        }
  793.   }
  794.  
  795.  return true;
  796. }
  797.  
  798. bool extractor::processX03(uint32 offset, uint32 parent, uint32 caller)
  799. {
  800.  // move to offset
  801.  using namespace std;
  802.  if(debug) dfile << endl;
  803.  if(debug) dfile << "LOADING SECTION 0x03 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  804.  ifile.seekg(offset);
  805.  if(ifile.fail()) return error("Seek failure.");
  806.  
  807.  // read header
  808.  static const uint32 header_elem = 5;
  809.  uint32 header[header_elem];
  810.  BE_read_array(ifile, &header[0], header_elem);
  811.  
  812.  // debug information
  813.  if(debug) {
  814.     dfile << "HEADER" << endl;
  815.     dfile << " headtype = " << header[0] << endl;
  816.     dfile << " headsize = " << header[1] << endl;
  817.     dfile << " number of children = " << header[2] << endl;
  818.     dfile << " string table index = " << header[3] << ", " << string_table[header[3]] << endl;
  819.     dfile << " string table index = " << header[4] << ", " << string_table[header[4]] << endl;
  820.    }
  821.  
  822.  // validate
  823.  if(header[0] != 0x03) return error("Expecting SECTION 0x03.");
  824.  if(header[1] != 20) return error("Invalid SECTION 0x03 size of header.");
  825.  
  826.  // read offsets
  827.  deque<uint32> offsets;
  828.  for(uint32 i = 0; i < header[2]; i++) {
  829.      uint32 temp = BE_read_uint32(ifile);
  830.      offsets.push_back(temp);
  831.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  832.     }
  833.  
  834.  // process data at offsets
  835.  for(size_t i = 0; i < offsets.size(); i++)
  836.      if(!processXXX(offsets[i], offset, 0x03)) return false;
  837.  
  838.  return true;
  839. }
  840.  
  841. bool extractor::processX04(uint32 offset, uint32 parent, uint32 caller)
  842. {
  843.  // move to offset
  844.  using namespace std;
  845.  if(debug) dfile << endl;
  846.  if(debug) dfile << "LOADING SECTION 0x04 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  847.  ifile.seekg(offset);
  848.  if(ifile.fail()) return error("Seek failure.");
  849.  
  850.  // read header
  851.  static const uint32 header_elem = 16;
  852.  uint32 header[header_elem];
  853.  BE_read_array(ifile, &header[0], header_elem);
  854.  
  855.  // debug information
  856.  if(debug) {
  857.     dfile << "HEADER" << endl;
  858.     dfile << " headtype = " << header[0] << endl;
  859.     dfile << " headsize = " << header[1] << endl;
  860.     dfile << " number of children = " << header[2] << endl;
  861.     dfile << " string table index = " << header[3] << ", " << string_table[header[3]] << endl;
  862.     dfile << " string table index = " << header[4] << ", " << string_table[header[4]] << endl;
  863.     dfile << " unknown = " << header[ 5] << endl; // 0
  864.     dfile << " unknown = " << header[ 6] << endl; // 0
  865.     dfile << " unknown = " << header[ 7] << endl; // 0
  866.     dfile << " unknown = " << header[ 8] << endl; // 0
  867.     dfile << " unknown = " << header[ 9] << endl; // 1
  868.     dfile << " unknown = " << header[10] << endl; // 1
  869.     dfile << " unknown = " << header[11] << endl; // 0xFFFFFFFF
  870.     dfile << " unknown = " << header[12] << endl; // 0
  871.     dfile << " unknown = " << header[13] << endl; // 0 or 142
  872.     dfile << " unknown = " << header[14] << endl; // 0
  873.     dfile << " unknown = " << header[15] << endl; // 0
  874.    }
  875.  
  876.  // validate
  877.  if(header[0] != 0x04) return error("Expecting SECTION 0x04.");
  878.  if(header[1] != 64) return error("Invalid SECTION 0x04 size of header.");
  879.  
  880.  // read offsets
  881.  deque<uint32> offsets;
  882.  for(uint32 i = 0; i < header[2]; i++) {
  883.      uint32 temp = BE_read_uint32(ifile);
  884.      offsets.push_back(temp);
  885.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  886.     }
  887.  
  888.  // process data at offsets
  889.  for(size_t i = 0; i < offsets.size(); i++)
  890.      if(!processXXX(offsets[i], offset, 0x04)) return false;
  891.  
  892.  return true;
  893. }
  894.  
  895. bool extractor::processX05(uint32 offset, uint32 parent, uint32 caller)
  896. {
  897.  // move to offset
  898.  using namespace std;
  899.  if(debug) dfile << endl;
  900.  if(debug) dfile << "LOADING SECTION 0x05 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  901.  ifile.seekg(offset);
  902.  if(ifile.fail()) return error("Seek failure.");
  903.  
  904.  // read header
  905.  static const uint32 header_elem = 16;
  906.  uint32 header[header_elem];
  907.  BE_read_array(ifile, &header[0], header_elem);
  908.  
  909.  // debug information
  910.  if(debug) {
  911.     dfile << "HEADER" << endl;
  912.     dfile << " headtype = " << header[0] << endl;
  913.     dfile << " headsize = " << header[1] << endl;
  914.     dfile << " number of children = " << header[2] << endl;
  915.     dfile << " string table index = " << header[3] << ", " << string_table[header[3]] << endl;
  916.     dfile << " string table index = " << header[4] << ", " << string_table[header[4]] << endl;
  917.     dfile << " string table index = " << header[5] << ", " << string_table[header[5]] << endl;
  918.     dfile << " unknown = " << header[6] << endl; // 0
  919.     dfile << " parent section 0x05 offset = 0x" << hex << header[7] << dec << endl;
  920.     dfile << " number of children = " << header[8] << endl;
  921.     dfile << " unknown = " << header[ 9] << endl; // 1
  922.     dfile << " unknown = " << header[10] << endl; // 0
  923.     dfile << " bone index = " << header[11] << endl;
  924.     dfile << " unknown = " << header[12] << endl; // 0
  925.     dfile << " index into section 0x03 offset array = " << header[13] << endl;
  926.     dfile << " unknown = " << header[14] << endl; // 0
  927.     dfile << " unknown = " << header[15] << endl; // 0
  928.    }
  929.  
  930.  // validate
  931.  if(header[0] != 0x05) return error("Expecting SECTION 0x05.");
  932.  if(header[1] != 64) return error("Invalid SECTION 0x05 size of header.");
  933.  
  934.  // read offsets
  935.  deque<uint32> offsets;
  936.  for(uint32 i = 0; i < header[2]; i++) {
  937.      uint32 temp = BE_read_uint32(ifile);
  938.      offsets.push_back(temp);
  939.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  940.     }
  941.  
  942.  // process data at offsets
  943.  for(size_t i = 0; i < offsets.size(); i++)
  944.      if(!processXXX(offsets[i], offset, 0x05)) return false;
  945.  
  946.  return true;
  947. }
  948.  
  949. bool extractor::processX0A(uint32 offset, uint32 parent, uint32 caller)
  950. {
  951.  // move to offset
  952.  using namespace std;
  953.  if(debug) dfile << endl;
  954.  if(debug) dfile << "LOADING SECTION 0x0A at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  955.  ifile.seekg(offset);
  956.  if(ifile.fail()) return error("Seek failure.");
  957.  
  958.  // read header
  959.  static const uint32 header_elem = 8;
  960.  uint32 header[header_elem];
  961.  BE_read_array(ifile, &header[0], header_elem);
  962.  
  963.  // debug information
  964.  if(debug) {
  965.     dfile << "HEADER" << endl;
  966.     dfile << " headtype = " << header[0] << endl;
  967.     dfile << " headsize = " << header[1] << endl;
  968.     dfile << " number of children = " << header[2] << endl;
  969.     dfile << " string table index = " << header[3] << ", " << string_table[header[3]] << endl;
  970.     dfile << " string table index = " << header[4] << ", " << string_table[header[4]] << endl;
  971.     dfile << " unknown = " << header[5] << endl;
  972.     dfile << " unknown = " << header[6] << endl;
  973.     dfile << " unknown = " << header[7] << endl;
  974.    }
  975.  
  976.  // validate
  977.  if(header[0] != 0x0A) return error("Expecting SECTION 0x0A.");
  978.  if(header[1] != 32) return error("Invalid SECTION 0x0A size of header.");
  979.  
  980.  // read offsets
  981.  deque<uint32> offsets;
  982.  for(uint32 i = 0; i < header[2]; i++) {
  983.      uint32 temp = BE_read_uint32(ifile);
  984.      offsets.push_back(temp);
  985.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  986.     }
  987.  
  988.  // process data at offsets
  989.  for(size_t i = 0; i < offsets.size(); i++)
  990.      if(!processXXX(offsets[i], offset, 0x0A)) return false;
  991.  
  992.  return true;
  993. }
  994.  
  995. bool extractor::processX0B(uint32 offset, uint32 parent, uint32 caller)
  996. {
  997.  // move to offset
  998.  using namespace std;
  999.  if(debug) dfile << endl;
  1000.  if(debug) dfile << "LOADING SECTION 0x0B at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1001.  ifile.seekg(offset);
  1002.  if(ifile.fail()) return error("Seek failure.");
  1003.  
  1004.  // read header
  1005.  static const uint32 header_elem = 3;
  1006.  uint32 header[header_elem];
  1007.  BE_read_array(ifile, &header[0], header_elem);
  1008.  
  1009.  // debug information
  1010.  if(debug) {
  1011.     dfile << "HEADER" << endl;
  1012.     dfile << " headtype = " << header[0] << endl;
  1013.     dfile << " headsize = " << header[1] << endl;
  1014.     dfile << " number of children = " << header[2] << endl;
  1015.    }
  1016.  
  1017.  // validate
  1018.  if(header[0] != 0x0B) return error("Expecting SECTION 0x0B.");
  1019.  if(header[1] != 12) return error("Invalid SECTION 0x0B size of header.");
  1020.  
  1021.  if(header[2] == 0) return error("Section 0x0B must have at least one child.");
  1022.  if(header[2] > 1) return error("Section 0x0B has multiple children.");
  1023.  
  1024.  // read offsets
  1025.  deque<uint32> offsets;
  1026.  for(uint32 i = 0; i < header[2]; i++) {
  1027.      uint32 temp = BE_read_uint32(ifile);
  1028.      offsets.push_back(temp);
  1029.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  1030.     }
  1031.  
  1032.  // process data at offsets
  1033.  for(size_t i = 0; i < offsets.size(); i++)
  1034.      if(!processXXX(offsets[i], offset, 0x0B)) return false;
  1035.  
  1036.  return true;
  1037. }
  1038.  
  1039. bool extractor::processX0D(uint32 offset, uint32 parent, uint32 caller)
  1040. {
  1041.  // move to offset
  1042.  using namespace std;
  1043.  if(debug) dfile << endl;
  1044.  if(debug) dfile << "LOADING SECTION 0x0D at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1045.  ifile.seekg(offset);
  1046.  if(ifile.fail()) return error("Seek failure.");
  1047.  
  1048.  // read header
  1049.  static const uint32 header_elem = 7;
  1050.  uint32 header[header_elem];
  1051.  BE_read_array(ifile, &header[0], header_elem);
  1052.  
  1053.  // debug information
  1054.  if(debug) {
  1055.     dfile << "HEADER" << endl;
  1056.     dfile << " headtype = " << header[0] << endl;
  1057.     dfile << " headsize = " << header[1] << endl;
  1058.     dfile << " number of children = " << header[2] << endl;
  1059.     dfile << " string table index = " << header[3] << ", " << string_table[header[3]] << endl;
  1060.     dfile << " string table index = " << header[4] << ", " << string_table[header[4]] << endl;
  1061.     dfile << " string table index = " << header[5] << ", " << string_table[header[5]] << endl;
  1062.     dfile << " string table index = " << header[6] << ", " << string_table[header[6]] << endl;
  1063.    }
  1064.  
  1065.  // validate
  1066.  if(header[0] != 0x0D) return error("Expecting SECTION 0x0D.");
  1067.  if(header[1] != 28) return error("Invalid SECTION 0x0D size of header.");
  1068.  
  1069.  // read offsets
  1070.  deque<uint32> offsets;
  1071.  for(uint32 i = 0; i < header[2]; i++) {
  1072.      uint32 temp = BE_read_uint32(ifile);
  1073.      offsets.push_back(temp);
  1074.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  1075.     }
  1076.  
  1077.  // process data at offsets
  1078.  for(size_t i = 0; i < offsets.size(); i++)
  1079.      if(!processXXX(offsets[i], offset, 0x0D)) return false;
  1080.  
  1081.  return true;
  1082. }
  1083.  
  1084. bool extractor::processX0F(uint32 offset, uint32 parent, uint32 caller)
  1085. {
  1086.  // move to offset
  1087.  using namespace std;
  1088.  if(debug) dfile << endl;
  1089.  if(debug) dfile << "LOADING SECTION 0x0F at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1090.  ifile.seekg(offset);
  1091.  if(ifile.fail()) return error("Seek failure.");
  1092.  
  1093.  return true;
  1094. }
  1095.  
  1096. bool extractor::processX21(uint32 offset, uint32 parent, uint32 caller)
  1097. {
  1098.  // move to offset
  1099.  using namespace std;
  1100.  if(debug) dfile << endl;
  1101.  if(debug) dfile << "LOADING SECTION 0x21 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1102.  ifile.seekg(offset);
  1103.  if(ifile.fail()) return error("Seek failure.");
  1104.  
  1105.  // read header
  1106.  static const uint32 header_elem = 3;
  1107.  uint32 header[header_elem];
  1108.  BE_read_array(ifile, &header[0], header_elem);
  1109.  
  1110.  // debug information
  1111.  if(debug) {
  1112.     dfile << "HEADER" << endl;
  1113.     dfile << " headtype = " << header[0] << endl;
  1114.     dfile << " headsize = " << header[1] << endl;
  1115.     dfile << " number of children = " << header[2] << endl;
  1116.    }
  1117.  
  1118.  // validate
  1119.  if(header[0] != 33) return error("Expecting SECTION 0x21.");
  1120.  if(header[1] != 12) return error("Invalid SECTION 0x21 size of header.");
  1121.  
  1122.  // read offsets
  1123.  deque<uint32> offsets;
  1124.  for(uint32 i = 0; i < header[2]; i++) {
  1125.      uint32 temp = BE_read_uint32(ifile);
  1126.      offsets.push_back(temp);
  1127.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  1128.     }
  1129.  
  1130.  // process data at offsets
  1131.  for(size_t i = 0; i < offsets.size(); i++)
  1132.     {
  1133.      // move to table data
  1134.      ifile.seekg(offsets[i], ios::beg);
  1135.      if(ifile.fail()) return error("Seek failure.");
  1136.  
  1137.      // read string
  1138.      char item[1024];
  1139.      read_string(ifile, &item[0], 1024);
  1140.  
  1141.      // add string
  1142.      string_table.push_back(item);
  1143.      if(debug) dfile << " string_table[" << i << "] = " << string_table[i] << endl;
  1144.     }
  1145.  
  1146.  return true;
  1147. }
  1148.  
  1149. bool extractor::processX2D(uint32 offset, uint32 parent, uint32 caller)
  1150. {
  1151.  // move to offset
  1152.  using namespace std;
  1153.  if(debug) dfile << endl;
  1154.  if(debug) dfile << "LOADING SECTION 0x2D at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1155.  ifile.seekg(offset);
  1156.  if(ifile.fail()) return error("Seek failure.");
  1157.  
  1158.  // read header
  1159.  static const uint32 header_elem = 8;
  1160.  uint32 header[header_elem];
  1161.  BE_read_array(ifile, &header[0], header_elem);
  1162.  
  1163.  // debug information
  1164.  if(debug) {
  1165.     dfile << "HEADER" << endl;
  1166.     dfile << " headtype = " << header[0] << endl;
  1167.     dfile << " string table index = " << header[1] << ", " << string_table[header[1]] << endl;
  1168.     dfile << " string table index = " << header[2] << ", " << string_table[header[2]] << endl;
  1169.     dfile << " string table index = " << header[3] << ", " << string_table[header[3]] << endl;
  1170.     dfile << " string table index = " << header[4] << ", " << string_table[header[4]] << endl;
  1171.     dfile << " string table index = " << header[5] << ", " << string_table[header[5]] << endl;
  1172.     dfile << " string table index = " << header[6] << ", " << string_table[header[6]] << endl;
  1173.     dfile << " string table index = " << header[7] << ", " << string_table[header[7]] << endl;
  1174.    }
  1175.  
  1176.  // save data
  1177.  TEXTUREINFO info;
  1178.  info.data1 = header[0];
  1179.  info.data2 = header[1];
  1180.  info.data3 = header[2];
  1181.  info.data4 = header[3];
  1182.  info.data5 = header[4];
  1183.  info.data6 = header[5];
  1184.  info.data7 = header[6];
  1185.  info.data8 = header[7];
  1186.  texture_info.push_back(info);
  1187.  
  1188.  return true;
  1189. }
  1190.  
  1191. bool extractor::processX2E(uint32 offset, uint32 parent, uint32 caller)
  1192. {
  1193.  // move to offset
  1194.  using namespace std;
  1195.  if(debug) dfile << endl;
  1196.  if(debug) dfile << "LOADING SECTION 0x2E at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1197.  ifile.seekg(offset);
  1198.  if(ifile.fail()) return error("Seek failure.");
  1199.  
  1200.  // read header
  1201.  static const uint32 header_elem = 3;
  1202.  uint32 header[header_elem];
  1203.  BE_read_array(ifile, &header[0], header_elem);
  1204.  
  1205.  // debug information
  1206.  if(debug) {
  1207.     dfile << "HEADER" << endl;
  1208.     dfile << " headtype = " << header[0] << endl;
  1209.     dfile << " headsize = " << header[1] << endl;
  1210.     dfile << " number of children = " << header[2] << endl;
  1211.    }
  1212.  
  1213.  // validate
  1214.  if(header[0] != 0x2E) return error("Expecting SECTION 0x2E.");
  1215.  if(header[1] != 12) return error("Invalid SECTION 0x2E size of header.");
  1216.  
  1217.  // read offsets
  1218.  deque<uint32> offsets;
  1219.  for(uint32 i = 0; i < header[2]; i++) {
  1220.      uint32 temp = BE_read_uint32(ifile);
  1221.      offsets.push_back(temp);
  1222.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  1223.     }
  1224.  
  1225.  // process data at offsets
  1226.  for(size_t i = 0; i < offsets.size(); i++)
  1227.      if(!processXXX(offsets[i], offset, 0x2E)) return false;
  1228.  
  1229.  return true;
  1230. }
  1231.  
  1232. bool extractor::processX30(uint32 offset, uint32 parent, uint32 caller)
  1233. {
  1234.  // move to offset
  1235.  using namespace std;
  1236.  if(debug) dfile << endl;
  1237.  if(debug) dfile << "LOADING SECTION 0x30 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1238.  ifile.seekg(offset);
  1239.  if(ifile.fail()) return error("Seek failure.");
  1240.  
  1241.  // read header
  1242.  static const uint32 header_elem = 21;
  1243.  uint32 header[header_elem];
  1244.  BE_read_array(ifile, &header[0], header_elem);
  1245.  
  1246.  // debug information
  1247.  if(debug) {
  1248.     dfile << "HEADER" << endl;
  1249.     dfile << " headtype = " << header[0] << endl;
  1250.     dfile << " headsize = " << header[1] << endl;
  1251.     dfile << " number of children = " << header[2] << endl;
  1252.     dfile << " unknown = " << header[3] << ", " << string_table[header[3]] << endl;
  1253.     dfile << " unknown = " << header[4] << ", " << string_table[header[4]] << endl;
  1254.     dfile << " matrix[0x0] = " << interpret_as_real32(header[5]) << endl;
  1255.     dfile << " matrix[0x1] = " << interpret_as_real32(header[6]) << endl;
  1256.     dfile << " matrix[0x2] = " << interpret_as_real32(header[7]) << endl;
  1257.     dfile << " matrix[0x3] = " << interpret_as_real32(header[8]) << endl;
  1258.     dfile << " matrix[0x4] = " << interpret_as_real32(header[9]) << endl;
  1259.     dfile << " matrix[0x5] = " << interpret_as_real32(header[10]) << endl;
  1260.     dfile << " matrix[0x6] = " << interpret_as_real32(header[11]) << endl;
  1261.     dfile << " matrix[0x7] = " << interpret_as_real32(header[12]) << endl;
  1262.     dfile << " matrix[0x8] = " << interpret_as_real32(header[13]) << endl;
  1263.     dfile << " matrix[0x9] = " << interpret_as_real32(header[14]) << endl;
  1264.     dfile << " matrix[0xA] = " << interpret_as_real32(header[15]) << endl;
  1265.     dfile << " matrix[0xB] = " << interpret_as_real32(header[16]) << endl;
  1266.     dfile << " matrix[0xC] = " << interpret_as_real32(header[17]) << endl;
  1267.     dfile << " matrix[0xD] = " << interpret_as_real32(header[18]) << endl;
  1268.     dfile << " matrix[0xE] = " << interpret_as_real32(header[19]) << endl;
  1269.     dfile << " matrix[0xF] = " << interpret_as_real32(header[20]) << endl;
  1270.    }
  1271.  
  1272.  // validate
  1273.  if(header[0] != 0x30) return error("Expecting SECTION 0x30.");
  1274.  if(header[1] != 84) return error("Invalid SECTION 0x30 size of header.");
  1275.  
  1276.  // read offsets
  1277.  deque<uint32> offsets;
  1278.  for(uint32 i = 0; i < header[2]; i++) {
  1279.      uint32 temp = BE_read_uint32(ifile);
  1280.      offsets.push_back(temp);
  1281.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  1282.     }
  1283.  
  1284.  // process data at offsets
  1285.  for(size_t i = 0; i < offsets.size(); i++)
  1286.      if(!processXXX(offsets[i], offset, 0x30)) return false;
  1287.  
  1288.  return true;
  1289. }
  1290.  
  1291. bool extractor::processX31(uint32 offset, uint32 parent, uint32 caller)
  1292. {
  1293.  // move to offset
  1294.  using namespace std;
  1295.  if(debug) dfile << endl;
  1296.  if(debug) dfile << "LOADING SECTION 0x31 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1297.  ifile.seekg(offset);
  1298.  if(ifile.fail()) return error("Seek failure.");
  1299.  
  1300.  // read header
  1301.  static const uint32 header_elem = 5;
  1302.  uint32 header[header_elem];
  1303.  BE_read_array(ifile, &header[0], header_elem);
  1304.  
  1305.  // debug information
  1306.  if(debug) {
  1307.     dfile << "HEADER" << endl;
  1308.     dfile << " headtype = " << header[0] << endl;
  1309.     dfile << " headsize = " << header[1] << endl;
  1310.     dfile << " number of children = " << header[2] << endl;
  1311.     dfile << " string table index = " << header[3] << ", " << string_table[header[3]] << endl;
  1312.     dfile << " string table index = " << header[4] << ", " << string_table[header[4]] << endl;
  1313.    }
  1314.  
  1315.  // validate
  1316.  if(header[0] != 0x31) return error("Expecting SECTION 0x31.");
  1317.  if(header[1] != 20) return error("Invalid SECTION 0x31 size of header.");
  1318.  
  1319.  // read offsets
  1320.  deque<uint32> offsets;
  1321.  for(uint32 i = 0; i < header[2]; i++) {
  1322.      uint32 temp = BE_read_uint32(ifile);
  1323.      offsets.push_back(temp);
  1324.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  1325.     }
  1326.  
  1327.  // process data at offsets
  1328.  for(size_t i = 0; i < offsets.size(); i++)
  1329.      if(!processXXX(offsets[i], offset, 0x31)) return false;
  1330.  
  1331.  return true;
  1332. }
  1333.  
  1334. bool extractor::processX32(uint32 offset, uint32 parent, uint32 caller)
  1335. {
  1336.  // move to offset
  1337.  using namespace std;
  1338.  if(debug) dfile << endl;
  1339.  if(debug) dfile << "LOADING SECTION 0x32 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1340.  ifile.seekg(offset);
  1341.  if(ifile.fail()) return error("Seek failure.");
  1342.  
  1343.  // read header
  1344.  static const uint32 header_elem = 5;
  1345.  uint32 header[header_elem];
  1346.  BE_read_array(ifile, &header[0], header_elem);
  1347.  
  1348.  // debug information
  1349.  if(debug) {
  1350.     dfile << "HEADER" << endl;
  1351.     dfile << " headtype = " << header[0] << endl;
  1352.     dfile << " headsize = " << header[1] << endl;
  1353.     dfile << " number of children = " << header[2] << endl;
  1354.     dfile << " unknown = " << header[3] << endl; // 0
  1355.     dfile << " unknown = " << header[4] << endl; // 0
  1356.    }
  1357.  
  1358.  // validate
  1359.  if(header[0] != 0x32) return error("Expecting SECTION 0x32.");
  1360.  if(header[1] != 20) return error("Invalid SECTION 0x32 size of header.");
  1361.  
  1362.  // read offsets
  1363.  deque<uint32> offsets;
  1364.  for(uint32 i = 0; i < header[2]; i++) {
  1365.      uint32 temp = BE_read_uint32(ifile);
  1366.      offsets.push_back(temp);
  1367.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  1368.     }
  1369.  
  1370.  // process data at offsets
  1371.  for(size_t i = 0; i < offsets.size(); i++)
  1372.      if(!processXXX(offsets[i], offset, 0x32)) return false;
  1373.  
  1374.  return true;
  1375. }
  1376.  
  1377. bool extractor::processX34(uint32 offset, uint32 parent, uint32 caller)
  1378. {
  1379.  // move to offset
  1380.  using namespace std;
  1381.  if(debug) dfile << endl;
  1382.  if(debug) dfile << "LOADING SECTION 0x34 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1383.  ifile.seekg(offset);
  1384.  if(ifile.fail()) return error("Seek failure.");
  1385.  
  1386.  if(debug) dfile << endl;
  1387.  return true;
  1388. }
  1389.  
  1390. bool extractor::processX44(uint32 offset, uint32 parent, uint32 caller)
  1391. {
  1392.  // move to offset
  1393.  using namespace std;
  1394.  if(debug) dfile << endl;
  1395.  if(debug) dfile << "LOADING SECTION 0x44 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1396.  ifile.seekg(offset);
  1397.  if(ifile.fail()) return error("Seek failure.");
  1398.  
  1399.  // read header
  1400.  static const uint32 header_elem = 8;
  1401.  uint32 header[header_elem];
  1402.  BE_read_array(ifile, &header[0], header_elem);
  1403.  
  1404.  // debug information
  1405.  if(debug) {
  1406.     dfile << "HEADER" << endl;
  1407.     dfile << " headtype = " << header[0] << endl;
  1408.     dfile << " headsize = " << header[1] << endl;
  1409.     dfile << " number of items = " << header[2] << endl;
  1410.     dfile << " unknown = " << header[3] << endl; // 0x0
  1411.     dfile << " unknown = " << header[4] << endl; // type of data 5 (shorts?) or 18 (floats?), 12 (matrix?)
  1412.     dfile << " unknown = " << header[5] << endl; // group size (typically 1, 5, 13, or 16)
  1413.     dfile << " unknown = " << header[6] << endl; // 0x0
  1414.     dfile << " unknown = " << header[7] << endl; // 0x0
  1415.    }
  1416.  
  1417.  // validate
  1418.  if(header[0] != 0x44) return error("Expecting SECTION 0x44.");
  1419.  if(header[1] != 32) return error("Invalid SECTION 0x44 size of header.");
  1420.  
  1421.  // TODO: read data
  1422.  // could be matrix, single values
  1423.  
  1424.  // read bone string table data
  1425.  if(header[4] == 5 && header[5] == 1)
  1426.    {
  1427.     for(size_t i = 0; i < header[2]; i++) {
  1428.         uint16 index = BE_read_uint16(ifile);
  1429.         if(debug) dfile << " " << index << ", " << string_table[index] << endl;
  1430.        }
  1431.    }
  1432.  // read bone matrices
  1433.  else if(header[4] == 12 && header[5] == 16)
  1434.    {
  1435.     for(size_t i = 0; i < header[2]/16; i++) {
  1436.         boost::shared_array<float> matrix(new float[16]);
  1437.         BE_read_array(ifile, matrix.get(), 16);
  1438.         if(debug) dfile << " ";
  1439.         if(debug) for(size_t j = 0; j < 16; j++) dfile << matrix[j] << "  ";
  1440.         if(debug) dfile << endl;
  1441.        }
  1442.    }
  1443.  // ???
  1444.  else
  1445.     return error("SOME OTHER TYPE OF SKINNING OPTIONS.");
  1446.  
  1447.  return true;
  1448. }
  1449.  
  1450. bool extractor::processX45(uint32 offset, uint32 parent, uint32 caller)
  1451. {
  1452.  // move to offset
  1453.  using namespace std;
  1454.  if(debug) dfile << endl;
  1455.  if(debug) dfile << "LOADING SECTION 0x45 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1456.  ifile.seekg(offset);
  1457.  if(ifile.fail()) return error("Seek failure.");
  1458.  
  1459.  // read header
  1460.  static const uint32 header_elem = 5;
  1461.  uint32 header[header_elem];
  1462.  BE_read_array(ifile, &header[0], header_elem);
  1463.  
  1464.  // debug information
  1465.  if(debug) {
  1466.     dfile << "HEADER" << endl;
  1467.     dfile << " headtype = " << header[0] << endl;
  1468.     dfile << " headsize = " << header[1] << endl;
  1469.     dfile << " number of indices = " << header[2] << endl;
  1470.     dfile << " unknown = " << header[3] << endl; // 5, 7
  1471.     dfile << " unknown = " << header[4] << endl; // 0
  1472.    }
  1473.  
  1474.  // validate
  1475.  if(header[0] != 0x45) return error("Expecting SECTION 0x45.");
  1476.  if(header[1] != 20) return error("Invalid SECTION 0x45 size of header.");
  1477.  
  1478.  // indices must be divisible by 3
  1479.  if(header[2] % 3) return error("The number of face indices must be divisible by three.");
  1480.  size_t n_triangles = header[2]/3; 
  1481.  
  1482.  // read triangles
  1483.  if(debug) dfile << "DATA" << endl;
  1484.  if(header[3] == 5) {
  1485.     for(size_t i = 0; i < n_triangles; i++) {
  1486.         uint16 a = BE_read_uint16(ifile);
  1487.         uint16 b = BE_read_uint16(ifile);
  1488.         uint16 c = BE_read_uint16(ifile);
  1489.         if(dfile) dfile << "face[" << i << "] = (" << a << ", " << b << ", " << c << ")" << endl;
  1490.        }
  1491.    }
  1492.  else if(header[3] == 7) {
  1493.     for(size_t i = 0; i < n_triangles; i++) {
  1494.         uint16 a = BE_read_uint32(ifile);
  1495.         uint16 b = BE_read_uint32(ifile);
  1496.         uint16 c = BE_read_uint32(ifile);
  1497.         if(dfile) dfile << "face[" << i << "] = (" << a << ", " << b << ", " << c << ")" << endl;
  1498.        }
  1499.    }
  1500.  else
  1501.     return error("Unknown index buffer format.");
  1502.  
  1503.  return true;
  1504. }
  1505.  
  1506. bool extractor::processX46(uint32 offset, uint32 parent, uint32 caller)
  1507. {
  1508.  // move to offset
  1509.  using namespace std;
  1510.  if(debug) dfile << endl;
  1511.  if(debug) dfile << "LOADING SECTION 0x46 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1512.  ifile.seekg(offset);
  1513.  if(ifile.fail()) return error("Seek failure.");
  1514.  
  1515.  // read header
  1516.  static const uint32 header_elem = 7;
  1517.  uint32 header[header_elem];
  1518.  BE_read_array(ifile, &header[0], header_elem);
  1519.  
  1520.  // debug information
  1521.  if(debug) {
  1522.     dfile << "HEADER" << endl;
  1523.     dfile << " headtype = " << header[0] << endl;
  1524.     dfile << " headsize = " << header[1] << endl;
  1525.     dfile << " number of children = " << header[2] << endl;
  1526.     dfile << " unknown = " << header[3] << endl; // 44, 54, 74 string table?
  1527.     dfile << " unknown = " << header[4] << endl; // 0?
  1528.     dfile << " unknown = " << header[5] << endl; // 4?
  1529.     dfile << " number of triangles = " << header[6] << endl;
  1530.    }
  1531.  
  1532.  // validate
  1533.  if(header[0] != 0x46) return error("Expecting SECTION 0x46.");
  1534.  if(header[1] != 28) return error("Invalid SECTION 0x46 size of header.");
  1535.  
  1536.  // read offsets
  1537.  deque<uint32> offsets;
  1538.  for(uint32 i = 0; i < header[2]; i++) {
  1539.      uint32 temp = BE_read_uint32(ifile);
  1540.      offsets.push_back(temp);
  1541.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  1542.     }
  1543.  
  1544.  // process data at offsets
  1545.  for(size_t i = 0; i < offsets.size(); i++)
  1546.      if(!processXXX(offsets[i], offset, 0x46)) return false;
  1547.  
  1548.  return true;
  1549. }
  1550.  
  1551. bool extractor::processX4B(uint32 offset, uint32 parent, uint32 caller)
  1552. {
  1553.  // move to offset
  1554.  using namespace std;
  1555.  if(debug) dfile << endl;
  1556.  if(debug) dfile << "LOADING SECTION 0x4B at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1557.  ifile.seekg(offset);
  1558.  if(ifile.fail()) return error("Seek failure.");
  1559.  
  1560.  // read header
  1561.  static const uint32 header_elem = 6;
  1562.  uint32 header[header_elem];
  1563.  BE_read_array(ifile, &header[0], header_elem);
  1564.  
  1565.  // debug information
  1566.  if(debug) {
  1567.     dfile << "HEADER" << endl;
  1568.     dfile << " headtype = " << header[0] << endl;
  1569.     dfile << " headsize = " << header[1] << endl;
  1570.     dfile << " number of children = " << header[2] << endl;
  1571.     dfile << " string table index = " << header[3] << ", " << string_table[header[3]] << endl;
  1572.     dfile << " string table index = " << header[4] << ", " << string_table[header[4]] << endl;
  1573.     dfile << " unknown = " << header[5] << endl;
  1574.    }
  1575.  
  1576.  // validate
  1577.  if(header[0] != 0x4B) return error("Expecting SECTION 0x4B.");
  1578.  if(header[1] != 24) return error("Invalid SECTION 0x4B size of header.");
  1579.  
  1580.  // read offsets
  1581.  deque<uint32> offsets;
  1582.  for(uint32 i = 0; i < header[2]; i++) {
  1583.      uint32 temp = BE_read_uint32(ifile);
  1584.      offsets.push_back(temp);
  1585.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  1586.     }
  1587.  
  1588.  // process data at offsets
  1589.  for(size_t i = 0; i < offsets.size(); i++)
  1590.     {
  1591.      // move to offset
  1592.      ifile.seekg(offsets[i]);
  1593.      if(ifile.fail()) return error("Seek failure.");
  1594.  
  1595.      // read data
  1596.      static const uint32 elem = 7;
  1597.      uint32 data[elem];
  1598.      BE_read_array(ifile, &data[0], elem);
  1599.  
  1600.      // debug information
  1601.      if(debug) {
  1602.         dfile << "DATA" << endl;
  1603.         dfile << " unknown = " << data[0] << endl; // 0x0
  1604.         dfile << " unknown = " << data[1] << endl; // 0xC
  1605.         dfile << " unknown = " << data[2] << endl; // 0x1
  1606.         dfile << " string table index = " << data[3] << ", " << string_table[data[3]] << endl; // TEX0
  1607.         dfile << " string table index = " << data[4] << ", " << string_table[data[4]] << endl; // TEXCOORD
  1608.         dfile << " unknown = " << data[5] << endl; // 0x0
  1609.         dfile << " unknown = " << data[6] << endl; // 0x0
  1610.        }
  1611.     }
  1612.  
  1613.  return true;
  1614. }
  1615.  
  1616. bool extractor::processX4C(uint32 offset, uint32 parent, uint32 caller)
  1617. {
  1618.  // move to offset
  1619.  using namespace std;
  1620.  if(debug) dfile << endl;
  1621.  if(debug) dfile << "LOADING SECTION 0x4C at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1622.  ifile.seekg(offset);
  1623.  if(ifile.fail()) return error("Seek failure.");
  1624.  
  1625.  // read header
  1626.  static const uint32 header_elem = 6;
  1627.  uint32 header[header_elem];
  1628.  BE_read_array(ifile, &header[0], header_elem);
  1629.  
  1630.  // debug information
  1631.  if(debug) {
  1632.     dfile << "HEADER" << endl;
  1633.     dfile << " headtype = " << header[0] << endl;
  1634.     dfile << " headsize = " << header[1] << endl;
  1635.     dfile << " number of children = " << header[2] << endl;
  1636.     dfile << " string table index = " << header[3] << ", " << string_table[header[3]] << endl;
  1637.     dfile << " unknown = " << header[4] << endl;
  1638.     dfile << " string table index = " << header[5] << ", " << string_table[header[5]] << endl;
  1639.    }
  1640.  
  1641.  // validate
  1642.  if(header[0] != 0x4C) return error("Expecting SECTION 0x4C.");
  1643.  if(header[1] != 24) return error("Invalid SECTION 0x4C size of header.");
  1644.  
  1645.  // read offsets
  1646.  deque<uint32> offsets;
  1647.  for(uint32 i = 0; i < header[2]; i++) {
  1648.      uint32 temp = BE_read_uint32(ifile);
  1649.      offsets.push_back(temp);
  1650.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  1651.     }
  1652.  
  1653.  // process data at offsets
  1654.  for(size_t i = 0; i < offsets.size(); i++)
  1655.      if(!processXXX(offsets[i], offset, 0x4C)) return false;
  1656.  
  1657.  return true;
  1658. }
  1659.  
  1660. bool extractor::processX4D(uint32 offset, uint32 parent, uint32 caller)
  1661. {
  1662.  // move to offset
  1663.  using namespace std;
  1664.  if(debug) dfile << endl;
  1665.  if(debug) dfile << "LOADING SECTION 0x4D at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1666.  ifile.seekg(offset);
  1667.  if(ifile.fail()) return error("Seek failure.");
  1668.  
  1669.  // read header
  1670.  static const uint32 header_elem = 5;
  1671.  uint32 header[header_elem];
  1672.  BE_read_array(ifile, &header[0], header_elem);
  1673.  
  1674.  // debug information
  1675.  if(debug) {
  1676.     dfile << "HEADER" << endl;
  1677.     dfile << " headtype = " << header[0] << endl;
  1678.     dfile << " headsize = " << header[1] << endl;
  1679.     dfile << " number of children = " << header[2] << endl;
  1680.     dfile << " unknown = " << header[3] << endl;
  1681.     dfile << " unknown = " << header[4] << endl;
  1682.    }
  1683.  
  1684.  // validate
  1685.  if(header[0] != 0x4D) return error("Expecting SECTION 0x4D.");
  1686.  if(header[1] != 20) return error("Invalid SECTION 0x4D size of header.");
  1687.  
  1688.  // read offsets
  1689.  deque<uint32> offsets;
  1690.  for(uint32 i = 0; i < header[2]; i++) {
  1691.      uint32 temp = BE_read_uint32(ifile);
  1692.      offsets.push_back(temp);
  1693.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  1694.     }
  1695.  
  1696.  // process data at offsets
  1697.  for(size_t i = 0; i < offsets.size(); i++)
  1698.      if(!processXXX(offsets[i], offset, 0x4D)) return false;
  1699.  
  1700.  return true;
  1701. }
  1702.  
  1703. bool extractor::processX50(uint32 offset, uint32 parent, uint32 caller)
  1704. {
  1705.  // move to offset
  1706.  using namespace std;
  1707.  if(debug) dfile << endl;
  1708.  if(debug) dfile << "LOADING SECTION 0x50 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1709.  ifile.seekg(offset);
  1710.  if(ifile.fail()) return error("Seek failure.");
  1711.  
  1712.  cout << "PROCESS #0x50" << endl;
  1713.  
  1714.  // read header
  1715.  static const uint32 header_elem = 8;
  1716.  uint32 header[header_elem];
  1717.  BE_read_array(ifile, &header[0], header_elem);
  1718.  
  1719.  // debug information
  1720.  if(debug) {
  1721.     dfile << "HEADER" << endl;
  1722.     dfile << " headtype = " << header[0] << endl;
  1723.     dfile << " headsize = " << header[1] << endl;
  1724.     dfile << " number of children = " << header[2] << endl;
  1725.     dfile << " string table index = " << header[3] << ", " << string_table[header[3]] << endl;
  1726.     dfile << " unknown = " << header[4] << endl;
  1727.     dfile << " unknown = " << header[5] << endl;
  1728.     dfile << " unknown = " << header[6] << endl;
  1729.     dfile << " unknown = " << header[7] << endl;
  1730.    }
  1731.  
  1732.  // validate
  1733.  if(header[0] != 0x50) return error("Expecting SECTION 0x50.");
  1734.  if(header[1] != 32) return error("Invalid SECTION 0x50 size of header.");
  1735.  
  1736.  // read offsets
  1737.  deque<uint32> offsets;
  1738.  for(uint32 i = 0; i < header[2]; i++) {
  1739.      uint32 temp = BE_read_uint32(ifile);
  1740.      offsets.push_back(temp);
  1741.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  1742.     }
  1743.  
  1744.  // process data at offsets
  1745.  for(size_t i = 0; i < offsets.size(); i++)
  1746.      if(!processXXX(offsets[i], offset, 0x50)) return false;
  1747.  
  1748.  return true;
  1749. }
  1750.  
  1751. bool extractor::processX59(uint32 offset, uint32 parent, uint32 caller)
  1752. {
  1753.  // move to offset
  1754.  using namespace std;
  1755.  if(debug) dfile << endl;
  1756.  if(debug) dfile << "LOADING SECTION 0x59 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1757.  ifile.seekg(offset);
  1758.  if(ifile.fail()) return error("Seek failure.");
  1759.  
  1760.  // read header
  1761.  static const uint32 header_elem = 7;
  1762.  uint32 header[header_elem];
  1763.  BE_read_array(ifile, &header[0], header_elem);
  1764.  
  1765.  // debug information
  1766.  if(debug) {
  1767.     dfile << "HEADER" << endl;
  1768.     dfile << " headtype = " << header[0] << endl;
  1769.     dfile << " headsize = " << header[1] << endl;
  1770.     dfile << " number of children = " << header[2] << endl;
  1771.     dfile << " type = " << header[3] << endl;
  1772.     dfile << " number of vertices = " << header[4] << endl;
  1773.     dfile << " vertex bytes = " << header[5] << endl;
  1774.     dfile << " unknown = " << header[6] << endl; // 0x0
  1775.    }
  1776.  
  1777.  // validate
  1778.  if(header[0] != 0x59) return error("Expecting SECTION 0x59.");
  1779.  if(header[1] != 28) return error("Invalid SECTION 0x59 size of header.");
  1780.  
  1781.  // read offsets
  1782.  deque<uint32> offsets;
  1783.  for(uint32 i = 0; i < header[2]; i++) {
  1784.      uint32 temp = BE_read_uint32(ifile);
  1785.      offsets.push_back(temp);
  1786.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  1787.     }
  1788.  
  1789.  struct VERTEXINFO {
  1790.   uint32 type;
  1791.   uint32 elem;
  1792.   uint32 vertex_type;
  1793.   uint32 vertex_size;
  1794.   uint32 item_offset;
  1795.   uint32 file_offset;
  1796.  };
  1797.  
  1798.  // data
  1799.  deque<VERTEXINFO> vinfo;
  1800.  bool has_points = false;
  1801.  bool has_normal = false;
  1802.  uint32 start = 0;
  1803.  
  1804.  // process data at offsets
  1805.  for(size_t i = 0; i < offsets.size(); i++)
  1806.     {
  1807.      // move to offset
  1808.      ifile.seekg(offsets[i]);
  1809.      if(ifile.fail()) return error("Seek failure.");
  1810.  
  1811.      // read vertex information
  1812.      static const uint32 elem = 6;
  1813.      uint32 data[elem];
  1814.      BE_read_array(ifile, &data[0], elem);
  1815.  
  1816.      // save vertex information
  1817.      VERTEXINFO vi;
  1818.      vi.type = data[0];
  1819.      vi.elem = data[1];
  1820.      vi.vertex_type = data[2];
  1821.      vi.vertex_size = data[3];
  1822.      vi.item_offset = data[4];
  1823.      vi.file_offset = data[5];
  1824.      vinfo.push_back(vi);
  1825.  
  1826.      // test
  1827.      if(vi.type == 0) has_points = true;
  1828.      if(vi.type == 2) has_normal = true;
  1829.  
  1830.      // debug information
  1831.      if(debug) {
  1832.         dfile << "DATA" << endl;
  1833.         dfile << " type = " << data[0] << endl;
  1834.         dfile << " elem = " << data[1] << endl;
  1835.         dfile << " vertex_type = " << data[2] << endl; // 12 = float, 18 = half float
  1836.         dfile << " vertex_size = " << data[3] << endl;
  1837.         dfile << " item offset = " << data[4] << endl;
  1838.         dfile << " file offset = " << hex << data[5] << dec << endl;
  1839.        }
  1840.  
  1841.      // save start of vertex data
  1842.      if(i == 0) start = data[5];
  1843.      else if(start != data[5]) return error("Vertex data offsets do not match.");
  1844.     }
  1845.  
  1846.  // move to vertex data
  1847.  ifile.seekg(start);
  1848.  if(ifile.fail()) return error("Seek failure.");
  1849.  
  1850.  // VERTEX TYPE: 1
  1851.  // POSITION
  1852.  if(header[3] == 1)
  1853.    {
  1854.     // create position data
  1855.     uint32 n_vertices = header[4];
  1856.     uint32 vertexsize = header[5];
  1857.     if(has_points) points.resize(n_vertices);
  1858.     if(has_normal) normal.resize(n_vertices);
  1859.  
  1860.     // compute total number of bytes to read
  1861.     uint32 total_bytes = n_vertices*vertexsize;
  1862.     if(!total_bytes) return error("No vertex data to read.");
  1863.  
  1864.     // read vertex data
  1865.     boost::shared_array<char> data(new char[total_bytes]);
  1866.     ifile.read(data.get(), total_bytes);
  1867.     if(ifile.fail()) return error("Read failure.");
  1868.  
  1869.     // read points
  1870.     binary_stream bs(data, total_bytes);
  1871.     for(size_t i = 0; i < n_vertices; i++)
  1872.        {
  1873.         // for each vertex component
  1874.         for(size_t j = 0; j < vinfo.size(); j++)
  1875.            {
  1876.             // move to vertex component
  1877.             bs.seek(i*vinfo[j].vertex_size + vinfo[j].item_offset);
  1878.  
  1879.             // position
  1880.             if(vinfo[j].type == 0) {
  1881.                real32 x = bs.BE_read_real32();
  1882.                real32 y = bs.BE_read_real32();
  1883.                real32 z = bs.BE_read_real32();
  1884.                points[i].x = x;
  1885.                points[i].y = y;
  1886.                points[i].z = z;
  1887.                if(debug) dfile << " position[" << i << "] = (" << x << ", " << y << ", " << z << ") ";
  1888.               }
  1889.             else if(vinfo[j].type == 2) {
  1890.                real32 x = bs.BE_read_real16();
  1891.                real32 y = bs.BE_read_real16();
  1892.                real32 z = bs.BE_read_real16();
  1893.                normal[i].x = x;
  1894.                normal[i].y = y;
  1895.                normal[i].z = z;
  1896.                if(debug) dfile << " normal[" << i << "] = (" << x << ", " << y << ", " << z << ") ";
  1897.               }
  1898.             else if(vinfo[j].type == 3) {
  1899.                real32 x = bs.BE_read_real16();
  1900.                real32 y = bs.BE_read_real16();
  1901.                real32 z = bs.BE_read_real16();
  1902.                real32 w = bs.BE_read_real16();
  1903.                if(debug) dfile << " type03[" << i << "] = (" << x << ", " << y << ", " << z << ", " << w << ") ";
  1904.               }
  1905.             else if(vinfo[j].type == 14) {
  1906.                real32 x = bs.BE_read_real16();
  1907.                real32 y = bs.BE_read_real16();
  1908.                real32 z = bs.BE_read_real16();
  1909.                if(debug) dfile << " type14[" << i << "] = (" << x << ", " << y << ", " << z << ") ";
  1910.               }
  1911.             else if(vinfo[j].type == 15) {
  1912.                real32 x = bs.BE_read_real16();
  1913.                real32 y = bs.BE_read_real16();
  1914.                real32 z = bs.BE_read_real16();
  1915.                if(debug) dfile << " type15[" << i << "] = (" << x << ", " << y << ", " << z << ") ";
  1916.               }
  1917.            }
  1918.         if(debug) dfile << endl;
  1919.        }
  1920.    }
  1921.  // VERTEX TYPE: 2
  1922.  // UV
  1923.  else if(header[3] == 2)
  1924.    {
  1925.     // read UV map data
  1926.     if(debug) dfile << "UV DATA" << endl;
  1927.     for(size_t i = 0; i < header[4]; i++)
  1928.        {
  1929.         // read point
  1930.         real32 x = BE_read_real16(ifile);
  1931.         real32 y = BE_read_real16(ifile);
  1932.         y = 1.0f - y;
  1933.         if(debug) dfile << " uv[" << i << "] = (" << x << ", " << y << ")" << endl;
  1934.        }
  1935.    }
  1936.  // VERTEX TYPE: 3
  1937.  // WEIGHTS
  1938.  else if(header[3] == 3)
  1939.    {
  1940.    }
  1941.  else
  1942.    {
  1943.     return error("Unknown vertex type.");
  1944.    }
  1945.  
  1946.  return true;
  1947. }
  1948.  
  1949. bool extractor::processX5B(uint32 offset, uint32 parent, uint32 caller)
  1950. {
  1951.  // move to offset
  1952.  using namespace std;
  1953.  if(debug) dfile << endl;
  1954.  if(debug) dfile << "LOADING SECTION 0x5B at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  1955.  ifile.seekg(offset);
  1956.  if(ifile.fail()) return error("Seek failure.");
  1957.  
  1958.  // read header
  1959.  static const uint32 header_elem = 3;
  1960.  uint32 header[header_elem];
  1961.  BE_read_array(ifile, &header[0], header_elem);
  1962.  
  1963.  // debug information
  1964.  if(debug) {
  1965.     dfile << "HEADER" << endl;
  1966.     dfile << " headtype = " << header[0] << endl;
  1967.     dfile << " headsize = " << header[1] << endl;
  1968.     dfile << " number of children = " << header[2] << endl;
  1969.    }
  1970.  
  1971.  // validate
  1972.  if(header[0] != 0x5B) return error("Expecting SECTION 0x5B.");
  1973.  if(header[1] != 12) return error("Invalid SECTION 0x5B size of header.");
  1974.  
  1975.  // read offsets
  1976.  deque<uint32> offsets;
  1977.  for(uint32 i = 0; i < header[2]; i++) {
  1978.      uint32 temp = BE_read_uint32(ifile);
  1979.      offsets.push_back(temp);
  1980.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  1981.     }
  1982.  
  1983.  // process data at offsets
  1984.  for(size_t i = 0; i < offsets.size(); i++)
  1985.     {
  1986.      // move to offset
  1987.      ifile.seekg(offsets[i]);
  1988.      if(ifile.fail()) return error("Seek failure.");
  1989.  
  1990.      // read data
  1991.      static const uint32 elem = 2;
  1992.      uint32 data[elem];
  1993.      BE_read_array(ifile, &data[0], elem);
  1994.  
  1995.      // debug information
  1996.      if(debug) {
  1997.         dfile << "DATA" << endl;
  1998.         dfile << " data type = " << data[0] << endl;
  1999.         dfile << " string table index = " << data[1] << ", " << string_table[data[1]] << endl;
  2000.        }
  2001.  
  2002.      // Translation
  2003.      // 12 bytes
  2004.      if(data[0] == 20)
  2005.        {
  2006.         real32 x = BE_read_real32(ifile);
  2007.         real32 y = BE_read_real32(ifile);
  2008.         real32 z = BE_read_real32(ifile);
  2009.         if(debug) {
  2010.            dfile << " x = " << x << endl;
  2011.            dfile << " y = " << y << endl;
  2012.            dfile << " z = " << z << endl;
  2013.           }
  2014.        }
  2015.      // Scale
  2016.      // 20 or 24 bytes?
  2017.      else if(data[0] == 21)
  2018.        {
  2019.         real32 x = BE_read_real32(ifile);
  2020.         real32 y = BE_read_real32(ifile);
  2021.         real32 z = BE_read_real32(ifile);
  2022.         if(debug) {
  2023.            dfile << " x = " << x << endl;
  2024.            dfile << " y = " << y << endl;
  2025.            dfile << " z = " << z << endl;
  2026.           }
  2027.        }
  2028.      // rotateX, rotateY, rotateZ
  2029.      // 24 bytes
  2030.      else if(data[0] >= 93 && data[0] <= 95)
  2031.        {
  2032.         real32 a = BE_read_real32(ifile);
  2033.         real32 b = BE_read_real32(ifile);
  2034.         real32 c = BE_read_real32(ifile);
  2035.         real32 d = BE_read_real32(ifile);
  2036.         if(debug) {
  2037.            dfile << " a = " << a << endl;
  2038.            dfile << " b = " << b << endl;
  2039.            dfile << " c = " << c << endl;
  2040.            dfile << " d = " << d << endl;
  2041.           }
  2042.        }
  2043.      // jointOrientX
  2044.      // 24 bytes
  2045.      else if(data[0] == 103)
  2046.        {
  2047.         real32 a = BE_read_real32(ifile);
  2048.         real32 b = BE_read_real32(ifile);
  2049.         real32 c = BE_read_real32(ifile);
  2050.         real32 d = BE_read_real32(ifile);
  2051.         if(debug) {
  2052.            dfile << " a = " << a << endl;
  2053.            dfile << " b = " << b << endl;
  2054.            dfile << " c = " << c << endl;
  2055.            dfile << " d = " << d << endl;
  2056.           }
  2057.        }
  2058.      // CollisionFlag
  2059.      // 20 bytes
  2060.      else if(data[0] == 112)
  2061.        {
  2062.        }
  2063.      // CollisionRadius
  2064.      // 20 bytes
  2065.      else if(data[0] == 113)
  2066.        {
  2067.        }
  2068.      // PhysicsFlag
  2069.      // 20 bytes
  2070.      else if(data[0] == 114)
  2071.        {
  2072.        }
  2073.      // PhysicsRadius
  2074.      // 20 bytes
  2075.      else if(data[0] == 115)
  2076.        {
  2077.        }
  2078.      // PhysicsCost
  2079.      // 20 bytes
  2080.      else if(data[0] == 116)
  2081.        {
  2082.        }
  2083.      // PhysicsMass
  2084.      // 20 bytes
  2085.      else if(data[0] == 117)
  2086.        {
  2087.        }
  2088.      // PhysicsExpand
  2089.      // 20 bytes
  2090.      else if(data[0] == 118)
  2091.        {
  2092.        }
  2093.      // PhysicsShapeMemory
  2094.      // 20 bytes
  2095.      else if(data[0] == 119)
  2096.        {
  2097.        }
  2098.      // ???
  2099.      else if(data[0] >= 122 && data[0] <= 126)
  2100.        {
  2101.        }
  2102.      // ???
  2103.      else
  2104.        {
  2105.        }
  2106.     }
  2107.  
  2108.  return true;
  2109. }
  2110.  
  2111. bool extractor::processX5C(uint32 offset, uint32 parent, uint32 caller)
  2112. {
  2113.  // move to offset
  2114.  using namespace std;
  2115.  if(debug) dfile << endl;
  2116.  if(debug) dfile << "LOADING SECTION 0x5C at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  2117.  ifile.seekg(offset);
  2118.  if(ifile.fail()) return error("Seek failure.");
  2119.  
  2120.  // read header
  2121.  static const uint32 header_elem = 3;
  2122.  uint32 header[header_elem];
  2123.  BE_read_array(ifile, &header[0], header_elem);
  2124.  
  2125.  // debug information
  2126.  if(debug) {
  2127.     dfile << "HEADER" << endl;
  2128.     dfile << " headtype = " << header[0] << endl;
  2129.     dfile << " headsize = " << header[1] << endl;
  2130.     dfile << " number of children = " << header[2] << endl;
  2131.    }
  2132.  
  2133.  // validate
  2134.  if(header[0] != 0x5C) return error("Expecting SECTION 0x5C.");
  2135.  if(header[1] != 12) return error("Invalid SECTION 0x5C size of header.");
  2136.  
  2137.  // read offsets
  2138.  deque<uint32> offsets;
  2139.  for(uint32 i = 0; i < header[2]; i++) {
  2140.      uint32 temp = BE_read_uint32(ifile);
  2141.      offsets.push_back(temp);
  2142.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  2143.     }
  2144.  
  2145.  // TODO: offsets refer to bone offsets in SECTION 0x05
  2146.  // it is safe to link child bones here
  2147.  
  2148.  return true;
  2149. }
  2150.  
  2151. bool extractor::processX61(uint32 offset, uint32 parent, uint32 caller)
  2152. {
  2153.  // move to offset
  2154.  using namespace std;
  2155.  if(debug) dfile << endl;
  2156.  if(debug) dfile << "LOADING SECTION 0x61 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  2157.  ifile.seekg(offset);
  2158.  if(ifile.fail()) return error("Seek failure.");
  2159.  
  2160.  // read header
  2161.  static const uint32 header_elem = 3;
  2162.  uint32 header[header_elem];
  2163.  BE_read_array(ifile, &header[0], header_elem);
  2164.  
  2165.  // debug information
  2166.  if(debug) {
  2167.     dfile << "HEADER" << endl;
  2168.     dfile << " headtype = " << header[0] << endl;
  2169.     dfile << " headsize = " << header[1] << endl;
  2170.     dfile << " number of children = " << header[2] << endl;
  2171.    }
  2172.  
  2173.  // validate
  2174.  if(header[0] != 97) return error("Expecting SECTION 0x61.");
  2175.  if(header[1] != 12) return error("Invalid SECTION 0x61 size of header.");
  2176.  
  2177.  // read offsets
  2178.  deque<uint32> offsets;
  2179.  for(uint32 i = 0; i < header[2]; i++) {
  2180.      uint32 temp = BE_read_uint32(ifile);
  2181.      offsets.push_back(temp);
  2182.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  2183.     }
  2184.  
  2185.  // process data at offsets
  2186.  for(size_t i = 0; i < offsets.size(); i++)
  2187.      if(!processXXX(offsets[i], offset, 0x61)) return false;
  2188.  
  2189.  return true;
  2190. }
  2191.  
  2192. bool extractor::processX62(uint32 offset, uint32 parent, uint32 caller)
  2193. {
  2194.  // move to offset
  2195.  using namespace std;
  2196.  if(debug) dfile << endl;
  2197.  if(debug) dfile << "LOADING SECTION 0x62 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  2198.  ifile.seekg(offset);
  2199.  if(ifile.fail()) return error("Seek failure.");
  2200.  
  2201.  // read header
  2202.  static const uint32 header_elem = 3;
  2203.  uint32 header[header_elem];
  2204.  BE_read_array(ifile, &header[0], header_elem);
  2205.  
  2206.  // debug information
  2207.  if(debug) {
  2208.     dfile << "HEADER" << endl;
  2209.     dfile << " headtype = " << header[0] << endl;
  2210.     dfile << " headsize = " << header[1] << endl;
  2211.     dfile << " number of children = " << header[2] << endl;
  2212.    }
  2213.  
  2214.  // validate
  2215.  if(header[0] != 0x62) return error("Expecting SECTION 0x62.");
  2216.  if(header[1] != 12) return error("Invalid SECTION 0x62 size of header.");
  2217.  
  2218.  // read offsets
  2219.  deque<uint32> offsets;
  2220.  for(uint32 i = 0; i < header[2]; i++) {
  2221.      uint32 temp = BE_read_uint32(ifile);
  2222.      offsets.push_back(temp);
  2223.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  2224.     }
  2225.  
  2226.  // process data at offsets
  2227.  for(size_t i = 0; i < offsets.size(); i++)
  2228.      if(!processXXX(offsets[i], offset, 0x62)) return false;
  2229.  
  2230.  return true;
  2231. }
  2232.  
  2233. bool extractor::processX63(uint32 offset, uint32 parent, uint32 caller)
  2234. {
  2235.  // move to offset
  2236.  using namespace std;
  2237.  if(debug) dfile << endl;
  2238.  if(debug) dfile << "LOADING SECTION 0x63 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  2239.  ifile.seekg(offset);
  2240.  if(ifile.fail()) return error("Seek failure.");
  2241.  
  2242.  // read header
  2243.  static const uint32 header_elem = 11;
  2244.  uint32 header[header_elem];
  2245.  BE_read_array(ifile, &header[0], header_elem);
  2246.  
  2247.  // debug information
  2248.  if(debug) {
  2249.     dfile << "HEADER" << endl;
  2250.     dfile << " headtype = " << header[0] << endl;
  2251.     dfile << " headsize = " << header[1] << endl;
  2252.     dfile << " number of children = " << header[2] << endl;
  2253.     dfile << " unknown = " << header[3] << endl;
  2254.     dfile << " unknown = " << header[4] << endl;
  2255.     dfile << " unknown = " << header[5] << endl;
  2256.     dfile << " unknown = " << header[6] << endl;
  2257.     dfile << " unknown = " << header[7] << endl;
  2258.     dfile << " unknown = " << header[8] << endl;
  2259.     dfile << " unknown = " << header[9] << endl;
  2260.     dfile << " unknown = " << header[10] << endl;
  2261.    }
  2262.  
  2263.  // validate
  2264.  if(header[0] != 0x63) return error("Expecting SECTION 0x63.");
  2265.  if(header[1] != 44) return error("Invalid SECTION 0x63 size of header.");
  2266.  
  2267.  // read offsets
  2268.  deque<uint32> offsets;
  2269.  for(uint32 i = 0; i < header[2]; i++) {
  2270.      uint32 temp = BE_read_uint32(ifile);
  2271.      offsets.push_back(temp);
  2272.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  2273.     }
  2274.  
  2275.  // process data at offsets
  2276.  for(size_t i = 0; i < offsets.size(); i++)
  2277.      if(!processXXX(offsets[i], offset, 0x63)) return false;
  2278.  
  2279.  return true;
  2280. }
  2281.  
  2282. bool extractor::processX65(uint32 offset, uint32 parent, uint32 caller)
  2283. {
  2284.  // move to offset
  2285.  using namespace std;
  2286.  if(debug) dfile << endl;
  2287.  if(debug) dfile << "LOADING SECTION 0x65 at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  2288.  ifile.seekg(offset);
  2289.  if(ifile.fail()) return error("Seek failure.");
  2290.  
  2291.  // read header
  2292.  static const uint32 header_elem = 4;
  2293.  uint32 header[header_elem];
  2294.  BE_read_array(ifile, &header[0], header_elem);
  2295.  
  2296.  // debug information
  2297.  if(debug) {
  2298.     dfile << "HEADER" << endl;
  2299.     dfile << " headtype = " << header[0] << endl;
  2300.     dfile << " headsize = " << header[1] << endl;
  2301.     dfile << " number of children = " << header[2] << endl;
  2302.     dfile << " unknown = " << header[3] << endl;
  2303.    }
  2304.  
  2305.  // validate
  2306.  if(header[0] != 0x65) return error("Expecting SECTION 0x65.");
  2307.  if(header[1] != 16) return error("Invalid SECTION 0x65 size of header.");
  2308.  
  2309.  // read offsets
  2310.  deque<uint32> offsets;
  2311.  for(uint32 i = 0; i < header[2]; i++) {
  2312.      uint32 temp = BE_read_uint32(ifile);
  2313.      offsets.push_back(temp);
  2314.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  2315.     }
  2316.  
  2317.  // process data at offsets
  2318.  for(size_t i = 0; i < offsets.size(); i++)
  2319.     {
  2320.      // move to offset
  2321.      ifile.seekg(offsets[i]);
  2322.      if(ifile.fail()) return error("Seek failure.");
  2323.  
  2324.      // read data
  2325.      static const uint32 elem = 4;
  2326.      uint32 data[elem];
  2327.      BE_read_array(ifile, &data[0], elem);
  2328.  
  2329.      // debug information
  2330.      if(debug) {
  2331.         dfile << "DATA" << endl;
  2332.         dfile << " index = " << data[0] << endl; // 1, 2, 3, ...
  2333.         dfile << " unknown = " << data[1] << endl; // 1, 2
  2334.         dfile << " number of items = " << data[2] << endl; // 1 (20 bytes) or 4 (32 bytes)
  2335.         dfile << " item type = " << data[3] << endl; // 0 or some integer
  2336.        }
  2337.  
  2338.      // read data
  2339.      for(size_t i = 0; i < data[2]; i++) {
  2340.          uint32 item = BE_read_uint32(ifile);
  2341.          if(debug) {
  2342.             if(data[3] == 0) dfile << " item = " << interpret_as_real32(item) << endl;
  2343.             else dfile << " item = " << item << endl;
  2344.            }
  2345.         }
  2346.     }
  2347.  
  2348.  return true;
  2349. }
  2350.  
  2351. bool extractor::processX6A(uint32 offset, uint32 parent, uint32 caller)
  2352. {
  2353.  // move to offset
  2354.  using namespace std;
  2355.  if(debug) dfile << endl;
  2356.  if(debug) dfile << "LOADING SECTION 0x6A at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  2357.  ifile.seekg(offset);
  2358.  if(ifile.fail()) return error("Seek failure.");
  2359.  
  2360.  // read header
  2361.  static const uint32 header_elem = 5;
  2362.  uint32 header[header_elem];
  2363.  BE_read_array(ifile, &header[0], header_elem);
  2364.  
  2365.  // debug information
  2366.  if(debug) {
  2367.     dfile << "HEADER" << endl;
  2368.     dfile << " headtype = " << header[0] << endl;
  2369.     dfile << " headsize = " << header[1] << endl;
  2370.     dfile << " number of children = " << header[2] << endl;
  2371.     dfile << " string table index = " << header[3] << ", " << string_table[header[3]] << endl;
  2372.     dfile << " string table index = " << header[4] << ", " << string_table[header[4]] << endl;
  2373.    }
  2374.  
  2375.  // validate
  2376.  if(header[0] != 0x6A) return error("Expecting SECTION 0x6A.");
  2377.  if(header[1] != 20) return error("Invalid SECTION 0x6A size of header.");
  2378.  
  2379.  // read offsets
  2380.  deque<uint32> offsets;
  2381.  for(uint32 i = 0; i < header[2]; i++) {
  2382.      uint32 temp = BE_read_uint32(ifile);
  2383.      offsets.push_back(temp);
  2384.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  2385.     }
  2386.  
  2387.  // process data at offsets
  2388.  for(size_t i = 0; i < offsets.size(); i++)
  2389.      if(!processXXX(offsets[i], offset, 0x6A)) return false;
  2390.  
  2391.  return true;
  2392. }
  2393.  
  2394. bool extractor::processX6B(uint32 offset, uint32 parent, uint32 caller)
  2395. {
  2396.  // move to offset
  2397.  using namespace std;
  2398.  if(debug) dfile << endl;
  2399.  if(debug) dfile << "LOADING SECTION 0x6B at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  2400.  ifile.seekg(offset);
  2401.  if(ifile.fail()) return error("Seek failure.");
  2402.  
  2403.  // read header
  2404.  static const uint32 header_elem = 6;
  2405.  uint32 header[header_elem];
  2406.  BE_read_array(ifile, &header[0], header_elem);
  2407.  
  2408.  // debug information
  2409.  if(debug) {
  2410.     dfile << "HEADER" << endl;
  2411.     dfile << " headtype = " << header[0] << endl;
  2412.     dfile << " headsize = " << header[1] << endl;
  2413.     dfile << " number of children = " << header[2] << endl;
  2414.     dfile << " type = " << header[3] << endl;
  2415.     dfile << " elem = " << header[4] << endl;
  2416.     dfile << " 0x6A offset = 0x" << hex << header[5] << dec << endl;
  2417.    }
  2418.  
  2419.  // validate
  2420.  if(header[0] != 0x6B) return error("Expecting SECTION 0x6B.");
  2421.  if(header[1] != 24) return error("Invalid SECTION 0x6B size of header.");
  2422.  
  2423.  // read offsets
  2424.  deque<uint32> offsets;
  2425.  for(uint32 i = 0; i < header[2]; i++) {
  2426.      uint32 temp = BE_read_uint32(ifile);
  2427.      offsets.push_back(temp);
  2428.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  2429.     }
  2430.  
  2431.  // process data at offsets
  2432.  if(header[3] == 0x02 || header[3] == 0x06) {
  2433.     for(size_t i = 0; i < offsets.size(); i++)
  2434.         if(!processXXX(offsets[i], offset, 0x6B)) return false;
  2435.    }
  2436.  // process data
  2437.  else if(header[3] == 0x15)
  2438.    {
  2439.     if(offsets.size() != 1) return error("Invalid section 0x6B data.");
  2440.     ifile.seekg(offsets[0]);
  2441.     if(ifile.fail()) return error("Seek failure.");
  2442.     uint32 index = BE_read_uint32(ifile);
  2443.     string value = string_table[index];
  2444.     if(debug) {
  2445.        dfile << "DATA" << endl;
  2446.        dfile << " surface = " << value << endl;
  2447.       }
  2448.    }
  2449.  // process data
  2450.  else if(header[3] == 0x18)
  2451.    {
  2452.     if(offsets.size() != 1) return error("Invalid section 0x6B data.");
  2453.     ifile.seekg(offsets[0]);
  2454.     if(ifile.fail()) return error("Seek failure.");
  2455.     uint32 index = BE_read_uint32(ifile);
  2456.     string value = string_table[index];
  2457.     if(debug) {
  2458.        dfile << "DATA" << endl;
  2459.        dfile << " image format = " << value << endl;
  2460.       }
  2461.    }
  2462.  // process data
  2463.  else
  2464.    {
  2465.     uint32 elem = header[4];
  2466.     boost::shared_array<uint32> data(new uint32[elem]);
  2467.     BE_read_array(ifile, data.get(), elem);
  2468.     if(debug) {
  2469.        dfile << "DATA" << endl;
  2470.        for(uint32 i = 0; i < elem; i++) dfile << " data[" << i << "] = " << data[i] << endl;
  2471.       }
  2472.    }
  2473.  
  2474.  return true;
  2475. }
  2476.  
  2477. bool extractor::processX6C(uint32 offset, uint32 parent, uint32 caller)
  2478. {
  2479.  // move to offset
  2480.  using namespace std;
  2481.  if(debug) dfile << endl;
  2482.  if(debug) dfile << "LOADING SECTION 0x6C at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  2483.  ifile.seekg(offset);
  2484.  if(ifile.fail()) return error("Seek failure.");
  2485.  
  2486.  // read header
  2487.  static const uint32 header_elem = 3;
  2488.  uint32 header[header_elem];
  2489.  BE_read_array(ifile, &header[0], header_elem);
  2490.  
  2491.  // debug information
  2492.  if(debug) {
  2493.     dfile << "HEADER" << endl;
  2494.     dfile << " headtype = " << header[0] << endl;
  2495.     dfile << " headsize = " << header[1] << endl;
  2496.     dfile << " number of children = " << header[2] << endl;
  2497.    }
  2498.  
  2499.  // validate
  2500.  if(header[0] != 0x6C) return error("Expecting SECTION 0x6C.");
  2501.  if(header[1] != 12) return error("Invalid SECTION 0x6C size of header.");
  2502.  
  2503.  // read offsets
  2504.  deque<uint32> offsets;
  2505.  for(uint32 i = 0; i < header[2]; i++) {
  2506.      uint32 temp = BE_read_uint32(ifile);
  2507.      offsets.push_back(temp);
  2508.      if(debug) dfile << " offsets[" << i << "] = 0x" << hex << offsets[i] << dec << endl;
  2509.     }
  2510.  
  2511.  // process data at offsets
  2512.  for(size_t i = 0; i < offsets.size(); i++)
  2513.      if(!processXXX(offsets[i], offset, 0x6C)) return false;
  2514.  
  2515.  return true;
  2516. }
  2517.  
  2518. bool extractor::processX6E(uint32 offset, uint32 parent, uint32 caller)
  2519. {
  2520.  // move to offset
  2521.  using namespace std;
  2522.  if(debug) dfile << endl;
  2523.  if(debug) dfile << "LOADING SECTION 0x6E at 0x" << hex << offset << " from 0x" << caller << dec << endl;
  2524.  ifile.seekg(offset);
  2525.  if(ifile.fail()) return error("Seek failure.");
  2526.  
  2527.  // read header
  2528.  static const uint32 header_elem = 12;
  2529.  uint32 header[header_elem];
  2530.  BE_read_array(ifile, &header[0], header_elem);
  2531.  
  2532.  // debug information
  2533.  if(debug) {
  2534.     dfile << "HEADER" << endl;
  2535.     dfile << " headtype = " << header[0] << endl;
  2536.     dfile << " headsize = " << header[1] << endl;
  2537.     dfile << " unknown = " << header[2] << endl; // 0
  2538.     dfile << " unknown = " << header[3] << endl; // 0
  2539.     dfile << " min_x = " << interpret_as_real32(header[ 4]) << endl;
  2540.     dfile << " min_y = " << interpret_as_real32(header[ 5]) << endl;
  2541.     dfile << " min_z = " << interpret_as_real32(header[ 6]) << endl;
  2542.     dfile << " max_w = " << interpret_as_real32(header[ 7]) << endl;
  2543.     dfile << " max_x = " << interpret_as_real32(header[ 8]) << endl;
  2544.     dfile << " max_y = " << interpret_as_real32(header[ 9]) << endl;
  2545.     dfile << " max_z = " << interpret_as_real32(header[10]) << endl;
  2546.     dfile << " max_w = " << interpret_as_real32(header[11]) << endl;
  2547.    }
  2548.  
  2549.  // validate
  2550.  if(header[0] != 0x6E) return error("Expecting SECTION 0x6E.");
  2551.  if(header[1] != 48) return error("Invalid SECTION 0x6E size of header.");
  2552.  
  2553.  return true;
  2554. }
  2555.  
  2556. };};
  2557.  
  2558. namespace X_SYSTEM { namespace X_GAME {
  2559.  
  2560. bool extract(void)
  2561. {
  2562.  std::string pathname = GetModulePathname();
  2563.  return extract(pathname.c_str());
  2564. }
  2565.  
  2566. bool extract(const char* pathname)
  2567. {
  2568.  return extractor(pathname).extract();
  2569. }
  2570.  
  2571. };};