home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 5257 / source.7z / ps3_macross_frontier.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2012-01-06  |  18.7 KB  |  557 lines

  1. #include "xentax.h"
  2. #include "ps3_macross_frontier.h"
  3.  
  4. // failed
  5. // 03057802.hld on 3rd surface
  6.  
  7. namespace PS3 { namespace MacrossFrontier {
  8.  
  9.  class extractor {
  10.   private :
  11.    std::string pathname;
  12.    std::ifstream ifile;
  13.    uint32 curr_model;
  14.    std::deque<VERTEX_BUFFER> curr_vd;
  15.    std::deque<INDEX_BUFFER> curr_fd;
  16.   private :
  17.    bool processHLD(const char* filename);
  18.    bool processHRTM(uint32 param01, uint32 param02, uint32 param03, uint32 param04);
  19.    bool processHARF(uint32 param01, uint32 param02, uint32 param03, uint32 param04);
  20.    bool processLKSE(uint32 param01, uint32 param02, uint32 param03, uint32 param04);
  21.    bool processMARF(uint32 param01, uint32 param02, uint32 param03, uint32 param04);
  22.    bool process_XET(uint32 param01, uint32 param02, uint32 param03, uint32 param04);
  23.    bool process2MDB(uint32 param01, uint32 param02, uint32 param03, uint32 param04);
  24.    bool process2HMG(uint32 param01, uint32 param02, uint32 param03, uint32 param04);
  25.    bool process_2MG(uint32 param01, uint32 param02, uint32 param03, uint32 param04);
  26.    bool processTPMG(uint32 param01, uint32 param02, uint32 param03, uint32 param04);
  27.   public :
  28.    bool extract(void);
  29.   public :
  30.    extractor(const char* pn);
  31.   ~extractor();
  32.  };
  33.  
  34. };}; // PS3::MacrossFrontier
  35.  
  36. namespace PS3 { namespace MacrossFrontier {
  37.  
  38.  extractor::extractor(const char* pn)
  39.  {
  40.   pathname = pn;
  41.   curr_model = 0;
  42.  }
  43.  
  44.  extractor::~extractor()
  45.  {
  46.  }
  47.  
  48.  bool extractor::extract(void)
  49.  {
  50.   std::deque<std::string> namelist;
  51.   BuildFilenameList(namelist, "hld", pathname.c_str());
  52.   for(size_t i = 0; i < namelist.size(); i++) {
  53.       cout << "Processing file " << i << " of " << namelist.size() << ": " << namelist[i] << "." << endl;
  54.       if(!processHLD(namelist[i].c_str())) return false;
  55.      }
  56.   return true;
  57.  }
  58.  
  59.  bool extractor::processHLD(const char* filename)
  60.  {
  61.   // open file
  62.   ifile.open(filename, ios::binary);
  63.   if(!ifile) return error("Failed to open file.");
  64.  
  65.   // read HLDM
  66.   uint32 hldm = BE_read_uint32(ifile);
  67.   if(hldm != 0x484C444D) return error("Expecting HLDM.");
  68.  
  69.   // read HLDM parameters
  70.   uint32 HLDM_param01 = BE_read_uint32(ifile); // 0x08
  71.   uint32 HLDM_param02 = BE_read_uint32(ifile); // 0x01
  72.   uint32 HLDM_param03 = BE_read_uint32(ifile); // 0x08
  73.   uint32 HLDM_param04 = BE_read_uint32(ifile); // _LDM
  74.   uint32 HLDM_param05 = BE_read_uint32(ifile); // 0x01
  75.  
  76.   if(HLDM_param04 != 0x5F4C444D) return error("Expecting _LDM.");
  77.   if(HLDM_param05 != 0x00000001) return error("Expecting 0x01.");
  78.  
  79.   for(;;)
  80.      {
  81.       // read chunkname
  82.       uint32 param01 = BE_read_uint32(ifile);
  83.       uint32 param02 = BE_read_uint32(ifile);
  84.       uint32 param03 = BE_read_uint32(ifile);
  85.       uint32 param04 = BE_read_uint32(ifile);
  86.  
  87.       // save position
  88.       uint32 position = (uint32)ifile.tellg();
  89.       if(ifile.fail()) return error("Failed to tell position.");
  90.  
  91.       // DONE chunk
  92.       if(param01 == 0x20444E45)
  93.         {
  94.          std::string shortname = GetShortFilenameWithoutExtension(filename);
  95.          bool success = GeometryToOBJ(GetPathnameFromFilename(filename).c_str(), shortname.c_str(), curr_vd, curr_fd);
  96.          curr_model = 0; // actually current surface
  97.          curr_vd.clear();
  98.          curr_fd.clear();
  99.          ifile.close();
  100.          if(!success) return false;
  101.          break;
  102.         }
  103.       // HRTM chunk
  104.       else if(param01 == 0x4852544D)
  105.         {
  106.          if(!processHRTM(param01, param02, param03, param04)) return false;
  107.         }
  108.       // HARF chunk
  109.       else if(param01 == 0x48415246)
  110.         {
  111.          if(!processHARF(param01, param02, param03, param04)) return false;
  112.         }
  113.       // LKSE chunk
  114.       else if(param01 == 0x4C4B5345)
  115.         {
  116.          if(!processLKSE(param01, param02, param03, param04)) return false;
  117.         }
  118.       // _XET chunk
  119.       else if(param01 == 0x20584554)
  120.         {
  121.          if(!process_XET(param01, param02, param03, param04)) return false;
  122.         }
  123.       // 2MDB chunk
  124.       else if(param01 == 0x324D4442)
  125.         {
  126.          if(!process2MDB(param01, param02, param03, param04)) return false;
  127.         }
  128.       // 2HMG chunk
  129.       else if(param01 == 0x32484D47)
  130.         {
  131.          if(!process2HMG(param01, param02, param03, param04)) return false;
  132.         }
  133.       // HMTA chunk
  134.       else if(param01 == 0x484D5441) {}
  135.       // ADOL chunk
  136.       else if(param01 == 0x41444F4C) {}
  137.       // DNBS chunk
  138.       else if(param01 == 0x444E4253) {}
  139.       else
  140.          return error("Unknown chunk.");
  141.  
  142.       // move to next section
  143.       ifile.seekg(position);
  144.       ifile.seekg(param02, ios::cur);
  145.       if(ifile.fail()) return error("Failed to seek position.");
  146.      }
  147.  
  148.   return true;
  149.  }
  150.  
  151.  bool extractor::processHRTM(uint32 param01, uint32 param02, uint32 param03, uint32 param04)
  152.  {
  153.   return true;
  154.  }
  155.  
  156.  bool extractor::processHARF(uint32 param01, uint32 param02, uint32 param03, uint32 param04)
  157.  {
  158.   // number of MARF sections
  159.   uint32 n_marf = BE_read_uint32(ifile);
  160.   if(n_marf < 1 || n_marf > 999) return error("Unexpected number of MARF chunks.");
  161.  
  162.   // for each MARF section
  163.   for(size_t i = 0; i < n_marf; i++)
  164.      {
  165.       // read MARF section
  166.       uint32 param01 = BE_read_uint32(ifile);
  167.       uint32 param02 = BE_read_uint32(ifile); // size of data after unk03
  168.       uint32 param03 = BE_read_uint32(ifile); // 0x01
  169.       uint32 param04 = BE_read_uint32(ifile); // size of data after unk03 again
  170.       if(param01 != 0x4D415246) return error("Expecting MARF.");
  171.  
  172.       // save position
  173.       uint32 position = (uint32)ifile.tellg();
  174.       if(ifile.fail()) return error("Failed to tell position.");
  175.  
  176.       // process MARF data
  177.       processMARF(param01, param02, param03, param04);
  178.  
  179.       // move to next section
  180.       ifile.seekg(position);
  181.       ifile.seekg(param02, ios::cur);
  182.       if(ifile.fail()) return error("Failed to seek position.");
  183.      }
  184.  
  185.   return true;
  186.  }
  187.  
  188.  bool extractor::processLKSE(uint32 param01, uint32 param02, uint32 param03, uint32 param04)
  189.  {
  190.   // skip skeleton data for now
  191.   return true;
  192.  }
  193.  
  194.  bool extractor::processMARF(uint32 param01, uint32 param02, uint32 param03, uint32 param04)
  195.  {
  196.   return true;
  197.  }
  198.  
  199.  bool extractor::process_XET(uint32 param01, uint32 param02, uint32 param03, uint32 param04)
  200.  {
  201.   uint32 n_textures = param03; // number of textures
  202.   uint32 buffersize = param04; // filename sizes
  203.   for(size_t i = 0; i < n_textures; i++) {
  204.       char buffer[1024];
  205.       ifile.read(buffer, buffersize);
  206.      }
  207.   return true;
  208.  }
  209.  
  210.  bool extractor::process2MDB(uint32 param01, uint32 param02, uint32 param03, uint32 param04)
  211.  {
  212.   return true;
  213.  }
  214.  
  215.  bool extractor::process2HMG(uint32 param01, uint32 param02, uint32 param03, uint32 param04)
  216.  {
  217.   // process _2MG sections
  218.   uint32 n_sections = param03;
  219.   for(size_t i = 0; i < n_sections; i++)
  220.      {
  221.       // read _2MG section
  222.       uint32 param01 = BE_read_uint32(ifile);
  223.       uint32 param02 = BE_read_uint32(ifile);
  224.       uint32 param03 = BE_read_uint32(ifile);
  225.       uint32 param04 = BE_read_uint32(ifile);
  226.       if(param01 != 0x20324D47) return error("Expecting 2MG.");
  227.  
  228.       // save position
  229.       uint32 position = (uint32)ifile.tellg();
  230.       if(ifile.fail()) return error("Failed to tell position.");
  231.  
  232.       // process _2MG data
  233.       if(!process_2MG(param01, param02, param03, param04))
  234.          return false;
  235.  
  236.       // move to next section
  237.       ifile.seekg(position);
  238.       ifile.seekg(param02, ios::cur);
  239.       if(ifile.fail()) return error("Failed to seek position.");
  240.      }
  241.  
  242.   return true;
  243.  }
  244.  
  245.  bool extractor::process_2MG(uint32 param01, uint32 param02, uint32 param03, uint32 param04)
  246.  {
  247.   // skip unknown data
  248.   ifile.seekg(0x50, ios::cur);
  249.   if(ifile.fail()) return error("Seek failure.");
  250.  
  251.   // process TPMG sections
  252.   uint32 n_sections = param03;
  253.   for(size_t i = 0; i < n_sections; i++)
  254.      {
  255.       // read TPMG section
  256.       uint32 param01 = BE_read_uint32(ifile);
  257.       uint32 param02 = BE_read_uint32(ifile);
  258.       uint32 param03 = BE_read_uint32(ifile);
  259.       uint32 param04 = BE_read_uint32(ifile);
  260.       if(param01 != 0x54504D47) return error("Expecting TPMG.");
  261.  
  262.       // save position
  263.       uint32 position = (uint32)ifile.tellg();
  264.       if(ifile.fail()) return error("Failed to tell position.");
  265.  
  266.       // process TPMG data
  267.       if(!processTPMG(param01, param02, param03, param04))
  268.           return false;
  269.  
  270.       // move to next section
  271.       ifile.seekg(position);
  272.       ifile.seekg(param02, ios::cur);
  273.       if(ifile.fail()) return error("Failed to seek position.");
  274.      }
  275.  
  276.   return true;
  277.  }
  278.  
  279.  bool extractor::processTPMG(uint32 param01, uint32 param02, uint32 param03, uint32 param04)
  280.  {
  281.   // save position
  282.   uint32 position = (uint32)ifile.tellg();
  283.   if(ifile.fail()) return error("Failed to tell position.");
  284.  
  285.   // unknown
  286.   uint16 u01 = BE_read_uint16(ifile); // 0x050F (1295)
  287.   uint16 u02 = BE_read_uint16(ifile); // 0x0606 (1542)
  288.   uint16 u03 = BE_read_uint16(ifile); // 0x10
  289.   uint16 u04 = BE_read_uint16(ifile); // 0x00
  290.  
  291.   // number of points and indices
  292.   uint16 n_point = BE_read_uint16(ifile); // number of points
  293.   uint16 n_index = BE_read_uint16(ifile); // number of shorts (exact, no padding)
  294.   BE_read_uint32(ifile); // 0xFFFFFFFF
  295.  
  296.   // offsets to points and indices
  297.   uint32 ib_offset = BE_read_uint32(ifile);
  298.   uint16 ib_size = BE_read_uint16(ifile);
  299.   BE_read_uint16(ifile);
  300.   uint32 vb_offset = BE_read_uint32(ifile); // offset from position to point buffer
  301.   BE_read_uint16(ifile);
  302.   uint32 vb_size = BE_read_uint32(ifile); // size of vertex data in bytes aligned to 16-byte boundary
  303.  
  304.   // move to index buffer
  305.   ifile.seekg(position);
  306.   ifile.seekg(ib_offset, ios::cur);
  307.  
  308.   // read index buffer
  309.   INDEX_BUFFER ib;
  310.   ib.format = FACE_FORMAT_UINT_16;
  311.   ib.type = FACE_TYPE_TRIANGLES;
  312.   ib.name = "";
  313.   ib.reference = 0;
  314.   ib.elem = n_index;
  315.   ib.data.reset(reinterpret_cast<char*>(new uint16[ib.elem]));
  316.   BE_read_array(ifile, reinterpret_cast<uint16*>(ib.data.get()), ib.elem);
  317.  
  318.   // move to point buffer
  319.   ifile.seekg(position);
  320.   ifile.seekg(vb_offset, ios::cur);
  321.   if(ifile.fail()) return error("Failed to seek position.");
  322.  
  323.   // u1 = 0x050D -> has some extra vertexes
  324.   // u1 = 0x050F
  325.   // u2 = 0x0606 -> 1C
  326.   if(u01 == 0x050D && u02 == 0x0606) ;
  327.   if(u01 == 0x050E && u02 == 0x0606) ;
  328.   if(u01 == 0x050F && u02 == 0x0606) ;
  329.  
  330.   // compute number of vertices manually because header data is somewhat unreliable
  331.   uint16 n_vertices = 0;
  332.   maximum(reinterpret_cast<uint16*>(ib.data.get()), n_index, n_vertices);
  333.   n_vertices = n_vertices + 1;
  334.  
  335.   // initialize vertex buffer
  336.   VERTEX_BUFFER vb;
  337.   vb.flags = VERTEX_POSITION | VERTEX_UV;
  338.   vb.elem = n_vertices;
  339.   vb.data.reset(new VERTEX[vb.elem]);
  340.  
  341.   // read point buffer
  342.   for(size_t i = 0; i < n_vertices; i++)
  343.      {
  344.       // 16 bytes
  345.       if((u01 >= 0x0209 && u01 <= 0x020F) && u02 == 0x0C08)
  346.         {
  347.          vb.data[i].vx = BE_read_float32(ifile); // 4
  348.          vb.data[i].vy = BE_read_float32(ifile); // 8
  349.          vb.data[i].vz = BE_read_float32(ifile); // 12
  350.          vb.data[i].tu = BE_read_uint16(ifile)/65535.0f; // 14
  351.          vb.data[i].tv = 1.0f - BE_read_uint16(ifile)/65535.0f; // 16
  352.         }
  353.       // 16 bytes
  354.       else if((u01 >= 0x0209 && u01 <= 0x020F) && u02 == 0x0707)
  355.         {
  356.          vb.data[i].vx = BE_read_float32(ifile); // 4
  357.          vb.data[i].vy = BE_read_float32(ifile); // 8
  358.          vb.data[i].vz = BE_read_float32(ifile); // 12
  359.          vb.data[i].tu = BE_read_float16(ifile); // 14
  360.          vb.data[i].tv = 1.0f - BE_read_float16(ifile); // 16
  361.         }
  362.       // 20 bytes
  363.       else if((u01 >= 0x030A && u01 <= 0x0311) && u02 == 0x0D09)
  364.         {
  365.          vb.data[i].vx = BE_read_float32(ifile); // 4
  366.          vb.data[i].vy = BE_read_float32(ifile); // 8
  367.          vb.data[i].vz = BE_read_float32(ifile); // 12
  368.          BE_read_float16(ifile); // 14
  369.          BE_read_float16(ifile); // 16
  370.          vb.data[i].tu = BE_read_float16(ifile); // 18
  371.          vb.data[i].tv = 1.0f - BE_read_float16(ifile); // 20
  372.         }
  373.       // 20 bytes
  374.       else if((u01 >= 0x030A && u01 <= 0x030F) && u02 == 0x0F0B)
  375.         {
  376.          vb.data[i].vx = BE_read_float32(ifile); // 4
  377.          vb.data[i].vy = BE_read_float32(ifile); // 8
  378.          vb.data[i].vz = BE_read_float32(ifile); // 12
  379.          BE_read_float16(ifile); // 14
  380.          BE_read_float16(ifile); // 16
  381.          vb.data[i].tu = BE_read_float16(ifile); // 18
  382.          vb.data[i].tv = 1.0f - BE_read_float16(ifile); // 20
  383.         }
  384.       else if(u01 == 0x030A && u02 == 0x100C) // different format!
  385.         {
  386.          vb.data[i].vx = BE_read_float32(ifile); // 4
  387.          vb.data[i].vy = BE_read_float32(ifile); // 8
  388.          vb.data[i].vz = BE_read_float32(ifile); // 12
  389.          BE_read_uint16(ifile); // 14
  390.          BE_read_uint16(ifile); // 16
  391.          vb.data[i].tu = BE_read_uint16(ifile)/127.0f; // 18
  392.          vb.data[i].tv = 1.0f - BE_read_uint16(ifile)/127.0f; // 20
  393.         }
  394.       else if((u01 >= 0x040B && u01 <= 0x0411) && u02 == 0x0303)
  395.         {
  396.          vb.data[i].vx = BE_read_float32(ifile); // 4
  397.          vb.data[i].vy = BE_read_float32(ifile); // 8
  398.          vb.data[i].vz = BE_read_float32(ifile); // 12
  399.          BE_read_float16(ifile); // 14
  400.          BE_read_float16(ifile); // 16
  401.          BE_read_float16(ifile); // 18
  402.          BE_read_float16(ifile); // 20
  403.          vb.data[i].tu = BE_read_float16(ifile); // 22
  404.          vb.data[i].tv = 1.0f - BE_read_float16(ifile); // 24
  405.         }
  406.       else if((u01 >= 0x040B && u01 <= 0x040F) && u02 == 0x110D)
  407.         {
  408.          vb.data[i].vx = BE_read_float32(ifile); // 4
  409.          vb.data[i].vy = BE_read_float32(ifile); // 8
  410.          vb.data[i].vz = BE_read_float32(ifile); // 12
  411.          BE_read_float16(ifile); // 14
  412.          BE_read_float16(ifile); // 16
  413.          BE_read_float16(ifile); // 18
  414.          BE_read_float16(ifile); // 20
  415.          vb.data[i].tu = BE_read_uint16(ifile)/65535.0f; // 22
  416.          vb.data[i].tv = 1.0f - BE_read_uint16(ifile)/65535.0f; // 24
  417.         }
  418.  
  419.       // 28 bytes
  420.       else if((u01 >= 0x050C && u01 <= 0x0512) && u02 == 0x0606)
  421.         {
  422.          vb.data[i].vx = BE_read_float32(ifile); // 4
  423.          vb.data[i].vy = BE_read_float32(ifile); // 8
  424.          vb.data[i].vz = BE_read_float32(ifile); // 12
  425.          BE_read_float16(ifile); // 16
  426.          BE_read_float16(ifile); // 16
  427.          BE_read_float16(ifile); // 20
  428.          BE_read_float16(ifile); // 20
  429.          BE_read_float16(ifile); // 24
  430.          BE_read_float16(ifile); // 24
  431.          vb.data[i].tu = BE_read_float16(ifile); // 28
  432.          vb.data[i].tv = 1.0f - BE_read_float16(ifile); // 28
  433.         }
  434.       // 28 bytes
  435.        else if((u01 >= 0x050C && u01 <= 0x0512) && u02 == 0x120E) // architecture format... 03b00002.hld
  436.         {
  437.          vb.data[i].vx = BE_read_float32(ifile); // 4
  438.          vb.data[i].vy = BE_read_float32(ifile); // 8
  439.          vb.data[i].vz = BE_read_float32(ifile); // 12
  440.          BE_read_float16(ifile); // 16
  441.          BE_read_float16(ifile); // 16
  442.          BE_read_float16(ifile); // 20
  443.          BE_read_float16(ifile); // 20
  444.          BE_read_float16(ifile); // 24
  445.          BE_read_float16(ifile); // 24
  446.          vb.data[i].tu = BE_read_uint16(ifile)/65535.0f; // 28
  447.          vb.data[i].tv = 1.0f - BE_read_uint16(ifile)/65535.0f; // 28
  448.         }
  449.  
  450.        // 32 bytes
  451.        else if((u01 >= 0x060D && u01 <= 0x0612) && u02 == 0x130F)
  452.         {
  453.          vb.data[i].vx = BE_read_float32(ifile); // 4
  454.          vb.data[i].vy = BE_read_float32(ifile); // 8
  455.          vb.data[i].vz = BE_read_float32(ifile); // 12
  456.          BE_read_float16(ifile); // 16
  457.          BE_read_float16(ifile);
  458.          BE_read_float16(ifile); // 20
  459.          BE_read_float16(ifile);
  460.          BE_read_float16(ifile); // 24
  461.          BE_read_float16(ifile);
  462.          BE_read_float16(ifile); // 28
  463.          BE_read_float16(ifile);
  464.          vb.data[i].tu = BE_read_float16(ifile); // 32
  465.          vb.data[i].tv = 1.0f - BE_read_float16(ifile);
  466.         }
  467.        // 32 bytes
  468.        else if((u01 >= 0x060D && u01 <= 0x0612) && u02 == 0x1713)
  469.         {
  470.          vb.data[i].vx = BE_read_float32(ifile); // 4
  471.          vb.data[i].vy = BE_read_float32(ifile); // 8
  472.          vb.data[i].vz = BE_read_float32(ifile); // 12
  473.          BE_read_float16(ifile); // 16
  474.          BE_read_float16(ifile);
  475.          BE_read_float16(ifile); // 20
  476.          BE_read_float16(ifile);
  477.          BE_read_float16(ifile); // 24
  478.          BE_read_float16(ifile);
  479.          BE_read_float16(ifile); // 28
  480.          BE_read_float16(ifile);
  481.          vb.data[i].tu = BE_read_float16(ifile); // 32
  482.          vb.data[i].tv = 1.0f - BE_read_float16(ifile);
  483.         }
  484.        // 32 bytes
  485.        else if((u01 >= 0x060D && u01 <= 0x0612) && u02 == 0x1814)
  486.         {
  487.          vb.data[i].vx = BE_read_float32(ifile); // 4
  488.          vb.data[i].vy = BE_read_float32(ifile); // 8
  489.          vb.data[i].vz = BE_read_float32(ifile); // 12
  490.          BE_read_float16(ifile); // 16
  491.          BE_read_float16(ifile);
  492.          BE_read_float16(ifile); // 20
  493.          BE_read_float16(ifile);
  494.          BE_read_float16(ifile); // 24
  495.          BE_read_float16(ifile);
  496.          BE_read_float16(ifile); // 28
  497.          BE_read_float16(ifile);
  498.          vb.data[i].tu = BE_read_float16(ifile); // 32
  499.          vb.data[i].tv = 1.0f - BE_read_float16(ifile);
  500.         }
  501.        // 36 bytes
  502.        else if((u01 >= 0x070E && u01 <= 0x0713) && u02 == 0x1612)
  503.         {
  504.          vb.data[i].vx = BE_read_float32(ifile); // 4
  505.          vb.data[i].vy = BE_read_float32(ifile); // 8
  506.          vb.data[i].vz = BE_read_float32(ifile); // 12
  507.          BE_read_float16(ifile); // 16
  508.          BE_read_float16(ifile);
  509.          BE_read_float16(ifile); // 20
  510.          BE_read_float16(ifile);
  511.          BE_read_float16(ifile); // 24
  512.          BE_read_float16(ifile);
  513.          BE_read_float16(ifile); // 28
  514.          BE_read_float16(ifile);
  515.          BE_read_float16(ifile); // 32
  516.          BE_read_float16(ifile);
  517.          vb.data[i].tu = BE_read_float16(ifile); // 36
  518.          vb.data[i].tv = 1.0f - BE_read_float16(ifile);
  519.         }
  520.        else {
  521.          cout << u01 << "," << u02 << endl;
  522.          return error("Unknown vertex format.");
  523.         }
  524.      }
  525.  
  526.   // finish model properties
  527.   stringstream ss;
  528.   ss << "surface_" << setfill('0') << setw(3) << curr_model;
  529.   ib.name = ss.str();
  530.   ib.reference = curr_model;
  531.  
  532.   // insert model data
  533.   curr_vd.push_back(vb);
  534.   curr_fd.push_back(ib);
  535.  
  536.   // increment model number
  537.   curr_model++;
  538.   return true;
  539.  }
  540.  
  541. };}; // PS3::MacrossFrontier
  542.  
  543. namespace PS3 { namespace MacrossFrontier {
  544.  
  545. bool extract(void)
  546. {
  547.  char pathname[MAX_PATH];
  548.  GetModulePathname(pathname, MAX_PATH);
  549.  return extract(pathname);
  550. }
  551.  
  552. bool extract(const char* pathname)
  553. {
  554.  return extractor(pathname).extract();
  555. }
  556.  
  557. };}; // PS3::MacrossFrontier