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

  1. #include "xentax.h"
  2. #include "psp_heroes_phantasia.h"
  3.  
  4. namespace PSP { namespace HeroesOfPhantasia {
  5.  
  6.  class extractor {
  7.   private :
  8.    std::string pathname;
  9.   private :
  10.    bool processPSARC(const char* fullname);
  11.    bool processTEXTURES(const char* fullname);
  12.    bool CreatePaths(const char* root, const char* path);
  13.   public :
  14.    bool extract(void);
  15.   public :
  16.    extractor(const char* pn);
  17.   ~extractor();
  18.  };
  19.  
  20. };};
  21.  
  22. namespace PSP { namespace HeroesOfPhantasia {
  23.  
  24. extractor::extractor(const char* pn) : pathname(pn)
  25. {
  26. }
  27.  
  28. extractor::~extractor()
  29. {
  30. }
  31.  
  32. bool extractor::CreatePaths(const char* root, const char* path)
  33. {
  34.  // check string properties
  35.  if(!path) return false;
  36.  uint32 elem = strlen(path);
  37.  if(!elem) return false;
  38.  
  39.  // parse directories
  40.  std::deque<std::string> list;
  41.  std::string temp;     
  42.  for(size_t i = 0; i < elem; i++) {
  43.      if(path[i] == '\\' || path[i] == '/') {
  44.         if(temp.length()) {
  45.            list.push_back(temp);
  46.            temp.clear();
  47.           }
  48.        }
  49.      else
  50.         temp += path[i];
  51.     }
  52.  
  53.  // create directories
  54.  std::string curr_path = root;
  55.  for(size_t i = 0; i < list.size(); i++) {
  56.      curr_path += list[i];
  57.      curr_path += "\\";
  58.      CreateDirectoryA(curr_path.c_str(), NULL);
  59.     }
  60.       
  61.  return true;
  62. }
  63.  
  64. bool extractor::extract(void)
  65. {
  66.  using namespace std;
  67.  
  68.  cout << "STAGE 1" << endl;
  69.  cout << "Processing PSARC files..." << endl;
  70.  deque<string> filelist;
  71.  BuildFilenameList(filelist, "psarc", pathname.c_str());
  72.  for(size_t i = 0; i < filelist.size(); i++) {
  73.      cout << "Processing file " << (i + 1) << " of " << filelist.size() << ": " << filelist[i] << "." << endl;
  74.      if(!processPSARC(filelist[i].c_str())) return false;
  75.     }
  76.  cout << endl;
  77.  
  78.  cout << "STAGE 2" << endl;
  79.  cout << "Processing PS3_TEXTURES files..." << endl;
  80.  filelist.clear();
  81.  BuildFilenameList(filelist, "PS3_TEXTURES", pathname.c_str());
  82.  for(size_t i = 0; i < filelist.size(); i++) {
  83.      cout << "Processing file " << (i + 1) << " of " << filelist.size() << ": " << filelist[i] << "." << endl;
  84.      if(!processTEXTURES(filelist[i].c_str())) return false;
  85.     }
  86.  cout << endl;
  87.  
  88.  return true;
  89. }
  90.  
  91. bool extractor::processPSARC(const char* fullname)
  92. {
  93.  string filepath = GetPathnameFromFilename(fullname);
  94.  string filename = GetShortFilenameWithoutExtension(fullname);
  95.  
  96.  // open file
  97.  ifstream ifile(fullname, ios::binary);
  98.  if(!ifile) return error("Could not open PSARC file.");
  99.  
  100.  // compute filesize
  101.  ifile.seekg(0, ios::end);
  102.  uint32 filesize = (uint32)ifile.tellg();
  103.  ifile.seekg(0, ios::beg);
  104.  
  105.  // read magic
  106.  uint32 magic = BE_read_uint32(ifile);
  107.  if(magic != 0x50534152) return error("Invalid PSARC file.");
  108.  
  109.  // read unknowns
  110.  uint16 unk01 = BE_read_uint16(ifile);
  111.  uint16 unk02 = BE_read_uint16(ifile);
  112.  
  113.  // read zlib
  114.  uint32 zlib = BE_read_uint32(ifile);
  115.  if(zlib != 0x7A6C6962) return error("Expecting zlib.");
  116.  
  117.  // read offset
  118.  uint32 offset = BE_read_uint32(ifile);
  119.  if(offset == 0) return error("Expecting zlib offset.");
  120.  
  121.  // read size of filename
  122.  ifile.seekg(0x38);
  123.  uint32 elem = BE_read_uint08(ifile);
  124.  if(elem == 0) return error("Invalid filename length.");
  125.  
  126.  // read name
  127.  char name[256];
  128.  ifile.read(&name[0], elem);
  129.  name[elem] = '\0';
  130.  
  131.  // build output file
  132.  stringstream ss;
  133.  ss << filepath << filename << ".arc";
  134.  
  135.  // create ouput file
  136.  ofstream ofile(ss.str(), ios::binary);
  137.  if(!ofile) return error("Failed to create output file.");
  138.  
  139.  // decompress data
  140.  ifile.seekg(offset + elem);
  141.  if(!DecompressZLIB(ifile, ofile)) return false;
  142.  
  143.  // display warning if leftover data
  144.  if((filesize - ifile.tellg()) > 1024)
  145.     cout << "Warning... more data!" << endl;
  146.  
  147.  return true;
  148. }
  149.  
  150. bool extractor::processTEXTURES(const char* fullname)
  151. {
  152.  string filepath = GetPathnameFromFilename(fullname);
  153.  string filename = GetShortFilenameWithoutExtension(fullname);
  154.  
  155.  // open file
  156.  ifstream ifile(fullname, ios::binary);
  157.  if(!ifile) return error("Could not open PS3_TEXTURES file.");
  158.  
  159.  // compute filesize
  160.  ifile.seekg(0, ios::end);
  161.  uint32 filesize = (uint32)ifile.tellg();
  162.  ifile.seekg(0, ios::beg);
  163.  if(filesize == 0) return true;
  164.  
  165.  // read magic
  166.  uint64 magic = BE_read_uint64(ifile);
  167.  if(magic != 0x4173757261202020) return error("Invalid PSARC file.");
  168.  
  169.  // read textures
  170.  for(;;)
  171.     {
  172.      // save position
  173.      uint32 position = (uint32)ifile.tellg();
  174.      if(ifile.fail() || ifile.eof()) return true;
  175.  
  176.      // read FCSR
  177.      uint32 param01 = BE_read_uint32(ifile);
  178.      if(ifile.fail() || ifile.eof()) return true;
  179.      if(param01 == 0x00000000) return true;
  180.      if(param01 != 0x46435352) return error("Expecting FCSR.");
  181.  
  182.      uint32 param02 = BE_read_uint32(ifile);
  183.      uint32 param03 = BE_read_uint32(ifile);
  184.      uint32 param04 = BE_read_uint32(ifile);
  185.      uint32 param05 = BE_read_uint32(ifile);
  186.      uint32 param06 = BE_read_uint32(ifile);
  187.      uint32 param07 = BE_read_uint32(ifile);
  188.  
  189.      char relname[1024];
  190.      read_string(ifile, &relname[0], 1024);
  191.      cout << "name = " << relname << endl;
  192.  
  193.      // take difference between param02 and param07
  194.      if(param02 < param07) return error("Expecting distance to be positive.");
  195.      uint32 distance = param02 - param07;
  196.      ifile.seekg(position + distance);
  197.  
  198.      CreatePaths(filepath.c_str(), relname);
  199.  
  200.      stringstream ss;
  201.      ss << filepath << relname;
  202.      ofstream ofile(ss.str(), ios::binary);
  203.      if(!ofile) return error("Failed to create output file.");
  204.  
  205.      boost::shared_array<char> data(new char[param07]);
  206.      ifile.read(data.get(), param07);
  207.      ofile.write(data.get(), param07);
  208.     }
  209.  
  210.  return true;
  211. }
  212.  
  213. };};
  214.  
  215. namespace PSP { namespace HeroesOfPhantasia {
  216.  
  217. bool extract(void)
  218. {
  219.  char pathname[MAX_PATH];
  220.  GetModulePathname(pathname, MAX_PATH);
  221.  return extract(pathname);
  222. }
  223.  
  224. bool extract(const char* pathname)
  225. {
  226.  return extractor(pathname).extract();
  227. }
  228.  
  229. };};