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

  1. #include "xentax.h"
  2. #include "ps3_ni_no_kuni.h"
  3.  
  4. namespace PS3 { namespace NiNoKuni {
  5.  
  6. class extractor {
  7.  private :
  8.   std::string pathname;
  9.   std::deque<std::string> arclist;
  10.   std::deque<std::string> datlist;
  11.   std::deque<std::string> hpklist;
  12.   std::deque<std::string> pkclist;
  13.   std::deque<std::string> ipklist;
  14.   std::deque<std::string> imglist;
  15.  private :
  16.   bool process001(void);
  17.   bool process002(void);
  18.   bool process003(void);
  19.   bool process004(void);
  20.   bool process005(void);
  21.   bool process006(void);
  22.   bool processGVEWJPEG(ifstream& ifile, const char* path, const char* name);
  23.   bool processGVEWGVMP(ifstream& ifile, const char* path, const char* name);
  24.  public :
  25.   bool extract(void);
  26.   void clear(void);
  27.  public :
  28.   extractor(const char* path);
  29.  ~extractor();
  30. };
  31.  
  32. extractor::extractor(const char* path) : pathname(path)
  33. {
  34. }
  35.  
  36. extractor::~extractor()
  37. {
  38. }
  39.  
  40. bool extractor::extract(void)
  41. {
  42.  // clear previous
  43.  clear();
  44.  
  45.  // find all dat files
  46.  cout << "----------" << endl;
  47.  cout << " PHASE #1 " << endl;
  48.  cout << "----------" << endl;
  49.  cout << "Searching for dat files." << endl;
  50.  BuildFilenameList(datlist, "dat", pathname.c_str());
  51.  cout << "Found " << datlist.size() << " dat files." << endl;
  52.  if(datlist.size()) { if(!process001()) return false; }
  53.  cout << endl;
  54.  
  55.  // find all arc files
  56.  cout << "----------" << endl;
  57.  cout << " PHASE #2 " << endl;
  58.  cout << "----------" << endl;
  59.  cout << "Searching for arc files." << endl;
  60.  BuildFilenameList(arclist, "zarc", pathname.c_str());
  61.  cout << "Found " << arclist.size() << " arc files." << endl;
  62.  if(arclist.size()) { if(!process002()) return false; }
  63.  cout << endl;
  64.  
  65.  // find all hpk files
  66.  cout << "----------" << endl;
  67.  cout << " PHASE #3 " << endl;
  68.  cout << "----------" << endl;
  69.  cout << "Searching for hpk files." << endl;
  70.  BuildFilenameList(hpklist, "hpk", pathname.c_str());
  71.  cout << "Found " << hpklist.size() << " hpk files." << endl;
  72.  if(hpklist.size()) { if(!process003()) return false; }
  73.  cout << endl;
  74.  
  75.  // find all pkchr files
  76.  cout << "----------" << endl;
  77.  cout << " PHASE #4 " << endl;
  78.  cout << "----------" << endl;
  79.  cout << "Searching for pkchr files." << endl;
  80.  BuildFilenameList(pkclist, "pkchr", pathname.c_str());
  81.  cout << "Found " << pkclist.size() << " pkchr files." << endl;
  82.  if(pkclist.size()) { if(!process004()) return false; }
  83.  cout << endl;
  84.  
  85.  // find all imgpak files
  86.  cout << "----------" << endl;
  87.  cout << " PHASE #5 " << endl;
  88.  cout << "----------" << endl;
  89.  cout << "Searching for imgpak files." << endl;
  90.  BuildFilenameList(ipklist, "imgpak", pathname.c_str());
  91.  cout << "Found " << ipklist.size() << " imgpak files." << endl;
  92.  if(ipklist.size()) { if(!process005()) return false; }
  93.  cout << endl;
  94.  
  95.  // find all img files
  96.  cout << "----------" << endl;
  97.  cout << " PHASE #6 " << endl;
  98.  cout << "----------" << endl;
  99.  cout << "Searching for img files." << endl;
  100.  BuildFilenameList(imglist, "img", pathname.c_str());
  101.  cout << "Found " << imglist.size() << " img files." << endl;
  102.  if(imglist.size()) { if(!process006()) return false; }
  103.  cout << endl;
  104.  
  105.  return true;
  106. }
  107.  
  108. bool extractor::process001(void)
  109. {
  110.  struct entry {
  111.   uint32 p1;
  112.   uint32 p2;
  113.   uint32 p3;
  114.   uint32 p4;
  115.   std::string name;
  116.  };
  117.  
  118.  for(size_t i = 0; i < datlist.size(); i++)
  119.     {
  120.      // open file
  121.      ifstream ifile(datlist[i].c_str(), ios::binary);
  122.      if(!ifile) return error("Could not open DAT file.");
  123.  
  124.      uint32 tgdt = BE_read_uint32(ifile);
  125.      if(tgdt != 0x54474454) continue;
  126.  
  127.      uint32 vers = BE_read_uint32(ifile);
  128.      if(vers != 0x30313030) continue;
  129.  
  130.      uint32 entries = BE_read_uint32(ifile);
  131.      uint32 start_offset = BE_read_uint32(ifile);
  132.  
  133.      std::deque<entry> entrylist;
  134.      for(size_t j = 0; j < entries; j++)
  135.         {
  136.          entry e;
  137.          e.p1 = BE_read_uint32(ifile);
  138.          e.p2 = BE_read_uint32(ifile);
  139.          e.p3 = BE_read_uint32(ifile); // offset to data section, from start offset
  140.          e.p4 = BE_read_uint32(ifile); // size of actual data section, padding may follow
  141.          entrylist.push_back(e);
  142.         }
  143.      cout << "Found " << entrylist.size() << " entries." << endl;
  144.  
  145.      // process entries names
  146.      for(size_t j = 0; j < entries; j++)
  147.         {
  148.          // move to name
  149.          ifile.seekg(start_offset + entrylist[j].p1);
  150.          if(ifile.fail()) return error("Failed to seek offset.");
  151.  
  152.          // extract name
  153.          char name[1024];
  154.          LE_read_array(ifile, &name[0], 1024);
  155.          entrylist[j].name = name;
  156.         }
  157.  
  158.      // process entries
  159.      for(size_t j = 0; j < entries; j++)
  160.         {
  161.          // move to data
  162.          ifile.seekg(start_offset + entrylist[j].p3);
  163.          if(ifile.fail()) return error("Failed to seek offset.");
  164.  
  165.          // read magic number #1
  166.          uint64 magic1 = BE_read_uint64(ifile);
  167.          if(magic1 != 0x4756455730313030) return error("Expecting GVEW0100.");
  168.  
  169.          // read magic number #2
  170.          uint64 magic2 = BE_read_uint64(ifile);
  171.          if(magic2 == 0x4A50454730313030) {
  172.             std::string path = GetPathnameFromFilename(datlist[i]);
  173.             if(!processGVEWJPEG(ifile, path.c_str(), entrylist[j].name.c_str())) return false;
  174.            }
  175.          else if(magic2 == 0x47564D5030313030) {
  176.             std::string path = GetPathnameFromFilename(datlist[i]);
  177.             if(!processGVEWGVMP(ifile, path.c_str(), entrylist[j].name.c_str())) return false;
  178.            }
  179.          else return error("Unknown entry type.");
  180.         }
  181.  
  182.      // delete DAT file
  183.      //ifile.close();
  184.      //DeleteFileA(datlist[i].c_str());
  185.     }
  186.  
  187.  return true;
  188. }
  189.  
  190. bool extractor::process002(void)
  191. {
  192.  struct zarcentry {
  193.   uint16 p1; // amount of zlib data to read
  194.   uint16 p2; // ?
  195.   uint32 p3; // zlib offset + 1
  196.  };
  197.  
  198.  for(size_t i = 0; i < arclist.size(); i++)
  199.     {
  200.      // open file
  201.      ifstream ifile(arclist[i].c_str(), ios::binary);
  202.      if(!ifile) return error("Could not open ZARC file.");
  203.  
  204.      // read magic
  205.      uint32 zarc = BE_read_uint32(ifile);
  206.      if(zarc != 0x7A617263) return error("Invalid ZARC file.");
  207.      uint32 vers = BE_read_uint16(ifile);
  208.      uint32 n_streams = BE_read_uint16(ifile);
  209.      BE_read_uint32(ifile);
  210.      BE_read_uint32(ifile);
  211.  
  212.      // create output file
  213.      std::string path = GetPathnameFromFilename(arclist[i]);
  214.      std::string short_name = GetShortFilenameWithoutExtension(arclist[i]);
  215.      stringstream fname;
  216.      fname << path.c_str() << short_name.c_str();
  217.  
  218.      // create file
  219.      cout << "Processing " << fname.str() << "." << endl;
  220.      ofstream ofile(fname.str().c_str(), ios::binary);
  221.      if(!ofile) return error("Failed to create output file.");
  222.  
  223.      // read entries
  224.      std::deque<zarcentry> entries;
  225.      for(size_t j = 0; j < n_streams; j++) {
  226.          zarcentry e;
  227.          e.p1 = BE_read_uint16(ifile);
  228.          e.p2 = BE_read_uint16(ifile);
  229.          e.p3 = BE_read_uint32(ifile);
  230.          entries.push_back(e);
  231.         }
  232.  
  233.      // read streams
  234.      for(size_t j = 0; j < entries.size(); j++) {
  235.          ifile.seekg(entries[j].p3 - 1);
  236.          if(!DecompressZLIB(ifile, entries[j].p1, ofile, -15)) return false;
  237.         }
  238.  
  239.      // delete ZARC file
  240.      //ifile.close();
  241.      //DeleteFileA(arclist[i].c_str());
  242.     }
  243.  
  244.  return true;
  245. }
  246.  
  247. bool extractor::process003(void)
  248. {
  249.  for(size_t i = 0; i < hpklist.size(); i++)
  250.     {
  251.      // open file
  252.      cout << "Processing " << hpklist[i].c_str() << "." << endl;
  253.      ifstream ifile(hpklist[i].c_str(), ios::binary);
  254.      if(!ifile) return error("Could not open HPK file.");
  255.  
  256.      // read magic
  257.      uint32 magic = BE_read_uint32(ifile);
  258.      if(magic != 0x30315048) return error("Expecting 01PH.");
  259.  
  260.      // read number of files
  261.      uint32 n_files = BE_read_uint32(ifile);
  262.  
  263.      // read filesize
  264.      uint32 filesize = BE_read_uint32(ifile);
  265.  
  266.      // read size of section
  267.      uint32 sectionsize = BE_read_uint32(ifile);
  268.  
  269.      // read offset to filenames
  270.      uint32 fname_offset = BE_read_uint32(ifile);
  271.  
  272.      // read offset to next section (can be different types)
  273.      uint32 next_section = BE_read_uint32(ifile);
  274.  
  275.      // read unknowns
  276.      uint16 unk001 = BE_read_uint16(ifile); // size of info data (0x20)
  277.      uint16 unk002 = BE_read_uint16(ifile); // 0x10
  278.      uint32 unk003 = BE_read_uint32(ifile); // 0 or 1
  279.  
  280.      // read file information
  281.      struct FILEINFO { uint32 offset, filesize; };
  282.      std::deque<FILEINFO> sizelist;
  283.      for(size_t j = 0; j < n_files; j++) {
  284.          uint32 param001 = BE_read_uint32(ifile);
  285.          uint32 param002 = BE_read_uint32(ifile);
  286.          uint32 param003 = BE_read_uint32(ifile);
  287.          uint32 param004 = BE_read_uint32(ifile);
  288.          uint32 param005 = BE_read_uint32(ifile); // offset from next_section
  289.          uint32 param006 = BE_read_uint32(ifile); // filesize
  290.          uint32 param007 = BE_read_uint32(ifile);
  291.          uint32 param008 = BE_read_uint32(ifile);
  292.          FILEINFO info = { param005, param006 };
  293.          sizelist.push_back(info);
  294.         }
  295.  
  296.      // move to string offset
  297.      ifile.seekg(fname_offset);
  298.      if(ifile.fail()) return error("Seek failure.");
  299.  
  300.      // read short filenames
  301.      std::deque<std::string> filelist;
  302.      for(size_t j = 0; j < n_files; j++) {
  303.          char buffer[1024];
  304.          read_string(ifile, buffer, 1024);
  305.          if(ifile.fail()) return error("Read failure.");
  306.          filelist.push_back(GetShortFilename(buffer));
  307.         }
  308.  
  309.      // create directory to save files
  310.      std::string fname_param1 = GetPathnameFromFilename(hpklist[i]);
  311.      std::string fname_param2 = GetShortFilenameWithoutExtension(hpklist[i]);
  312.      stringstream dirname;
  313.      dirname << fname_param1 << fname_param2 << "\\";
  314.      CreateDirectoryA(dirname.str().c_str(), NULL);
  315.  
  316.      // save files
  317.      for(size_t j = 0; j < n_files; j++)
  318.         {
  319.          // move to data
  320.          ifile.seekg(next_section + sizelist[j].offset);
  321.          if(ifile.fail()) return error("Seek failure.");
  322.  
  323.          // create file
  324.          stringstream ofname;
  325.          ofname << dirname.str().c_str() << filelist[j].c_str();
  326.          ofstream ofile(ofname.str().c_str(), ios::binary);
  327.          if(!ofile) return error("Failed to create ouptut file.");
  328.  
  329.          // OK if document contains no data
  330.          if(!sizelist[j].filesize) continue;
  331.  
  332.          // read data
  333.          boost::shared_array<char> data(new char[sizelist[j].filesize]);
  334.          ifile.read(data.get(), sizelist[j].filesize);
  335.          if(ifile.fail()) return error("Read failure.");
  336.  
  337.          // save data
  338.          ofile.write(data.get(), sizelist[j].filesize);
  339.          if(ofile.fail()) return error("Write failure.");
  340.         }
  341.  
  342.      // delete HPK file
  343.      //ifile.close();
  344.      //DeleteFileA(hpklist[i].c_str());
  345.     }
  346.  
  347.  return true;
  348. }
  349.  
  350. bool extractor::process004(void)
  351. {
  352.  for(size_t i = 0; i < pkclist.size(); i++)
  353.     {
  354.      // open file
  355.      cout << "Processing " << pkclist[i].c_str() << "." << endl;
  356.      ifstream ifile(pkclist[i].c_str(), ios::binary);
  357.      if(!ifile) return error("Could not open PKCHR file.");
  358.  
  359.      // read magic
  360.      uint32 magic = BE_read_uint32(ifile);
  361.      if(magic != 0x30315048) return error("Expecting 01PH.");
  362.  
  363.      // read number of files
  364.      uint32 n_files = BE_read_uint32(ifile);
  365.  
  366.      // read filesize
  367.      uint32 filesize = BE_read_uint32(ifile);
  368.  
  369.      // read size of section
  370.      uint32 sectionsize = BE_read_uint32(ifile);
  371.  
  372.      // read offset to filenames
  373.      uint32 fname_offset = BE_read_uint32(ifile);
  374.  
  375.      // read offset to next section (can be different types)
  376.      uint32 next_section = BE_read_uint32(ifile);
  377.  
  378.      // read unknowns
  379.      uint16 unk001 = BE_read_uint16(ifile); // 0x20, 0x800
  380.      uint16 unk002 = BE_read_uint16(ifile); // 0x10, 0x800
  381.      uint32 unk003 = BE_read_uint32(ifile); // 0 or 1
  382.  
  383.      // read file information
  384.      struct FILEINFO { uint32 offset, filesize; };
  385.      std::deque<FILEINFO> sizelist;
  386.      for(size_t j = 0; j < n_files; j++) {
  387.          uint32 param001 = BE_read_uint32(ifile);
  388.          uint32 param002 = BE_read_uint32(ifile);
  389.          uint32 param003 = BE_read_uint32(ifile);
  390.          uint32 param004 = BE_read_uint32(ifile);
  391.          uint32 param005 = BE_read_uint32(ifile); // offset from next_section
  392.          uint32 param006 = BE_read_uint32(ifile); // filesize
  393.          uint32 param007 = BE_read_uint32(ifile);
  394.          uint32 param008 = BE_read_uint32(ifile);
  395.          FILEINFO info = { param005, param006 };
  396.          sizelist.push_back(info);
  397.         }
  398.  
  399.      // move to string offset
  400.      ifile.seekg(fname_offset);
  401.      if(ifile.fail()) return error("Seek failure.");
  402.  
  403.      // read short filenames
  404.      std::deque<std::string> filelist;
  405.      for(size_t j = 0; j < n_files; j++) {
  406.          char buffer[1024];
  407.          read_string(ifile, buffer, 1024);
  408.          if(ifile.fail()) return error("Read failure.");
  409.          filelist.push_back(GetShortFilename(buffer));
  410.         }
  411.  
  412.      // save files
  413.      std::string dirname = GetPathnameFromFilename(pkclist[i]);
  414.      for(size_t j = 0; j < n_files; j++)
  415.         {
  416.          // move to data
  417.          ifile.seekg(next_section + sizelist[j].offset);
  418.          if(ifile.fail()) return error("Seek failure.");
  419.  
  420.          // create file
  421.          stringstream ofname;
  422.          ofname << dirname.c_str() << filelist[j].c_str();
  423.          ofstream ofile(ofname.str().c_str(), ios::binary);
  424.          if(!ofile) return error("Failed to create ouptut file.");
  425.  
  426.          // OK if document contains no data
  427.          if(!sizelist[j].filesize) continue;
  428.  
  429.          // read data
  430.          boost::shared_array<char> data(new char[sizelist[j].filesize]);
  431.          ifile.read(data.get(), sizelist[j].filesize);
  432.          if(ifile.fail()) return error("Read failure.");
  433.  
  434.          // save data
  435.          ofile.write(data.get(), sizelist[j].filesize);
  436.          if(ofile.fail()) return error("Write failure.");
  437.         }
  438.  
  439.      // delete PKCHR file
  440.      //ifile.close();
  441.      //DeleteFileA(pkclist[i].c_str());
  442.     }
  443.  
  444.  return true;
  445. }
  446.  
  447. bool extractor::process005(void)
  448. {
  449.  for(size_t i = 0; i < ipklist.size(); i++)
  450.     {
  451.      // open file
  452.      cout << "Processing " << ipklist[i].c_str() << "." << endl;
  453.      ifstream ifile(ipklist[i].c_str(), ios::binary);
  454.      if(!ifile) return error("Could not open IMGPAK file.");
  455.  
  456.      // read magic
  457.      uint32 magic = BE_read_uint32(ifile);
  458.      if(magic != 0x30315048) return error("Expecting 01PH.");
  459.  
  460.      // read number of files
  461.      uint32 n_files = BE_read_uint32(ifile);
  462.  
  463.      // read filesize
  464.      uint32 filesize = BE_read_uint32(ifile);
  465.  
  466.      // read size of section
  467.      uint32 sectionsize = BE_read_uint32(ifile);
  468.  
  469.      // read offset to filenames
  470.      uint32 fname_offset = BE_read_uint32(ifile);
  471.  
  472.      // read offset to next section (can be different types)
  473.      uint32 next_section = BE_read_uint32(ifile);
  474.  
  475.      // read unknowns
  476.      uint16 unk001 = BE_read_uint16(ifile);
  477.      uint16 unk002 = BE_read_uint16(ifile);
  478.      uint32 unk003 = BE_read_uint32(ifile);
  479.  
  480.      // read file information
  481.      struct FILEINFO { uint32 offset, filesize; };
  482.      std::deque<FILEINFO> sizelist;
  483.      for(size_t j = 0; j < n_files; j++) {
  484.          uint32 param001 = BE_read_uint32(ifile);
  485.          uint32 param002 = BE_read_uint32(ifile);
  486.          uint32 param003 = BE_read_uint32(ifile);
  487.          uint32 param004 = BE_read_uint32(ifile);
  488.          uint32 param005 = BE_read_uint32(ifile); // offset from next_section
  489.          uint32 param006 = BE_read_uint32(ifile); // filesize
  490.          uint32 param007 = BE_read_uint32(ifile);
  491.          uint32 param008 = BE_read_uint32(ifile);
  492.          FILEINFO info = { param005, param006 };
  493.          sizelist.push_back(info);
  494.         }
  495.  
  496.      // move to string offset
  497.      ifile.seekg(fname_offset);
  498.      if(ifile.fail()) return error("Seek failure.");
  499.  
  500.      // read short filenames
  501.      std::deque<std::string> filelist;
  502.      for(size_t j = 0; j < n_files; j++) {
  503.          char buffer[1024];
  504.          read_string(ifile, buffer, 1024);
  505.          if(ifile.fail()) return error("Read failure.");
  506.          filelist.push_back(GetShortFilename(buffer));
  507.         }
  508.  
  509.      // save files
  510.      std::string dirname = GetPathnameFromFilename(ipklist[i]);
  511.      for(size_t j = 0; j < n_files; j++)
  512.         {
  513.          // move to data
  514.          ifile.seekg(next_section + sizelist[j].offset);
  515.          if(ifile.fail()) return error("Seek failure.");
  516.  
  517.          // create file
  518.          stringstream ofname;
  519.          ofname << dirname.c_str() << filelist[j].c_str();
  520.          ofstream ofile(ofname.str().c_str(), ios::binary);
  521.          if(!ofile) return error("Failed to create ouptut file.");
  522.  
  523.          // OK if document contains no data
  524.          if(!sizelist[j].filesize) continue;
  525.  
  526.          // read data
  527.          boost::shared_array<char> data(new char[sizelist[j].filesize]);
  528.          ifile.read(data.get(), sizelist[j].filesize);
  529.          if(ifile.fail()) return error("Read failure.");
  530.  
  531.          // save data
  532.          ofile.write(data.get(), sizelist[j].filesize);
  533.          if(ofile.fail()) return error("Write failure.");
  534.         }
  535.     }
  536.  
  537.  // delete ipklist
  538.  ipklist.clear();
  539.  return true;
  540. }
  541.  
  542. bool extractor::process006(void)
  543. {
  544.  for(size_t i = 0; i < imglist.size(); i++)
  545.     {
  546.      // open file
  547.      cout << "Processing " << imglist[i].c_str() << "." << endl;
  548.      ifstream ifile(imglist[i].c_str(), ios::binary);
  549.      if(!ifile) return error("Could not open IMG file.");
  550.  
  551.      // read magic
  552.      uint32 magic = BE_read_uint32(ifile);
  553.      if(magic != 0x494D3300) return error("Expecting IMG.");
  554.  
  555.      uint32 start = LE_read_uint32(ifile);
  556.  
  557.      // read number of images
  558.      uint32 n_images = LE_read_uint32(ifile);
  559.      if(!n_images) continue;
  560.  
  561.      // read strings
  562.      std::deque<std::string> names;
  563.      std::deque<size_t> sizes;
  564.      for(size_t j = 0; j < n_images; j++)
  565.         {
  566.          // move to string
  567.          uint32 position = start + j*0x40;
  568.          ifile.seekg(position);
  569.          if(ifile.fail()) return error("Seek failed.");
  570.  
  571.          // read string
  572.          char buffer[1024];
  573.          read_string(ifile, buffer, 1024);
  574.          if(ifile.fail()) return error("Read failed.");
  575.          names.push_back(string(buffer));
  576.  
  577.          // move to size
  578.          position += 0x34;
  579.          ifile.seekg(position);
  580.          if(ifile.fail()) return error("Seek failed.");
  581.  
  582.          // read size
  583.          uint32 size = LE_read_uint32(ifile);
  584.          if(ifile.fail()) return error("Read failed.");
  585.          sizes.push_back(size);
  586.         }
  587.  
  588.      // move to first image
  589.      uint32 position = start + n_images*0x40;
  590.      ifile.seekg(position);
  591.      if(ifile.fail()) return error("Seek failed.");
  592.  
  593.      // read images
  594.      std::string dirname = GetPathnameFromFilename(imglist[i]);
  595.      for(size_t j = 0; j < n_images; j++)
  596.         {
  597.          // read image
  598.          boost::shared_array<char> data(new char[sizes[j]]);
  599.          ifile.read(data.get(), sizes[j]);
  600.          if(ifile.fail()) return error("Read failed.");
  601.  
  602.          // skip image
  603.          if(!strcmpi(names[j].c_str(), "#texanime"))
  604.             continue;
  605.  
  606.          // save image
  607.          stringstream ofname;
  608.          ofname << dirname.c_str() << names[j].c_str() << ".dds";
  609.          cout << ofname.str() << endl;
  610.          ofstream ofile(ofname.str().c_str(), ios::binary);
  611.          if(!ofile) return error("Failed to create DDS file.");
  612.          ofile.write(data.get(), sizes[j]);
  613.         }
  614.  
  615.      // delete IMG file
  616.      //ifile.close();
  617.      //DeleteFileA(imglist[i].c_str());
  618.     }
  619.  
  620.  // delete image list
  621.  imglist.clear();
  622.  return true;
  623. }
  624.  
  625. bool extractor::processGVEWJPEG(ifstream& ifile, const char* path, const char* name)
  626. {
  627.  // create directory
  628.  stringstream ss;
  629.  ss << path << GetShortFilenameWithoutExtension(name).c_str() << "\\";
  630.  cout << ss.str().c_str() << endl;
  631.  CreateDirectoryA(ss.str().c_str(), NULL);
  632.  
  633.  // read two numbers
  634.  uint32 unk01 = BE_read_uint32(ifile);
  635.  uint32 unk02 = BE_read_uint32(ifile);
  636.  
  637.  // read 1st block header
  638.  uint32 block1_param1 = BE_read_uint32(ifile); if(block1_param1 != 0x424C4B5F) return error("Expecting GVEW block.");
  639.  uint32 block1_param2 = BE_read_uint32(ifile);
  640.  uint32 block1_param3 = BE_read_uint32(ifile);
  641.  uint32 block1_param4 = BE_read_uint32(ifile);
  642.  uint32 block1_param5 = BE_read_uint32(ifile);
  643.  uint32 block1_param6 = BE_read_uint32(ifile);
  644.  
  645.  // read 1st block data
  646.  uint32 n_items = (block1_param2 - 8)/32;
  647.  std::deque<uint32> size_list;
  648.   for(uint32 i = 0; i < n_items; i++) {
  649.       uint32 items[8];
  650.       BE_read_array(ifile, &items[0], 8);
  651.       size_list.push_back(items[3]);
  652.      }
  653.  
  654.  // read next block
  655.  uint32 block2_param1 = BE_read_uint32(ifile);
  656.  uint32 block2_param2 = BE_read_uint32(ifile);
  657.  uint32 block2_param3 = BE_read_uint32(ifile);
  658.  uint32 block2_param4 = BE_read_uint32(ifile);
  659.  
  660.  // read JPEG files
  661.  for(uint32 i = 0; i < n_items; i++)
  662.     {
  663.      stringstream fname;
  664.      fname << ss.str().c_str() << setfill('0') << setw(4) << i << ".jpg";
  665.      ofstream ofile(fname.str().c_str(), ios::binary);
  666.      if(!ofile) return error("");
  667.  
  668.      boost::shared_array<char> data(new char[size_list[i]]);
  669.      ifile.read(data.get(), size_list[i]);
  670.      if(ifile.fail()) return error("Read failure.");
  671.      ofile.write(data.get(), size_list[i]);
  672.  
  673.      uint32 position = (uint32)ifile.tellg();
  674.      position = ((position + 0xF) & ~(0xF));
  675.      ifile.seekg(position);
  676.     }
  677.  
  678.  return true;
  679. }
  680.  
  681. bool extractor::processGVEWGVMP(ifstream& ifile, const char* path, const char* name)
  682. {
  683.  // create directory
  684.  stringstream ss;
  685.  ss << path << GetShortFilenameWithoutExtension(name).c_str() << "\\";
  686.  cout << ss.str().c_str() << endl;
  687.  CreateDirectoryA(ss.str().c_str(), NULL);
  688.  
  689.  // read two numbers
  690.  uint32 unk01 = BE_read_uint32(ifile);
  691.  uint32 unk02 = BE_read_uint32(ifile);
  692.  
  693.  // read 1st block header
  694.  uint32 block1_param1 = BE_read_uint32(ifile); if(block1_param1 != 0x424C4B5F) return error("Expecting GVEW block.");
  695.  uint32 block1_param2 = BE_read_uint32(ifile);
  696.  uint32 block1_param3 = BE_read_uint32(ifile);
  697.  uint32 block1_param4 = BE_read_uint32(ifile);
  698.  uint32 block1_param5 = BE_read_uint32(ifile);
  699.  uint32 block1_param6 = BE_read_uint32(ifile);
  700.  
  701.  // read 1st block data
  702.  uint32 n_items = (block1_param2 - 8)/32;
  703.  std::deque<uint32> size_list;
  704.   for(uint32 i = 0; i < n_items; i++) {
  705.       uint32 items[8];
  706.       BE_read_array(ifile, &items[0], 8);
  707.       size_list.push_back(items[3]);
  708.      }
  709.  
  710.  // read 2nd block header
  711.  uint32 block2_param1 = BE_read_uint32(ifile);
  712.  uint32 block2_param2 = BE_read_uint32(ifile);
  713.  uint32 block2_param3 = BE_read_uint32(ifile);
  714.  uint32 block2_param4 = BE_read_uint32(ifile);
  715.  
  716.  // read 2nd block data
  717.  for(uint32 i = 0; i < n_items; i++)
  718.     {
  719.      uint32 gvmp_param1 = BE_read_uint32(ifile);
  720.      uint32 gvmp_param2 = BE_read_uint32(ifile);
  721.      uint32 gvmp_param3 = BE_read_uint32(ifile);
  722.      uint32 gvmp_param4 = BE_read_uint32(ifile);
  723.      uint32 gvmp_param5 = BE_read_uint32(ifile);
  724.      uint32 gvmp_param6 = BE_read_uint32(ifile);
  725.      uint32 gvmp_param7 = BE_read_uint32(ifile);
  726.      uint32 gvmp_param8 = BE_read_uint32(ifile);
  727.  
  728.      stringstream fname;
  729.      fname << ss.str().c_str() << setfill('0') << setw(4) << i << "_a.jpg";
  730.      ofstream ofile(fname.str().c_str(), ios::binary);
  731.      if(!ofile) return error("Error creating output file.");
  732.  
  733.      uint32 datasize = gvmp_param4;
  734.      boost::shared_array<char> data(new char[datasize]);
  735.      ifile.read(data.get(), datasize);
  736.      if(ifile.fail()) return error("Read failure.");
  737.      ofile.write(data.get(), datasize);
  738.  
  739.      uint32 position = (uint32)ifile.tellg();
  740.      position = ((position + 0xF) & ~(0xF));
  741.      ifile.seekg(position);
  742.  
  743.      if(gvmp_param3 != gvmp_param5)
  744.        {
  745.         stringstream fname;
  746.         fname << ss.str().c_str() << setfill('0') << setw(4) << i << "_b.jpg";
  747.         ofstream ofile(fname.str().c_str(), ios::binary);
  748.         if(!ofile) return error("");
  749.         
  750.         uint32 datasize = gvmp_param6;
  751.         boost::shared_array<char> data(new char[datasize]);
  752.         ifile.read(data.get(), datasize);
  753.         if(ifile.fail()) return error("Read failure.");
  754.         ofile.write(data.get(), datasize);
  755.         
  756.         uint32 position = (uint32)ifile.tellg();
  757.         position = ((position + 0xF) & ~(0xF));
  758.         ifile.seekg(position);
  759.        }
  760.     }
  761.  
  762.  return true;
  763. }
  764.  
  765. void extractor::clear(void)
  766. {
  767.  arclist.clear();
  768.  datlist.clear();
  769. }
  770.  
  771. };};
  772.  
  773. namespace PS3 { namespace NiNoKuni {
  774.  
  775. bool extract(void)
  776. {
  777.  char pathname[MAX_PATH];
  778.  GetModulePathname(pathname, MAX_PATH);
  779.  return extract(pathname);
  780. }
  781.  
  782. bool extract(const char* pathname)
  783. {
  784.  return extractor(pathname).extract();
  785. }
  786.  
  787. };};