home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 5257 / source.7z / xb360_gundam3.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2011-12-17  |  82.3 KB  |  2,071 lines

  1. #include "xb360_gundam3.h"
  2.  
  3. struct G1MG0044_HEADER {
  4.  uint32 platform;
  5.  uint32 unknown1;
  6.  float32 bbox_min[3];
  7.  float32 bbox_max[3];
  8.  uint32 sections;
  9. };
  10.  
  11. struct G1MG0044_ITEMDATA {
  12.  uint32 type;
  13.  uint32 size;
  14.  boost::shared_array<char> data;
  15. };
  16.  
  17. struct G1MG0044_VERTEXDATA {
  18.  uint32 unknown1;
  19.  uint32 vertsize;
  20.  uint32 vertices;
  21.  uint32 unknown2;
  22. };
  23.  
  24. struct G1MG0044_FACEDATA {
  25.  uint32 numindex;
  26.  uint32 datatype;
  27.  uint32 unknown1;
  28. };
  29.  
  30. bool XB360ExtractMDLGundam3(ifstream& ifile, const deque<size_t>& list);
  31. bool XB360Gundam3_G1MG0044(ifstream& ifile, uint32 model);
  32. bool XB360Gundam3_G1MF0021(ifstream& ifile);
  33.  
  34. bool XB360Gundam3_G1MG0044(ifstream& ifile, uint32 index)
  35. {
  36.  // read magic
  37.  uint64 magic = BE_read_uint64(ifile); 
  38.  if(magic != 0x47314D4730303434) return error("Expecting G1MG0044.");
  39.  
  40.  // read size
  41.  uint32 datasize = BE_read_uint32(ifile); 
  42.  if(!datasize) return error("Unexpected G1MG0044 datasize.");
  43.  
  44.  // read header
  45.  G1MG0044_HEADER head;
  46.  head.platform = BE_read_uint32(ifile);
  47.  head.unknown1 = BE_read_uint32(ifile);
  48.  BE_read_array(ifile, &head.bbox_min[0], 3);
  49.  BE_read_array(ifile, &head.bbox_max[0], 3);
  50.  head.sections = BE_read_uint32(ifile);
  51.  
  52.  // read sections
  53.  deque<G1MG0044_ITEMDATA> itemdata;
  54.  for(size_t i = 0; i < head.sections; i++) {
  55.      G1MG0044_ITEMDATA item;
  56.      item.type = BE_read_uint32(ifile);
  57.      item.size = BE_read_uint32(ifile);
  58.      item.data.reset(new char[item.size - 0x8]);
  59.      ifile.read(item.data.get(), item.size - 0x8);
  60.      itemdata.push_back(item);
  61.     }
  62.  
  63.  deque<VERTEX_BUFFER> vdlist;
  64.  deque<INDEX_BUFFER> fdlist;
  65.  
  66.  // for each section
  67.  for(size_t i = 0; i < itemdata.size(); i++)
  68.     {
  69.      // vertex section
  70.      if(itemdata[i].type == 0x00010004)
  71.        {
  72.         // stringstream from data
  73.         stringstream ss(ios_base::out | ios_base::in | ios_base::binary);
  74.         ss.write(itemdata[i].data.get(), itemdata[i].size - 0x8);
  75.         ss.seekg(0);
  76.  
  77.         // read vertex sections
  78.         uint32 n_meshes = BE_read_uint32(ss);
  79.         for(size_t j = 0; j < n_meshes; j++)
  80.            {
  81.             // read mesh vertex info
  82.             G1MG0044_VERTEXDATA vd;
  83.             vd.unknown1 = BE_read_uint32(ss);
  84.             vd.vertsize = BE_read_uint32(ss);
  85.             vd.vertices = BE_read_uint32(ss);
  86.             vd.unknown2 = BE_read_uint32(ss);
  87.  
  88.             // set vertex buffer properties
  89.             VERTEX_BUFFER vb;
  90.             vb.elem = vd.vertices;
  91.             vb.flags = 0;
  92.             vb.data.reset(new VERTEX[vd.vertices]);
  93.  
  94.             // set vertex buffer flags
  95.             if(vd.vertsize == 0x10) {
  96.                vb.flags |= VERTEX_POSITION;
  97.                vb.flags |= VERTEX_NORMAL;
  98.                vb.flags |= VERTEX_UV;
  99.               }
  100.             else if(vd.vertsize == 0x14) {
  101.                vb.flags |= VERTEX_POSITION;
  102.                vb.flags |= VERTEX_NORMAL;
  103.                vb.flags |= VERTEX_UV;
  104.               }
  105.             else if(vd.vertsize == 0x18) {
  106.                vb.flags |= VERTEX_POSITION;
  107.                vb.flags |= VERTEX_NORMAL;
  108.               }
  109.             else if(vd.vertsize == 0x1C) {
  110.                vb.flags |= VERTEX_POSITION;
  111.                vb.flags |= VERTEX_NORMAL;
  112.                vb.flags |= VERTEX_UV;
  113.               }
  114.             else if(vd.vertsize == 0x20) {
  115.                vb.flags |= VERTEX_POSITION;
  116.                vb.flags |= VERTEX_NORMAL;
  117.                vb.flags |= VERTEX_UV;
  118.               }
  119.             else if(vd.vertsize == 0x24) {
  120.                vb.flags |= VERTEX_POSITION;
  121.                vb.flags |= VERTEX_NORMAL;
  122.                vb.flags |= VERTEX_UV;
  123.               }
  124.             else
  125.                return error("Unknown vertex format.");
  126.  
  127.             // read vertices
  128.             for(size_t k = 0; k < vd.vertices; k++)
  129.                {
  130.                 VERTEX vertex;
  131.                 if(vd.vertsize == 0x10) {
  132.                    vertex.vx = BE_read_float16(ss);
  133.                    vertex.vy = BE_read_float16(ss);
  134.                    vertex.vz = BE_read_float16(ss);
  135.                    BE_read_float16(ss);
  136.                    vertex.nx = BE_read_float16(ss);
  137.                    vertex.ny = BE_read_float16(ss);
  138.                    vertex.nz = BE_read_float16(ss);
  139.                    BE_read_float16(ss);
  140.                   }
  141.                 else if(vd.vertsize == 0x14) {
  142.                    vertex.vx = BE_read_float16(ss);
  143.                    vertex.vy = BE_read_float16(ss);
  144.                    vertex.vz = BE_read_float16(ss);
  145.                    BE_read_float16(ss);
  146.                    vertex.nx = BE_read_float16(ss);
  147.                    vertex.ny = BE_read_float16(ss);
  148.                    vertex.nz = BE_read_float16(ss);
  149.                    BE_read_float16(ss);
  150.                    vertex.tu = BE_read_float16(ss);
  151.                    vertex.tv = BE_read_float16(ss);
  152.                   }
  153.                 else if(vd.vertsize == 0x18) {
  154.                    vertex.vx = BE_read_float32(ss);
  155.                    vertex.vy = BE_read_float32(ss);
  156.                    vertex.vz = BE_read_float32(ss);
  157.                    vertex.nx = BE_read_float16(ss);
  158.                    vertex.ny = BE_read_float16(ss);
  159.                    vertex.nz = BE_read_float16(ss);
  160.                    BE_read_float16(ss);
  161.                    BE_read_float32(ss);
  162.                   }
  163.                 else if(vd.vertsize == 0x1C) {
  164.                    vertex.vx = BE_read_float32(ss);
  165.                    vertex.vy = BE_read_float32(ss);
  166.                    vertex.vz = BE_read_float32(ss);
  167.                    vertex.nx = BE_read_float16(ss);
  168.                    vertex.ny = BE_read_float16(ss);
  169.                    vertex.nz = BE_read_float16(ss);
  170.                    BE_read_float16(ss);
  171.                    BE_read_float32(ss);
  172.                    vertex.tu = BE_read_float16(ss);
  173.                    vertex.tv = BE_read_float16(ss);
  174.                   }
  175.                 else if(vd.vertsize == 0x20) {
  176.                    vertex.vx = BE_read_float32(ss);
  177.                    vertex.vy = BE_read_float32(ss);
  178.                    vertex.vz = BE_read_float32(ss);
  179.                    vertex.nx = BE_read_float16(ss);
  180.                    vertex.ny = BE_read_float16(ss);
  181.                    vertex.nz = BE_read_float16(ss);
  182.                    BE_read_float16(ss);
  183.                    BE_read_float32(ss);
  184.                    BE_read_float16(ss);
  185.                    BE_read_float16(ss);
  186.                    vertex.tu = BE_read_float16(ss);
  187.                    vertex.tv = BE_read_float16(ss);
  188.                   }
  189.                 else if(vd.vertsize == 0x24) {
  190.                    vertex.vx = BE_read_float32(ss);
  191.                    vertex.vy = BE_read_float32(ss);
  192.                    vertex.vz = BE_read_float32(ss);
  193.                    vertex.nx = BE_read_float32(ss);
  194.                    vertex.ny = BE_read_float32(ss);
  195.                    vertex.nz = BE_read_float32(ss);
  196.                    BE_read_float32(ss);
  197.                    vertex.tu = BE_read_float32(ss);
  198.                    vertex.tv = BE_read_float32(ss);
  199.                   }
  200.  
  201.                 // save vertex
  202.                 vb.data[k] = vertex;
  203.                }
  204.  
  205.             // save vertex data
  206.             cout << " vertices = " << vd.vertices << endl;
  207.             vdlist.push_back(vb);
  208.            }
  209.        }
  210.      // index buffer section
  211.      else if(itemdata[i].type == 0x00010007)
  212.        {
  213.         // stringstream from data
  214.         stringstream ss(ios_base::out | ios_base::in | ios_base::binary);
  215.         ss.write(itemdata[i].data.get(), itemdata[i].size - 0x8);
  216.         ss.seekg(0);
  217.  
  218.         // read face sections
  219.         uint32 n_meshes = BE_read_uint32(ss);
  220.         uint32 vb_index = 0;
  221.         for(size_t j = 0; j < n_meshes; j++)
  222.            {
  223.             // read face data
  224.             G1MG0044_FACEDATA fd;
  225.             fd.numindex = BE_read_uint32(ss);
  226.             fd.datatype = BE_read_uint32(ss);
  227.             fd.unknown1 = BE_read_uint32(ss);
  228.  
  229.             // set index buffer properties
  230.             INDEX_BUFFER ib;
  231.             ib.type = FACE_TYPE_TRISTRIP;
  232.             ib.elem = fd.numindex;
  233.             if(fd.datatype == 0x10) ib.format = FACE_FORMAT_UINT_16;
  234.             else if(fd.datatype == 0x20) ib.format = FACE_FORMAT_UINT_32;
  235.             else return error("Unknown index buffer data format.");
  236.  
  237.             // set index buffer name
  238.             stringstream surface;
  239.             surface << "CNS_G1MG_" << setfill('0') << setw(3) << index << "/" << setfill('0') << setw(3) << j << ends;
  240.             ib.name = surface.str();
  241.  
  242.             // determine index buffer data type size
  243.             unsigned int typesize = 0;
  244.             if(fd.datatype == 0x10) typesize = sizeof(uint16);
  245.             else if(fd.datatype == 0x20) typesize = sizeof(uint32);
  246.             else return error("Unknown index buffer data type.");
  247.  
  248.             // read face data
  249.             unsigned int total_bytes = ib.elem * typesize;
  250.             ib.data.reset(new char[total_bytes]);
  251.             if(ib.format == FACE_FORMAT_UINT_16) BE_read_array(ss, reinterpret_cast<uint16*>(ib.data.get()), ib.elem);
  252.             else if(ib.format == FACE_FORMAT_UINT_32) BE_read_array(ss, reinterpret_cast<uint32*>(ib.data.get()), ib.elem);
  253.  
  254.             // test face data
  255.             uint32 min_index = 0;
  256.             uint32 max_index = 0;
  257.             if(ib.format == FACE_FORMAT_UINT_16) {
  258.                uint16 a; minimum(reinterpret_cast<uint16*>(ib.data.get()), ib.elem, a);
  259.                uint16 b; maximum(reinterpret_cast<uint16*>(ib.data.get()), ib.elem, b);
  260.                min_index = a;
  261.                max_index = b;
  262.               }
  263.             else if(ib.format == FACE_FORMAT_UINT_32) {
  264.                uint32 a; minimum(reinterpret_cast<uint32*>(ib.data.get()), ib.elem, a);
  265.                uint32 b; maximum(reinterpret_cast<uint32*>(ib.data.get()), ib.elem, b);
  266.                min_index = a;
  267.                max_index = b;
  268.               }
  269.             cout << " min index = " << min_index << endl;
  270.             cout << " max index = " << max_index << endl;
  271.  
  272.             // set vertex buffer reference
  273.             if(min_index == 0) vb_index++;
  274.             if(vb_index > 0) ib.reference = vb_index - 1;
  275.             else return error("Unexpected vertex buffer reference.");
  276.  
  277.             // save face data
  278.             fdlist.push_back(ib);
  279.            }
  280.        }
  281.     }
  282.  
  283.  cout << " vertex data = " << vdlist.size() << endl;
  284.  cout << " face data = " << fdlist.size() << endl;
  285.  
  286.  // create filename
  287.  stringstream ofile;
  288.  ofile << setfill('0') << setw(4) << index << ends;
  289.  ofile << "CNS_G1MG_" << setfill('0') << setw(3) << index << ends;
  290.  
  291.  // save geometry
  292.  //if(!GeometryToOBJ(ofile.str().c_str(), vdlist, fdlist)) return false;
  293.  return true;
  294. }
  295.  
  296. namespace Xbox360 { namespace DynastyWarriorsGundam3 {
  297.  
  298. bool ExtractArchiveANS(void)
  299. {
  300.  cout << "Extracting ANS file." << endl;
  301.  ifstream ifile;
  302.  ifile.open("linkdata.ans", ios::binary);
  303.  if(!ifile) return error("Could not open file.");
  304.  
  305.  // read header
  306.  uint32 headMagic = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  307.  uint32 headFiles = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  308.  uint32 headScale = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  309.  uint32 headUnk01 = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  310.  
  311.  // validate header
  312.  if(headMagic != 0x1EDE) return error("Invalid header signature.");
  313.  if(headFiles >= 0xFFFF) return error("No dynasty warriors game contains this many files.");
  314.  if(headScale != 0x0800) return error("File assets should occur on 0x800 boundaries.");
  315.  
  316.  // read file table
  317.  deque<pair<uint32, uint32>> filetable;
  318.  for(size_t i = 0; i < headFiles; i++) {
  319.      pair<uint32, uint32> p;
  320.      p.first  = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  321.      p.second = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  322.      filetable.push_back(p);
  323.     }
  324.  
  325.  uint32 wave_count = 0;
  326.  uint32 astp_count = 0;
  327.  uint32 arch_count = 0;
  328.  
  329.  // for each item in the file table
  330.  for(size_t i = 0; i < filetable.size(); i++)
  331.     {
  332.      // move to file position
  333.      size_t position = filetable[i].first*headScale;
  334.      size_t filesize = filetable[i].second;
  335.      ifile.seekg(position);
  336.      if(ifile.fail()) return error("Failed to seek file position.");
  337.  
  338.      // read data
  339.      boost::shared_array<char> data(new char[filesize]);
  340.      ifile.read(data.get(), filesize);
  341.      if(ifile.fail()) return error("Read failure.");
  342.  
  343.      // save to stringstream
  344.      stringstream ss;
  345.      ss.write(data.get(), filesize);
  346.      if(ss.fail()) return error("Write to stringstream failure.");
  347.      
  348.      // read type of stringstream
  349.      uint32 type = BE_read_uint32(ss);
  350.      if(ifile.fail()) return error("Read failure.");
  351.  
  352.      // WAVE file
  353.      if(type == 0x52494646) {
  354.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (WAVE)." << endl;
  355.         stringstream name;
  356.         name << "ANS_" << setfill('0') << setw(4) << wave_count << ".wav" << ends;
  357.         ofstream ofile(name.str().c_str(), ios::binary);
  358.         if(!ofile) return error("Failed to create wave file.");
  359.         ofile.write(data.get(), filesize);
  360.         if(ofile.fail()) return error("Failed to write to wave file.");
  361.         wave_count++;
  362.        }
  363.      // ASTP file
  364.      else if(type == 0x41545350) {
  365.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (ASTP)." << endl;
  366.         stringstream name;
  367.         name << "ANS_" << setfill('0') << setw(4) << astp_count << ".astp" << ends;
  368.         ofstream ofile(name.str().c_str(), ios::binary);
  369.         if(!ofile) return error("Failed to create astp file.");
  370.         ofile.write(data.get(), filesize);
  371.         if(ofile.fail()) return error("Failed to write to astp file.");
  372.         astp_count++;
  373.        }
  374.      // ARCH file
  375.      else if(type == 0x2266) {
  376.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (ARCH)." << endl;
  377.         stringstream name;
  378.         name << "ANS_" << setfill('0') << setw(4) << arch_count << ".arch" << ends;
  379.         ofstream ofile(name.str().c_str(), ios::binary);
  380.         if(!ofile) return error("Failed to create arch file.");
  381.         ofile.write(data.get(), filesize);
  382.         if(ofile.fail()) return error("Failed to write to arch file.");
  383.         arch_count++;
  384.        }
  385.      else if(type == 0x5742445F) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (WBD_)." << endl;
  386.      else if(type == 0x5742485F) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (WBH_)." << endl;
  387.      else if(type == 0x04F) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x04F)." << endl;
  388.      else if(type == 0x07D) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x07D)." << endl;
  389.      else if(type == 0x4F0) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x4F0)." << endl;
  390.      else if(type == 0x62C) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x62C)." << endl;
  391.      else return error("Unknown section.");
  392.     }
  393.  
  394.  cout << endl;
  395.  return true;
  396. }
  397.  
  398. bool ExtractCNS_G1MG(istream& source, uint32 index)
  399. {
  400.  // read header
  401.  G1MG0044_HEADER head;
  402.  head.platform = BE_read_uint32(source);
  403.  head.unknown1 = BE_read_uint32(source);
  404.  BE_read_array(source, &head.bbox_min[0], 3);
  405.  BE_read_array(source, &head.bbox_max[0], 3);
  406.  head.sections = BE_read_uint32(source);
  407.  
  408.  // read sections
  409.  deque<G1MG0044_ITEMDATA> itemdata;
  410.  for(size_t i = 0; i < head.sections; i++) {
  411.      G1MG0044_ITEMDATA item;
  412.      item.type = BE_read_uint32(source);
  413.      item.size = BE_read_uint32(source);
  414.      item.data.reset(new char[item.size - 0x8]);
  415.      source.read(item.data.get(), item.size - 0x8);
  416.      itemdata.push_back(item);
  417.     }
  418.  
  419.  // data to save
  420.  deque<VERTEX_BUFFER> vdlist;
  421.  deque<INDEX_BUFFER> fdlist;
  422.  
  423.  // process section data
  424.  for(size_t i = 0; i < itemdata.size(); i++)
  425.     {
  426.      // vertex section
  427.      if(itemdata[i].type == 0x00010004)
  428.        {
  429.         // stringstream from data
  430.         stringstream ss(ios_base::out | ios_base::in | ios_base::binary);
  431.         ss.write(itemdata[i].data.get(), itemdata[i].size - 0x8);
  432.         ss.seekg(0);
  433.  
  434.         // read vertex sections
  435.         uint32 meshes = BE_read_uint32(ss);
  436.         for(size_t j = 0; j < meshes; j++)
  437.            {
  438.             // read mesh vertex info
  439.             G1MG0044_VERTEXDATA vd;
  440.             vd.unknown1 = BE_read_uint32(ss);
  441.             vd.vertsize = BE_read_uint32(ss);
  442.             vd.vertices = BE_read_uint32(ss);
  443.             vd.unknown2 = BE_read_uint32(ss);
  444.                    cout << "VERTEX SIZE = " << vd.vertsize << endl;
  445.             // set vertex buffer properties
  446.             VERTEX_BUFFER vb;
  447.             vb.elem = vd.vertices;
  448.             vb.flags = 0;
  449.             vb.data.reset(new VERTEX[vd.vertices]);
  450.  
  451.             // set vertex buffer flags
  452.             if(vd.vertsize == 0x10) {
  453.                vb.flags |= VERTEX_POSITION;
  454.                vb.flags |= VERTEX_NORMAL;
  455.                vb.flags |= VERTEX_UV;
  456.               }
  457.             else if(vd.vertsize == 0x14) {
  458.                vb.flags |= VERTEX_POSITION;
  459.                vb.flags |= VERTEX_NORMAL;
  460.                vb.flags |= VERTEX_UV;
  461.               }
  462.             else if(vd.vertsize == 0x18) {
  463.                vb.flags |= VERTEX_POSITION;
  464.                vb.flags |= VERTEX_NORMAL;
  465.               }
  466.             else if(vd.vertsize == 0x1C) {
  467.                vb.flags |= VERTEX_POSITION;
  468.                vb.flags |= VERTEX_NORMAL;
  469.                vb.flags |= VERTEX_UV;
  470.               }
  471.             else if(vd.vertsize == 0x20) {
  472.                vb.flags |= VERTEX_POSITION;
  473.                vb.flags |= VERTEX_NORMAL;
  474.                vb.flags |= VERTEX_UV;
  475.               }
  476.             else if(vd.vertsize == 0x24) {
  477.                vb.flags |= VERTEX_POSITION;
  478.                vb.flags |= VERTEX_NORMAL;
  479.                vb.flags |= VERTEX_UV;
  480.               }
  481.             else
  482.                return error("Unknown vertex format.");
  483.  
  484.             // read vertices
  485.             for(size_t k = 0; k < vd.vertices; k++)
  486.                {
  487.                 VERTEX vertex;
  488.                 if(vd.vertsize == 0x10) {
  489.                    vertex.vx = BE_read_float16(ss);
  490.                    vertex.vy = BE_read_float16(ss);
  491.                    vertex.vz = BE_read_float16(ss);
  492.                    BE_read_float16(ss);
  493.                    vertex.nx = BE_read_float16(ss);
  494.                    vertex.ny = BE_read_float16(ss);
  495.                    vertex.nz = BE_read_float16(ss);
  496.                    BE_read_float16(ss);
  497.                   }
  498.                 else if(vd.vertsize == 0x14) {
  499.                    vertex.vx = BE_read_float16(ss);
  500.                    vertex.vy = BE_read_float16(ss);
  501.                    vertex.vz = BE_read_float16(ss);
  502.                    BE_read_float16(ss);
  503.                    vertex.nx = BE_read_float16(ss);
  504.                    vertex.ny = BE_read_float16(ss);
  505.                    vertex.nz = BE_read_float16(ss);
  506.                    BE_read_float16(ss);
  507.                    vertex.tu = BE_read_float16(ss);
  508.                    vertex.tv = BE_read_float16(ss);
  509.                   }
  510.                 else if(vd.vertsize == 0x18) {
  511.                    vertex.vx = BE_read_float32(ss);
  512.                    vertex.vy = BE_read_float32(ss);
  513.                    vertex.vz = BE_read_float32(ss);
  514.                    vertex.nx = BE_read_float16(ss);
  515.                    vertex.ny = BE_read_float16(ss);
  516.                    vertex.nz = BE_read_float16(ss);
  517.                    BE_read_float16(ss);
  518.                    BE_read_float32(ss);
  519.                   }
  520.                 else if(vd.vertsize == 0x1C) {
  521.                    vertex.vx = BE_read_float32(ss);
  522.                    vertex.vy = BE_read_float32(ss);
  523.                    vertex.vz = BE_read_float32(ss);
  524.                    vertex.nx = BE_read_float16(ss);
  525.                    vertex.ny = BE_read_float16(ss);
  526.                    vertex.nz = BE_read_float16(ss);
  527.                    BE_read_float16(ss);
  528.                    BE_read_float32(ss);
  529.                    vertex.tu = BE_read_float16(ss);
  530.                    vertex.tv = BE_read_float16(ss);
  531.                   }
  532.                 else if(vd.vertsize == 0x20) {
  533.                    vertex.vx = BE_read_float32(ss);
  534.                    vertex.vy = BE_read_float32(ss);
  535.                    vertex.vz = BE_read_float32(ss);
  536.                    vertex.nx = BE_read_float16(ss);
  537.                    vertex.ny = BE_read_float16(ss);
  538.                    vertex.nz = BE_read_float16(ss);
  539.                    BE_read_float16(ss);
  540.                    BE_read_float32(ss);
  541.                    BE_read_float16(ss);
  542.                    BE_read_float16(ss);
  543.                    vertex.tu = BE_read_float16(ss);
  544.                    vertex.tv = BE_read_float16(ss);
  545.                   }
  546.                 else if(vd.vertsize == 0x24) {
  547.                    vertex.vx = BE_read_float32(ss);
  548.                    vertex.vy = BE_read_float32(ss);
  549.                    vertex.vz = BE_read_float32(ss);
  550.                    vertex.nx = BE_read_float32(ss);
  551.                    vertex.ny = BE_read_float32(ss);
  552.                    vertex.nz = BE_read_float32(ss);
  553.                    BE_read_float32(ss);
  554.                    vertex.tu = BE_read_float32(ss);
  555.                    vertex.tv = BE_read_float32(ss);
  556.                   }
  557.  
  558.                 // save vertex
  559.                 vb.data[k] = vertex;
  560.                }
  561.  
  562.             // save vertex data
  563.             cout << " vertices = " << vd.vertices << endl;
  564.             vdlist.push_back(vb);
  565.            }
  566.        }
  567.      // index buffer section
  568.      else if(itemdata[i].type == 0x00010007)
  569.        {
  570.         // stringstream from data
  571.         stringstream ss(ios_base::out | ios_base::in | ios_base::binary);
  572.         ss.write(itemdata[i].data.get(), itemdata[i].size - 0x8);
  573.         ss.seekg(0);
  574.  
  575.         // read face sections
  576.         uint32 n_meshes = BE_read_uint32(ss);
  577.         uint32 vb_index = 0;
  578.         for(size_t j = 0; j < n_meshes; j++)
  579.            {
  580.             // read face data
  581.             G1MG0044_FACEDATA fd;
  582.             fd.numindex = BE_read_uint32(ss);
  583.             fd.datatype = BE_read_uint32(ss);
  584.             fd.unknown1 = BE_read_uint32(ss);
  585.  
  586.             // set index buffer properties
  587.             INDEX_BUFFER ib;
  588.             ib.type = FACE_TYPE_TRISTRIP;
  589.             ib.elem = fd.numindex;
  590.             if(fd.datatype == 0x10) ib.format = FACE_FORMAT_UINT_16;
  591.             else if(fd.datatype == 0x20) ib.format = FACE_FORMAT_UINT_32;
  592.             else return error("Unknown index buffer data format.");
  593.  
  594.             // set index buffer name
  595.             stringstream surface;
  596.             surface << setfill('0') << setw(4) << index << "_" << setw(3) << j << ends;
  597.             ib.name = surface.str();
  598.  
  599.             // determine index buffer data type size
  600.             unsigned int typesize = 0;
  601.             if(fd.datatype == 0x10) typesize = sizeof(uint16);
  602.             else if(fd.datatype == 0x20) typesize = sizeof(uint32);
  603.             else return error("Unknown index buffer data type.");
  604.  
  605.             // read face data
  606.             unsigned int total_bytes = ib.elem * typesize;
  607.             ib.data.reset(new char[total_bytes]);
  608.             if(ib.format == FACE_FORMAT_UINT_16) BE_read_array(ss, reinterpret_cast<uint16*>(ib.data.get()), ib.elem);
  609.             else if(ib.format == FACE_FORMAT_UINT_32) BE_read_array(ss, reinterpret_cast<uint32*>(ib.data.get()), ib.elem);
  610.  
  611.             // test face data
  612.             uint32 min_index = 0;
  613.             uint32 max_index = 0;
  614.             if(ib.format == FACE_FORMAT_UINT_16) {
  615.                uint16 a; minimum(reinterpret_cast<uint16*>(ib.data.get()), ib.elem, a);
  616.                uint16 b; maximum(reinterpret_cast<uint16*>(ib.data.get()), ib.elem, b);
  617.                min_index = a;
  618.                max_index = b;
  619.               }
  620.             else if(ib.format == FACE_FORMAT_UINT_32) {
  621.                uint32 a; minimum(reinterpret_cast<uint32*>(ib.data.get()), ib.elem, a);
  622.                uint32 b; maximum(reinterpret_cast<uint32*>(ib.data.get()), ib.elem, b);
  623.                min_index = a;
  624.                max_index = b;
  625.               }
  626.             cout << " min index = " << min_index << endl;
  627.             cout << " max index = " << max_index << endl;
  628.  
  629.             // set vertex buffer reference
  630.             if(min_index == 0) vb_index++;
  631.             if(vb_index > 0) ib.reference = vb_index - 1;
  632.             else return error("Unexpected vertex buffer reference.");
  633.  
  634.             // save face data
  635.             fdlist.push_back(ib);
  636.            }
  637.        }
  638.     }
  639.  
  640.  cout << " vertex data = " << vdlist.size() << endl;
  641.  cout << " face data = " << fdlist.size() << endl;
  642.  
  643.  // create filename
  644.  stringstream ofile;
  645.  ofile << "CSN_G1MG_" << setfill('0') << setw(4) << index << ends;
  646.  
  647.  // save geometry
  648.  //if(!GeometryToOBJ(ofile.str().c_str(), vdlist, fdlist)) return false;
  649.  return true;
  650. }
  651.  
  652. bool ExtractCNS_G1MX(uint32 index, uint32 position, uint32 datasize, uint32 nextsize, boost::shared_array<char> data, boost::shared_array<char> next)
  653. {
  654.  // create a folder for this file
  655.  stringstream name;
  656.  name << "CNS_G1MX_" << setfill('0') << setw(3) << index << ends;
  657.  CreateDirectoryA(name.str().c_str(), NULL);
  658.  
  659.  // read data into stringstream
  660.  stringstream ss_data(ios::in | ios::out | ios::binary);
  661.  ss_data.write(data.get(), datasize);
  662.  if(ss_data.fail()) return error("Stream write failure.");
  663.  
  664.  // read next into stringstream
  665.  stringstream ss_next(ios::in | ios::out | ios::binary);
  666.  ss_next.write(next.get(), nextsize);
  667.  if(ss_next.fail()) return error("Stream write failure.");
  668.  
  669.  struct G1M_HEADER {
  670.   uint32 magic;
  671.   uint32 version;
  672.   uint32 size;
  673.   uint32 offset;
  674.   uint32 unknown1;
  675.   uint32 sections;
  676.  };
  677.  
  678.  // read header
  679.  G1M_HEADER head;
  680.  head.magic    = BE_read_uint32(ss_data); if(ss_data.fail()) return error("Stream read failure.");
  681.  head.version  = BE_read_uint32(ss_data); if(ss_data.fail()) return error("Stream read failure.");
  682.  head.size     = BE_read_uint32(ss_data); if(ss_data.fail()) return error("Stream read failure.");
  683.  head.offset   = BE_read_uint32(ss_data); if(ss_data.fail()) return error("Stream read failure.");
  684.  head.unknown1 = BE_read_uint32(ss_data); if(ss_data.fail()) return error("Stream read failure.");
  685.  head.sections = BE_read_uint32(ss_data); if(ss_data.fail()) return error("Stream read failure.");
  686.  
  687.  // validate header
  688.  if(head.magic != 0x47314D5F) return error("Expecting G1M_ section.");
  689.  if(head.version != 0x30303334) return error("Invalid G1M_ version.");
  690.  if(!head.size) return error("Invalid G1M_ data size.");
  691.  if(!head.offset) return error("Invalid G1M_ data offset.");
  692.  if(!head.sections) return error("Expecting at least one G1M_ section.");
  693.  
  694.  // read sections
  695.  for(size_t i = 0; i < head.sections; i++)
  696.     {
  697.      uint32 section_name = BE_read_uint32(ss_data); if(ss_data.fail()) return error("Stream read failure.");
  698.      uint32 section_vers = BE_read_uint32(ss_data); if(ss_data.fail()) return error("Stream read failure.");
  699.      uint32 section_size = BE_read_uint32(ss_data); if(ss_data.fail()) return error("Stream read failure.");
  700.  
  701.      // G1MF
  702.      if(section_name == 0x47314D46) {
  703.         ss_data.seekg(section_size - 0xC, ios::cur);
  704.         if(ss_data.fail()) return error("Stream seek failure.");
  705.        }
  706.      // G1MS
  707.      else if(section_name == 0x47314D53) {
  708.         ss_data.seekg(section_size - 0xC, ios::cur);
  709.         if(ss_data.fail()) return error("Stream seek failure.");
  710.        }
  711.      // G1MM
  712.      else if(section_name == 0x47314D4D) {
  713.         ss_data.seekg(section_size - 0xC, ios::cur);
  714.         if(ss_data.fail()) return error("Stream seek failure.");
  715.        }
  716.      // EXTR
  717.      else if(section_name == 0x45585452) {
  718.         ss_data.seekg(section_size - 0xC, ios::cur);
  719.         if(ss_data.fail()) return error("Stream seek failure.");
  720.        }
  721.      // G1MG
  722.      else if(section_name == 0x47314D47) {
  723.         size_t save = (size_t)ss_data.tellg();
  724.         if(!ExtractCNS_G1MG(ss_data, index)) return false;
  725.         ss_data.seekg(save);
  726.         ss_data.seekg(section_size - 0xC, ios::cur);
  727.         if(ss_data.fail()) return error("Stream seek failure.");
  728.        }
  729.      else
  730.         return error("Unknown G1M_ section.");
  731.     }
  732.  
  733.  return true;
  734. }
  735.  
  736. bool ExtractCNS_G1TG(uint32 index, uint32 position, uint32 datasize, uint32 nextsize, boost::shared_array<char> data, boost::shared_array<char> next)
  737. {
  738.  // create a folder for this file
  739.  stringstream name;
  740.  name << "CNS_G1TG_" << setfill('0') << setw(3) << index << ends;
  741.  CreateDirectoryA(name.str().c_str(), NULL);
  742.  
  743.  // read data into stringstream
  744.  stringstream ss_data(ios::in | ios::out | ios::binary);
  745.  ss_data.write(data.get(), datasize);
  746.  if(ss_data.fail()) return error("Stream write failure.");
  747.  
  748.  // read next into stringstream
  749.  stringstream ss_next(ios::in | ios::out | ios::binary);
  750.  ss_next.write(next.get(), nextsize);
  751.  if(ss_next.fail()) return error("Stream write failure.");
  752.  
  753.  // read header
  754.  uint32 magic = BE_read_uint32(ss_data);
  755.  uint32 version = BE_read_uint32(ss_data);
  756.  uint32 section_size = BE_read_uint32(ss_data);
  757.  uint32 table_offset = BE_read_uint32(ss_data);
  758.  uint32 n_textures = BE_read_uint32(ss_data);
  759.  
  760.  // validate header
  761.  if(magic != 0x47315447) return error("Expecting G1TG section.");
  762.  if(!(version == 0x30303530 || version == 0x30303630)) return error("Invalid G1TG version.");
  763.  if(n_textures == 0) return error("Invalid number of textures.");
  764.  
  765.  // move to table
  766.  ss_data.seekg(table_offset);
  767.  if(ss_data.fail()) return error("Stream seek failure.");
  768.  
  769.  // read offset table
  770.  deque<size_t> offset_list;
  771.  for(size_t i = 0; i < n_textures; i++) {
  772.      offset_list.push_back(BE_read_uint32(ss_data));
  773.      if(ss_data.fail()) return error("Stream read failure.");
  774.     }
  775.  
  776.  // process textures
  777.  for(size_t i = 0; i < offset_list.size(); i++)
  778.     {
  779.      ss_data.seekg(table_offset + offset_list[i]);
  780.      if(ss_data.fail()) return error("Stream seek failure.");
  781.  
  782.      // read texture information
  783.      uint08 b1 = BE_read_uint08(ss_data); // unknown
  784.      uint08 b2 = BE_read_uint08(ss_data); // texture type
  785.      uint08 b3 = BE_read_uint08(ss_data); // dx/dy
  786.      uint08 b4 = BE_read_uint08(ss_data); // unknown
  787.      uint16 s1 = BE_read_uint16(ss_data); // unknown
  788.      uint16 s2 = BE_read_uint16(ss_data); // unknown
  789.  
  790.      // header is extended depending on version
  791.      if(version == 0x30303630) {
  792.         uint32 v1 = BE_read_uint32(ss_data); // 12
  793.         uint32 v2 = BE_read_uint32(ss_data); // 0
  794.         uint32 v3 = BE_read_uint32(ss_data); // 0 or 1
  795.        }
  796.  
  797.      // compute dimensions
  798.      uint32 temp1 = ((b3 & 0xF0) >> 4);
  799.      uint32 temp2 = ((b3 & 0x0F));
  800.      uint32 dx = 1 << temp1;
  801.      uint32 dy = 1 << temp2;
  802.  
  803.      // create texture file
  804.      stringstream filename;
  805.      filename << "CNS_G1TG_" << setfill('0') << setw(3) << index << "/" << setfill('0') << setw(3) << i << ".dds" << ends;
  806.      ofstream ofile(filename.str().c_str(), ios::binary);
  807.  
  808.      // save texture
  809.      if(b2 == 0)
  810.        {
  811.         // read texture
  812.         DWORD filesize = UncompressedDDSFileSize(dx, dy, 0, 0xFF, 0xFF00, 0xFF0000, 0xFF000000);
  813.         boost::shared_array<char> buffer(new char[filesize]);
  814.         ss_data.read((char*)buffer.get(), filesize);
  815.  
  816.         // save texture
  817.         DDS_HEADER ddsh;
  818.         CreateUncompressedDDSHeader(dx, dy, 0, 0xFF000000, 0xFF0000, 0xFF00, 0xFF, FALSE, &ddsh);
  819.         DWORD signature = 0x20534444;
  820.         ofile.write((char*)&signature, sizeof(signature));
  821.         ofile.write((char*)&ddsh, sizeof(ddsh));
  822.         ofile.write((char*)buffer.get(), filesize);
  823.  
  824.         cout << filename.str() << endl;
  825.         cout << " dx = " << dx << endl;
  826.         cout << " dy = " << dy << endl;
  827.         cout << " filesize = " << filesize << endl;
  828.         if(i != offset_list.size() - 1) cout << " expected = " << (offset_list[i + 1] - offset_list[i] - 0x14) << endl;
  829.        }
  830.      // UNCOMPRESSED DDS (PS3 works good)
  831.      else if(b2 == 1)
  832.        {
  833.         // read texture
  834.         DWORD filesize = UncompressedDDSFileSize(dx, dy, 0, 0xFF, 0xFF00, 0xFF0000, 0xFF000000);
  835.         boost::shared_array<char> buffer(new char[filesize]);
  836.         ss_data.read((char*)buffer.get(), filesize);
  837.  
  838.         // save texture
  839.         DDS_HEADER ddsh;
  840.         CreateUncompressedDDSHeader(dx, dy, 0, 0xFF000000, 0xFF0000, 0xFF00, 0xFF, FALSE, &ddsh);
  841.         DWORD signature = 0x20534444;
  842.         ofile.write((char*)&signature, sizeof(signature));
  843.         ofile.write((char*)&ddsh, sizeof(ddsh));
  844.         ofile.write((char*)buffer.get(), filesize);
  845.        }
  846.      // DXT1 (PS3 works good)
  847.      else if(b2 == 6)
  848.        {
  849.         // read texture
  850.         DWORD filesize = DXT1Filesize(dx, dy, 0);
  851.         boost::shared_array<char> buffer(new char[filesize]);
  852.         ss_data.read((char*)buffer.get(), filesize);
  853.  
  854.         // save texture
  855.         DDS_HEADER ddsh;
  856.         CreateDXT1Header(dx, dy, 0, FALSE, &ddsh);
  857.         DWORD signature = 0x20534444;
  858.         ofile.write((char*)&signature, sizeof(signature));
  859.         ofile.write((char*)&ddsh, sizeof(ddsh));
  860.         ofile.write((char*)buffer.get(), filesize);
  861.        }
  862.      // DXT5 (PS3 works good)
  863.      else if(b2 == 8)
  864.        {
  865.         // read texture
  866.         DWORD filesize = DXT5Filesize(dx, dy, 0);
  867.         boost::shared_array<char> buffer(new char[filesize]);
  868.         ss_data.read((char*)buffer.get(), filesize);
  869.  
  870.         // save texture
  871.         DDS_HEADER ddsh;
  872.         CreateDXT5Header(dx, dy, 0, FALSE, &ddsh);
  873.         DWORD signature = 0x20534444;
  874.         ofile.write((char*)&signature, sizeof(signature));
  875.         ofile.write((char*)&ddsh, sizeof(ddsh));
  876.         ofile.write((char*)buffer.get(), filesize);
  877.        }
  878.      else {
  879.         return error("Unsupported texture type.");
  880.        }
  881.     }
  882.  
  883.  return true;
  884. }
  885.  
  886. bool ExtractArchiveBNS(void)
  887. {
  888.  // set EXE pathname
  889.  char c_pathname[1024];
  890.  GetModulePathname(c_pathname, 1024);
  891.  string s_pathname(c_pathname);
  892.  
  893.  // open BNS file
  894.  cout << "Extracting BNS file." << endl;
  895.  stringstream filename;
  896.  filename << s_pathname << "linkdata.bns" << ends;
  897.  ifstream ifile;
  898.  ifile.open(filename.str().c_str(), ios::binary);
  899.  if(!ifile) return error("Could not open file.");
  900.  
  901.  // create subdirectory to store files
  902.  string datapath = s_pathname;
  903.  datapath += "LINKDATA_BNS\\";
  904.  CreateDirectoryA(datapath.c_str(), NULL);
  905.  
  906.  // read header
  907.  uint32 headMagic = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  908.  uint32 headFiles = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  909.  uint32 headScale = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  910.  uint32 headUnk01 = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  911.  
  912.  // validate header
  913.  if(headMagic != 0x1EDE) return error("Invalid header signature.");
  914.  if(headFiles >= 0xFFFF) return error("No dynasty warriors game contains this many files.");
  915.  if(headScale != 0x0800) return error("File assets should occur on 0x800 boundaries.");
  916.  
  917.  // read file table
  918.  deque<pair<uint32, uint32>> filetable;
  919.  for(size_t i = 0; i < headFiles; i++) {
  920.      pair<uint32, uint32> p;
  921.      p.first  = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  922.      p.second = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  923.      filetable.push_back(p);
  924.     }
  925.  
  926.  uint32 ping_count = 0;
  927.  uint32 file_count = 0;
  928.  deque<string> filelist;
  929.  
  930.  // for each item in the file table
  931.  for(size_t i = 0; i < filetable.size(); i++)
  932.     {
  933.      // move to file position
  934.      size_t position = filetable[i].first*headScale;
  935.      size_t filesize = filetable[i].second;
  936.      ifile.seekg(position);
  937.      if(ifile.fail()) return error("Failed to seek file position.");
  938.  
  939.      // read data
  940.      boost::shared_array<char> data(new char[filesize]);
  941.      ifile.read(data.get(), filesize);
  942.      if(ifile.fail()) return error("Read data failure.");
  943.  
  944.      // extract type from data
  945.      stringstream ss;
  946.      ss.write(data.get(), 4);
  947.      if(ss.fail()) return error("Write to stringstream failure.");
  948.      uint32 type = BE_read_uint32(ss);
  949.      if(ss.fail()) return error("Read from stream failure.");
  950.  
  951.      // save textures and models
  952.      binary_stream bs(data, filesize);
  953.      if((bs.search("G1TG00", 6) != binary_stream::npos) || (bs.search("G1M_00", 6) != binary_stream::npos))
  954.        {
  955.         // display some information
  956.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (BIN)." << endl;
  957.         file_count++;
  958.         
  959.         // save file data
  960.         stringstream binfile;
  961.         binfile << datapath.c_str() << setfill('0') << setw(3) << file_count << ".bin" << ends;
  962.         ofstream ofile(binfile.str(), ios::binary);
  963.         ofile.write(data.get(), filesize);
  964.         if(ofile.fail()) return error("Write failure.");
  965.         
  966.         // save file list
  967.         filelist.push_back(binfile.str());
  968.        }
  969.     }
  970.  
  971.  // process each file
  972.  for(size_t i = 0; i < filelist.size(); i++)
  973.     {
  974.      // open file
  975.      cout << "Processing " << filelist[i].c_str() << "." << endl;
  976.      ifstream ifile(filelist[i].c_str(), ios::binary);
  977.      if(!ifile) return error("Error opening file.");
  978.  
  979.      // read file
  980.      ifile.seekg(0, ios::end);
  981.      size_t size = (size_t)ifile.tellg();
  982.      ifile.seekg(0, ios::beg);
  983.      boost::shared_array<char> data(new char[size]);
  984.      ifile.read(data.get(), size);
  985.  
  986.      // read type
  987.      binary_stream bs(data, size);
  988.      uint32 type = bs.BE_read_uint32();
  989.      bs.seek(0);
  990.  
  991.      // G1TG (textures)
  992.      if(type == 0x47315447)
  993.        {
  994.         // make directory
  995.         char c_drive[1024];
  996.         char c_path[1024];
  997.         char c_name[1024];
  998.         _splitpath(filelist[i].c_str(), c_drive, c_path, c_name, nullptr);
  999.         string pathname(c_drive);
  1000.         pathname += c_path;
  1001.         pathname += c_name;
  1002.         pathname += "\\";
  1003.  
  1004.         // make directory
  1005.         CreateDirectoryA(pathname.c_str(), NULL);
  1006.  
  1007.         // extract textures
  1008.         ExtractG1TG0060(bs, pathname.c_str(), 0);
  1009.        }
  1010.      else if(type == 0x1EDE)
  1011.        {
  1012.         // make directory
  1013.         char c_drive[1024];
  1014.         char c_path[1024];
  1015.         char c_name[1024];
  1016.         _splitpath(filelist[i].c_str(), c_drive, c_path, c_name, nullptr);
  1017.         string pathname(c_drive);
  1018.         pathname += c_path;
  1019.         pathname += c_name;
  1020.         pathname += "\\";
  1021.  
  1022.         // make directory
  1023.         CreateDirectoryA(pathname.c_str(), NULL);
  1024.  
  1025.         // extract textures
  1026.         size_t position = bs.search("G1TG00", 6);
  1027.         size_t index = 0;
  1028.         while(position != binary_stream::npos) {
  1029.               binary_stream temp(bs);
  1030.               temp.seek(position);
  1031.               ExtractG1TG0060(temp, pathname.c_str(), ++index);
  1032.               position = bs.search("G1TG00", 6, position + 1);
  1033.               if(position == binary_stream::npos) break;
  1034.              }
  1035.        }
  1036.      else if(type >= 0x1 && type <= 0xFF)
  1037.        {
  1038.         // make directory
  1039.         char c_drive[1024];
  1040.         char c_path[1024];
  1041.         char c_name[1024];
  1042.         _splitpath(filelist[i].c_str(), c_drive, c_path, c_name, nullptr);
  1043.         string pathname(c_drive);
  1044.         pathname += c_path;
  1045.         pathname += c_name;
  1046.         pathname += "\\";
  1047.  
  1048.         // make directory
  1049.         CreateDirectoryA(pathname.c_str(), NULL);
  1050.  
  1051.         // extract textures
  1052.         size_t position = bs.search("G1TG00", 6);
  1053.         size_t index = 0;
  1054.         while(position != binary_stream::npos) {
  1055.               binary_stream temp(bs);
  1056.               temp.seek(position);
  1057.               ExtractG1TG0060(temp, pathname.c_str(), ++index);
  1058.               position = bs.search("G1TG00", 6, position + 1);
  1059.               if(position == binary_stream::npos) break;
  1060.              }
  1061.  
  1062.         // extract models
  1063.         position = bs.search("G1MG00", 6);
  1064.         index = 0;
  1065.         while(position != binary_stream::npos) {
  1066.               binary_stream temp(bs);
  1067.               temp.seek(position);
  1068.               ExtractModels(temp, pathname.c_str(), ++index);
  1069.               position = bs.search("G1MG00", 6, position + 1);
  1070.               if(position == binary_stream::npos) break;
  1071.              }
  1072.        }
  1073.     }
  1074.  
  1075.  cout << endl;
  1076.  return true;
  1077. }
  1078.  
  1079. bool ExtractArchiveCNS(void)
  1080. {
  1081.  cout << "Extracting CNS file." << endl;
  1082.  ifstream ifile;
  1083.  ifile.open("linkdata.cns", ios::binary);
  1084.  if(!ifile) return error("Could not open file.");
  1085.  
  1086.  // create subdirectory to store files
  1087.  CreateDirectoryA("LINKDATA_CNS", NULL);
  1088.  
  1089.  // read header
  1090.  uint32 headMagic = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  1091.  uint32 headFiles = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  1092.  uint32 headScale = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  1093.  uint32 headUnk01 = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  1094.  
  1095.  // validate header
  1096.  if(headMagic != 0x1EDE) return error("Invalid header signature.");
  1097.  if(headFiles >= 0xFFFF) return error("No dynasty warriors game contains this many files.");
  1098.  if(headScale != 0x0800) return error("File assets should occur on 0x800 boundaries.");
  1099.  
  1100.  // read file table
  1101.  deque<pair<uint32, uint32>> filetable;
  1102.  for(size_t i = 0; i < headFiles; i++) {
  1103.      pair<uint32, uint32> p;
  1104.      p.first  = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  1105.      p.second = BE_read_uint32(ifile); if(ifile.fail()) return error("Read failure.");
  1106.      filetable.push_back(p);
  1107.     }
  1108.  
  1109.  uint32 g1tg_count = 0;
  1110.  uint32 g1mx_count = 0;
  1111.  uint32 ping_count = 0;
  1112.  uint32 d002_count = 0;
  1113.  uint32 d003_count = 0;
  1114.  
  1115.  // for each item in the file table
  1116.  for(size_t i = 0; i < filetable.size(); i++)
  1117.     {
  1118.      // move to file position
  1119.      size_t position = filetable[i].first*headScale;
  1120.      size_t filesize = filetable[i].second;
  1121.      ifile.seekg(position);
  1122.      if(ifile.fail()) return error("Failed to seek file position.");
  1123.  
  1124.      // read data
  1125.      boost::shared_array<char> data(new char[filesize]);
  1126.      ifile.read(data.get(), filesize);
  1127.      if(ifile.fail()) return error("Read data failure.");
  1128.  
  1129.      // read fill data
  1130.      boost::shared_array<char> fill;
  1131.      uint32 fillsize = 0;
  1132.      if((i != (filetable.size() - 1))) {
  1133.         uint32 p0 = filetable[i + 0].first*headScale + filetable[i].second;
  1134.         uint32 p1 = filetable[i + 1].first*headScale;
  1135.         if(p0 < p1) {
  1136.            fillsize = p1 - p0;
  1137.            fill.reset(new char[fillsize]);
  1138.            ifile.read(fill.get(), fillsize);
  1139.            if(ifile.fail()) { cout << "fillsize = " << fillsize << endl; return error("Read fill failure."); }
  1140.           }
  1141.        }
  1142.  
  1143.      // extract type from data
  1144.      stringstream ss;
  1145.      ss.write(data.get(), 4);
  1146.      if(ss.fail()) return error("Write to stringstream failure.");
  1147.      uint32 type = BE_read_uint32(ss);
  1148.      if(ss.fail()) return error("Read from stream failure.");
  1149.      
  1150.      // G1TG
  1151.      if(type == 0x47315447)
  1152.        {
  1153.         // display some information
  1154.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (G1TG)." << endl;
  1155.         g1tg_count++;
  1156.  
  1157.         // save file data
  1158.         stringstream name;
  1159.         name << "LINKDATA_CNS/GITG_" << setfill('0') << setw(3) << g1tg_count << ".g1tg" << ends;
  1160.         ofstream ofile(name.str().c_str(), ios::binary);
  1161.         ofile.write(data.get(), filesize);
  1162.         if(ofile.fail()) return error("Write failure.");
  1163.  
  1164.         // save fill data
  1165.         ofile.write(fill.get(), fillsize);
  1166.         if(ofile.fail()) return error("Write failure.");
  1167.        }
  1168.      // G1M_
  1169.      else if(type == 0x47314D5F)
  1170.        {
  1171.         // display some information
  1172.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (G1M_)." << endl;
  1173.         g1mx_count++;
  1174.  
  1175.         // save file data
  1176.         stringstream name;
  1177.         name << "LINKDATA_CNS/GIM_" << setfill('0') << setw(3) << g1mx_count << ".g1m" << ends;
  1178.         ofstream ofile(name.str().c_str(), ios::binary);
  1179.         ofile.write(data.get(), filesize);
  1180.         if(ofile.fail()) return error("Write failure.");
  1181.  
  1182.         // save fill data
  1183.         ofile.write(fill.get(), fillsize);
  1184.         if(ofile.fail()) return error("Write failure.");
  1185.        }
  1186.      // PING
  1187.      else if(type == 0x89504E47)
  1188.        {
  1189.         // display some information
  1190.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (PING)." << endl;
  1191.         ping_count++;
  1192.  
  1193.         // save file data
  1194.         stringstream name;
  1195.         name << "LINKDATA_CNS/PNG_" << setfill('0') << setw(3) << ping_count << ".png" << ends;
  1196.         ofstream ofile(name.str().c_str(), ios::binary);
  1197.         if(!ofile) return error("Error creating PNG file.");
  1198.         ofile.write(data.get(), filesize);
  1199.         if(ofile.fail()) return error("Error writing PNG file.");
  1200.        }
  1201.      else if(type == 0x02)
  1202.        {
  1203.         // display some information
  1204.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (002)." << endl;
  1205.         d002_count++;
  1206.  
  1207.         // save file data
  1208.         stringstream name;
  1209.         name << "LINKDATA_CNS/0002_" << setfill('0') << setw(3) << d002_count << ".002" << ends;
  1210.         ofstream ofile(name.str().c_str(), ios::binary);
  1211.         ofile.write(data.get(), filesize);
  1212.         if(ofile.fail()) return error("Write failure.");
  1213.  
  1214.         // save fill data
  1215.         ofile.write(fill.get(), fillsize);
  1216.         if(ofile.fail()) return error("Write failure.");
  1217.        }
  1218.      else if(type == 0x03)
  1219.        {
  1220.         // display some information
  1221.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (003)." << endl;
  1222.         d003_count++;
  1223.  
  1224.         // save file data
  1225.         stringstream name;
  1226.         name << "LINKDATA_CNS/0003_" << setfill('0') << setw(3) << d003_count << ".003" << ends;
  1227.         ofstream ofile(name.str().c_str(), ios::binary);
  1228.         ofile.write(data.get(), filesize);
  1229.         if(ofile.fail()) return error("Write failure.");
  1230.  
  1231.         // save fill data
  1232.         ofile.write(fill.get(), fillsize);
  1233.         if(ofile.fail()) return error("Write failure.");
  1234.        }
  1235.      else if(type == 0x4B53484C) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (KSHL)." << endl;
  1236.      else if(type == 0x5356445F) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (SVD_)." << endl;
  1237.      else if(type >= 0x10000 && type <= 0xFFFFF) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x10000 - 0xFFFFF)." << endl;
  1238.      else if(type == 0x0B) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x0B)." << endl;
  1239.      else if(type == 0x10) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x10)." << endl;
  1240.      else if(type == 0x1B) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x1B)." << endl;
  1241.      else {
  1242.         cout << "curr position = " << filetable[i].first*headScale << endl;
  1243.         cout << "curr filesize = " << filetable[i].second << endl;
  1244.         cout << "next position = " << filetable[i + 1].first*headScale << endl;
  1245.         cout << "next filesize = " << filetable[i + 1].second << endl;
  1246.         return false;
  1247.        }
  1248.     }
  1249.  
  1250.  cout << endl;
  1251.  return true;
  1252. }
  1253.  
  1254. bool ExtractArchive(const char* filename)
  1255. {
  1256. /*
  1257.  uint32 g1tg_count = 0;
  1258.  uint32 g1em_count = 0;
  1259.  uint32 g1m__count = 0;
  1260.  uint32 ping_count = 0;
  1261.  uint32 d002_count = 0;
  1262.  uint32 d003_count = 0;
  1263.  
  1264.  // for each item in the file table
  1265.  for(size_t i = 0; i < filetable.size(); i++)
  1266.     {
  1267.      // move to file position
  1268.      size_t position = filetable[i].first*headScale;
  1269.      size_t filesize = filetable[i].second;
  1270.      ifile.seekg(position);
  1271.      if(ifile.fail()) return error("Failed to seek file position.");
  1272.  
  1273.      // read data
  1274.      boost::shared_array<char> data(new char[filesize]);
  1275.      ifile.read(data.get(), filesize);
  1276.      if(ifile.fail()) return error("Read failure.");
  1277.  
  1278.      // save to stringstream
  1279.      stringstream ss;
  1280.      ss.write(data.get(), filesize);
  1281.      if(ss.fail()) return error("Write to stringstream failure.");
  1282.      
  1283.      // read type of stringstream
  1284.      uint32 type = BE_read_uint32(ss);
  1285.      if(ifile.fail()) return error("Read failure.");
  1286.  
  1287.      // WAVE file
  1288.      if(type == 0x52494646) {
  1289.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (WAVE)." << endl;
  1290.         stringstream name;
  1291.         name << setfill('0') << setw(4) << wave_count << ".wav" << ends;
  1292.         ofstream ofile(name.str().c_str(), ios::binary);
  1293.         if(!ofile) return error("Failed to create wave file.");
  1294.         ofile.write(data.get(), filesize);
  1295.         if(ofile.fail()) return error("Failed to write to wave file.");
  1296.         wave_count++;
  1297.        }
  1298.      // ASTP file
  1299.      else if(type == 0x41545350) {
  1300.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (ASTP)." << endl;
  1301.         stringstream name;
  1302.         name << setfill('0') << setw(4) << astp_count << ".astp" << ends;
  1303.         ofstream ofile(name.str().c_str(), ios::binary);
  1304.         if(!ofile) return error("Failed to create astp file.");
  1305.         ofile.write(data.get(), filesize);
  1306.         if(ofile.fail()) return error("Failed to write to astp file.");
  1307.         astp_count++;
  1308.        }
  1309.      // ARCH file
  1310.      else if(type == 0x2266) {
  1311.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (ARCH)." << endl;
  1312.         stringstream name;
  1313.         name << setfill('0') << setw(4) << arch_count << ".arch" << ends;
  1314.         ofstream ofile(name.str().c_str(), ios::binary);
  1315.         if(!ofile) return error("Failed to create arch file.");
  1316.         ofile.write(data.get(), filesize);
  1317.         if(ofile.fail()) return error("Failed to write to arch file.");
  1318.         arch_count++;
  1319.        }
  1320.      // G1TG
  1321.      else if(type == 0x47315447) {
  1322.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (G1TG)." << endl;
  1323.         stringstream name;
  1324.         name << setfill('0') << setw(4) << g1tg_count << ".g1tg" << ends;
  1325.         ofstream ofile(name.str().c_str(), ios::binary);
  1326.         if(!ofile) return error("Failed to create g1tc file.");
  1327.         ofile.write(data.get(), filesize);
  1328.         if(ofile.fail()) return error("Failed to write to g1tg file.");
  1329.         g1tg_count++;
  1330.        }
  1331.      // G1EM
  1332.      else if(type == 0x4731454D) {
  1333.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (G1EM)." << endl;
  1334.         stringstream name;
  1335.         name << setfill('0') << setw(4) << g1em_count << ".g1em" << ends;
  1336.         ofstream ofile(name.str().c_str(), ios::binary);
  1337.         if(!ofile) return error("Failed to create g1em file.");
  1338.         ofile.write(data.get(), filesize);
  1339.         if(ofile.fail()) return error("Failed to write to g1em file.");
  1340.         g1em_count++;
  1341.        }
  1342.      // G1M_
  1343.      else if(type == 0x47314D5F) {
  1344.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (G1M_)." << endl;
  1345.         stringstream name;
  1346.         name << setfill('0') << setw(4) << g1m__count << ".g1m_" << ends;
  1347.         ofstream ofile(name.str().c_str(), ios::binary);
  1348.         if(!ofile) return error("Failed to create g1m file.");
  1349.         ofile.write(data.get(), filesize);
  1350.         if(ofile.fail()) return error("Failed to write to g1m_ file.");
  1351.         g1m__count++;
  1352.        }
  1353.      // PING
  1354.      else if(type == 0x89504E47) {
  1355.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (PING)." << endl;
  1356.         stringstream name;
  1357.         name << setfill('0') << setw(4) << ping_count << ".png" << ends;
  1358.         ofstream ofile(name.str().c_str(), ios::binary);
  1359.         if(!ofile) return error("Failed to create png file.");
  1360.         ofile.write(data.get(), filesize);
  1361.         if(ofile.fail()) return error("Failed to write to png file.");
  1362.         ping_count++;
  1363.        }
  1364.  
  1365.      // IGNORE BNS file
  1366.      else if(type == 0x4731415F) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (G1A_)." << endl;
  1367.      else if(type == 0x02) {
  1368.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (002)." << endl;
  1369.         stringstream name;
  1370.         name << setfill('0') << setw(4) << d002_count << ".002" << ends;
  1371.         ofstream ofile(name.str().c_str(), ios::binary);
  1372.         if(!ofile) return error("Failed to create 002 file.");
  1373.         ofile.write(data.get(), filesize);
  1374.         if(ofile.fail()) return error("Failed to write to 002 file.");
  1375.         d002_count++;
  1376.        }
  1377.      else if(type == 0x03) {
  1378.         cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (003)." << endl;
  1379.         stringstream name;
  1380.         name << setfill('0') << setw(4) << d003_count << ".003" << ends;
  1381.         ofstream ofile(name.str().c_str(), ios::binary);
  1382.         if(!ofile) return error("Failed to create 003 file.");
  1383.         ofile.write(data.get(), filesize);
  1384.         if(ofile.fail()) return error("Failed to write to 003 file.");
  1385.         d003_count++;
  1386.        }
  1387.      // INGORE file
  1388.      else if(type == 0x0CFFFFFF) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x0CFFFFFF)." << endl;
  1389.      else if(type == 0x53FF0A00) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x53FF0A00)." << endl;
  1390.      else if(type == 0x64000000) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x64000000)." << endl;
  1391.  
  1392.      else if(type == 0x04) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x04)." << endl;
  1393.      else if(type == 0x06) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x06)." << endl;
  1394.      else if(type == 0x0A) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x0A)." << endl;
  1395.      else if(type == 0x0C) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x0C)." << endl;
  1396.      else if(type == 0x0D) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x0D)." << endl;
  1397.      else if(type == 0x10) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x10)." << filetable[i].first*headScale << endl;
  1398.      else if(type == 0x14) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x14)." << endl;
  1399.      else if(type == 0x16) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x16)." << endl;
  1400.      else if(type == 0x26) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x26)." << endl;
  1401.      else if(type == 0x32) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x32)." << endl;
  1402.      else if(type == 0x35) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x35)." << endl;
  1403.      else if(type == 0x46) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x46)." << endl;
  1404.      else if(type == 0x49) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x49)." << endl;
  1405.      else if(type == 0x64) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x64)." << endl;
  1406.      else if(type == 0x65) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x65)." << endl;
  1407.      else if(type == 0x67) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x67)." << endl;
  1408.      else if(type == 0x4E) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x4E)." << endl;
  1409.      else if(type == 0x72) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x72)." << endl;
  1410.      else if(type == 0x80) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x80)." << endl;
  1411.      else if(type == 0x149) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x149)." << endl;
  1412.      else if(type == 0x190) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x190)." << endl;
  1413.      else if(type == 0x1A4) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x1A4)." << endl;
  1414.      else if(type == 0x297) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x297)." << endl;
  1415.      else if(type == 0x29C) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x29C)." << endl;
  1416.      else if(type == 0x2A1) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x2A1)." << endl;
  1417.      else if(type == 0x717) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x717)." << endl;
  1418.      else if(type >= 0x001 && type <= 0x00F) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (CRAP BETWEEN 0x001 and 0x00F)." << endl;
  1419.      else if(type >= 0x010 && type <= 0x0FF) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (CRAP BETWEEN 0x010 and 0x0FF)." << endl;
  1420.      else if(type >= 0x100 && type <= 0xFFF) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (CRAP BETWEEN 0x100 and 0xFFF)." << endl;
  1421.      else if(type == 0x10063) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x10063)." << endl;
  1422.      else if(type == 0x10100) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x10100)." << endl;
  1423.      else if(type == 0x20063) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x20063)." << endl;
  1424.      else if(type == 0x200A9) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x200A9)." << endl;
  1425.      else if(type == 0x300A1) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x300A1)." << endl;
  1426.      else if(type == 0x30100) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x30100)." << endl;
  1427.      else if(type == 0x40033) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x40033)." << endl;
  1428.      else if(type == 0x40080) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x40080)." << endl;
  1429.      else if(type == 0x50032) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x50032)." << endl;
  1430.      else if(type == 0x50227) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x50227)." << endl;
  1431.      else if(type == 0x60041) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x60041)." << endl;
  1432.      else if(type == 0x601C2) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x601C2)." << endl;
  1433.      else if(type == 0x70023) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x70023)." << endl;
  1434.      else if(type == 0x70227) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x70227)." << endl;
  1435.      else if(type == 0x8002D) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x8002D)." << endl;
  1436.      else if(type == 0x80190) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x80190)." << endl;
  1437.      else if(type == 0x9002C) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x9002C)." << endl;
  1438.      else if(type == 0x9004D) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x9004D)." << endl;
  1439.      else if(type == 0xA0019) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0xA0019)." << endl;
  1440.      else if(type == 0xA0050) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0xA0050)." << endl;
  1441.      else if(type == 0xB0011) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0xB0011)." << endl;
  1442.      else if(type == 0xB0065) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0xB0065)." << endl;
  1443.      else if(type == 0xC000D) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0xC000D)." << endl;
  1444.      else if(type == 0xC0032) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0xC0032)." << endl; // last one checked... tired! at 0x542D000
  1445.      else if(type == 0xD000B) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0xD000B)." << endl;
  1446.      else if(type == 0xE0100) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0xE0100)." << endl;
  1447.      else if(type == 0xF00A1) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0xF00A1)." << endl;
  1448.      else if(type >= 0x10000 && type <= 0xFFFFFF) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0xCRAP)." << endl;
  1449.      else if(type == 0x100046) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x100046)." << endl;
  1450.      else if(type == 0x110020) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x110020)." << endl;
  1451.      else if(type == 0x1202EB) cout << "Reading section " << (i + 1) << " of " << filetable.size() << " (0x1202EB)." << endl;
  1452.      else {
  1453.         cout << "curr position = " << filetable[i].first*headScale << endl;
  1454.         cout << "curr filesize = " << filetable[i].second << endl;
  1455.         cout << "next position = " << filetable[i + 1].first*headScale << endl;
  1456.         cout << "next filesize = " << filetable[i + 1].second << endl;
  1457.         return false;
  1458.        }
  1459.     }
  1460. */
  1461.  cout << endl;
  1462.  return true;
  1463. }
  1464.  
  1465. bool ExtractDLC(const char* filename)
  1466. {
  1467.  return true;
  1468. }
  1469.  
  1470. bool Extract002(const binary_stream& bs, const char* path)
  1471. {
  1472.  /*
  1473.  ** 002 SECTION
  1474.  ** NOTE: This section appears to contain crap geometry and textures that
  1475.  ** are not important. It uses a crazy, fucked up vertex and index buffer
  1476.  ** format that I don't really want to mess with.
  1477.  */
  1478.  
  1479.  // skip
  1480.  return true;
  1481.  
  1482.  // binary stream iterator
  1483.  binary_stream ss(bs);
  1484.  
  1485.  // read 0002 header
  1486.  uint32 magic = ss.BE_read_uint32(); // magic
  1487.  uint32 start = ss.BE_read_uint32(); // start of data
  1488.  uint32 size  = ss.BE_read_uint32(); // size of 0002 section
  1489.  uint32 unk1  = ss.BE_read_uint32(); // 0xFFFFFFFF
  1490.  
  1491.  // read KTFK header
  1492.  uint32 ktfk_name = ss.BE_read_uint32(); // KTFK
  1493.  uint32 ktfk_vers = ss.BE_read_uint32(); // version
  1494.  uint32 ktfk_unk1 = ss.BE_read_uint32(); // 0x02
  1495.  uint32 ktfk_size = ss.BE_read_uint32(); // size of KTFK section
  1496.  
  1497.  // read four offsets
  1498.  uint32 ktfk_offset1 = start + ss.BE_read_uint32(); // offset to G1TG (ignore)
  1499.  uint32 ktfk_offset2 = start + ss.BE_read_uint32(); // offset to G1TG (ignore)
  1500.  uint32 ktfk_offset3 = start + ss.BE_read_uint32(); // offset to G1TG (ignore)
  1501.  uint32 ktfk_offset4 = start + ss.BE_read_uint32(); // offset to KHM_ (ignore)
  1502.  
  1503.  // read KTFK header
  1504.  struct KTFKHEADER {
  1505.   uint32 unk01;     // 0x01 or 0x02
  1506.   uint32 unk02;     // 0x04
  1507.   uint32 unk03;     // 0x0155
  1508.   uint32 unk04;     // 0x0100
  1509.   uint32 unk05;     // a section size/0x10
  1510.   uint32 unk06;     // number of entries
  1511.   uint32 vbuffsize; // v-buffer size
  1512.   uint32 ibuffsize; // i-buffer size
  1513.  };
  1514.  KTFKHEADER ktfk;
  1515.  ktfk.unk01 = ss.BE_read_uint32();
  1516.  ktfk.unk02 = ss.BE_read_uint32();
  1517.  ktfk.unk03 = ss.BE_read_uint32();
  1518.  ktfk.unk04 = ss.BE_read_uint32();
  1519.  ktfk.unk05 = ss.BE_read_uint32();
  1520.  ktfk.unk06 = ss.BE_read_uint32();
  1521.  ktfk.vbuffsize = ss.BE_read_uint32();
  1522.  ktfk.ibuffsize = ss.BE_read_uint32();
  1523.  
  1524.  // skip to vertex data
  1525.  binary_stream::size_type position = 0;
  1526.  position += 0x10;            // 0002 header
  1527.  position += 0x40;            // KTFK header
  1528.  position += 0x60;            // unknown data
  1529.  position += ktfk.unk01*0x20; // unknown data
  1530.  position += 0xC8;            // unknown data
  1531.  position += ktfk.unk03*0x40; // unknown data
  1532.  position += ktfk.unk05*0x10; // unknown data
  1533.  position += ktfk.unk06*0x18; // unknown data
  1534.  position += ktfk.unk05*0x08; // unknown data
  1535.  ss.seek(position);
  1536.  
  1537.  // geometry data
  1538.  deque<VERTEX_BUFFER> vblist;
  1539.  deque<INDEX_BUFFER> fdlist;
  1540.  
  1541.  // create vertex buffer
  1542.  VERTEX_BUFFER vb;
  1543.  vb.flags = VERTEX_POSITION;
  1544.  vb.elem = ktfk.vbuffsize/0x10;
  1545.  vb.data.reset(new VERTEX[vb.elem]);
  1546.  
  1547.  // fill vertex buffer
  1548.  for(size_t i = 0; i < vb.elem; i++)
  1549.     {
  1550.      // load vertex
  1551.      float x = (float)ss.BE_read_sint16()/32767.0f;
  1552.      (float)ss.BE_read_sint16()/32767.0f;
  1553.      float y = (float)ss.BE_read_sint16()/32767.0f;
  1554.      (float)ss.BE_read_sint16()/32767.0f;
  1555.      (float)ss.BE_read_sint16()/32767.0f;
  1556.      (float)ss.BE_read_sint16()/32767.0f;
  1557.      (float)ss.BE_read_sint16()/32767.0f;
  1558.      float z = (float)ss.BE_read_sint16()/32767.0f;
  1559.  
  1560.      // save vertex
  1561.      VERTEX v;
  1562.      v.vx = x;
  1563.      v.vy = y;
  1564.      v.vz = z;
  1565.      vb.data[i] = v;
  1566.     }
  1567.  
  1568.  // fill index buffer
  1569.  INDEX_BUFFER ib;
  1570.  ib.format = FACE_FORMAT_UINT_16;
  1571.  ib.type = FACE_TYPE_TRISTRIP;
  1572.  ib.name = "default";
  1573.  ib.reference = 0;
  1574.  ib.elem = ktfk.ibuffsize/0x02;
  1575.  ib.data.reset(new char[ktfk.ibuffsize]);
  1576.  ss.BE_read(reinterpret_cast<uint16*>(ib.data.get()), ib.elem);
  1577.  
  1578.  // insert buffers and convert to OBJ
  1579.  vblist.push_back(vb);
  1580.  fdlist.push_back(ib);
  1581.  //GeometryToOBJ("test", vblist, fdlist);
  1582.  
  1583.  return true;
  1584. }
  1585.  
  1586. struct GENERIC_SECTION {
  1587.  uint32 sign;
  1588.  uint32 size;
  1589.  uint32 offset1;
  1590.  uint32 offset2;
  1591. };
  1592.  
  1593. bool Extract003(const binary_stream& bs, const char* path)
  1594. {
  1595.  // binary stream iterator
  1596.  binary_stream ss(bs);
  1597.  
  1598.  deque<size_t> texture_list;
  1599.  deque<size_t> model_list;
  1600.  
  1601.  binary_stream::size_type index = ss.search("G1TG00", 6, 0);
  1602.  while(index != binary_stream::npos) {
  1603.        cout << "index = " << index << endl;
  1604.        texture_list.push_back(index);
  1605.        index = ss.search("G1TG00", 6, index + 1);
  1606.        if(index == binary_stream::npos) break;
  1607.       }
  1608.  
  1609.  index = ss.search("G1M_00", 6, 0);
  1610.  while(index != binary_stream::npos) {
  1611.        cout << "index = " << index << endl;
  1612.        model_list.push_back(index);
  1613.        index = ss.search("G1M_00", 6, index + 1);
  1614.        if(index == binary_stream::npos) break;
  1615.       }
  1616.  
  1617.  for(size_t i = 0; i < texture_list.size(); i++)
  1618.     {
  1619.      ss.seek(texture_list[i]);
  1620.      ExtractG1TG0060(ss, path, i);
  1621.     }
  1622.  
  1623.  return true;
  1624. }
  1625.  
  1626. bool ExtractModels(const binary_stream& bs, const char* path, size_t item)
  1627. {
  1628.  // create a folder for this file
  1629.  if(CreateDirectoryA(path, NULL) == 0)
  1630.     if(GetLastError() == ERROR_PATH_NOT_FOUND)
  1631.        return error("Could not create directory for model files.");
  1632.  
  1633.  // binary stream iterator and current position
  1634.  binary_stream ss(bs);
  1635.  binary_stream::size_type start = ss.tell();
  1636.  
  1637.  // create model filename (without extension, geometry function will take care of extension)
  1638.  stringstream filename;
  1639.  filename << path << "\\" << "G1MG_" << setfill('0') << setw(3) << item << ends;
  1640.  
  1641.  // read header
  1642.  G1MG0044_HEADER head;
  1643.  ss.BE_read_uint32(); // magic
  1644.  ss.BE_read_uint32(); // version
  1645.  ss.BE_read_uint32(); // size
  1646.  head.platform = ss.BE_read_uint32();
  1647.  head.unknown1 = ss.BE_read_uint32();
  1648.  ss.BE_read(&head.bbox_min[0], 3);
  1649.  ss.BE_read(&head.bbox_max[0], 3);
  1650.  head.sections = ss.BE_read_uint32();
  1651.  
  1652.  // read sections
  1653.  deque<G1MG0044_ITEMDATA> itemdata;
  1654.  for(size_t i = 0; i < head.sections; i++) {
  1655.      G1MG0044_ITEMDATA item;
  1656.      item.type = ss.BE_read_uint32();
  1657.      item.size = ss.BE_read_uint32();
  1658.      item.data.reset(new char[item.size - 0x8]);
  1659.      ss.read(item.data.get(), item.size - 0x8);
  1660.      itemdata.push_back(item);
  1661.     }
  1662.  
  1663.  // data to save
  1664.  deque<VERTEX_BUFFER> vdlist;
  1665.  deque<INDEX_BUFFER> fdlist;
  1666.  
  1667.  // process section data
  1668.  for(size_t i = 0; i < itemdata.size(); i++)
  1669.     {
  1670.      // vertex section
  1671.      if(itemdata[i].type == 0x00010004)
  1672.        {
  1673.         // stringstream from data
  1674.         stringstream ss(ios_base::out | ios_base::in | ios_base::binary);
  1675.         ss.write(itemdata[i].data.get(), itemdata[i].size - 0x8);
  1676.         ss.seekg(0);
  1677.  
  1678.         // read vertex sections
  1679.         uint32 meshes = BE_read_uint32(ss);
  1680.         for(size_t j = 0; j < meshes; j++)
  1681.            {
  1682.             // read mesh vertex info
  1683.             G1MG0044_VERTEXDATA vd;
  1684.             vd.unknown1 = BE_read_uint32(ss);
  1685.             vd.vertsize = BE_read_uint32(ss);
  1686.             vd.vertices = BE_read_uint32(ss);
  1687.             vd.unknown2 = BE_read_uint32(ss);
  1688.  
  1689.             // set vertex buffer properties
  1690.             VERTEX_BUFFER vb;
  1691.             vb.elem = vd.vertices;
  1692.             vb.flags = 0;
  1693.             vb.data.reset(new VERTEX[vd.vertices]);
  1694.  
  1695.             // set vertex buffer flags
  1696.             if(vd.vertsize == 0x10) {
  1697.                vb.flags |= VERTEX_POSITION;
  1698.                vb.flags |= VERTEX_NORMAL;
  1699.                //vb.flags |= VERTEX_UV;
  1700.               }
  1701.             else if(vd.vertsize == 0x14) {
  1702.                vb.flags |= VERTEX_POSITION;
  1703.                vb.flags |= VERTEX_NORMAL;
  1704.                vb.flags |= VERTEX_UV;
  1705.               }
  1706.             else if(vd.vertsize == 0x18) {
  1707.                vb.flags |= VERTEX_POSITION;
  1708.                vb.flags |= VERTEX_NORMAL;
  1709.                vb.flags |= VERTEX_UV;
  1710.               }
  1711.             else if(vd.vertsize == 0x1C) {
  1712.                vb.flags |= VERTEX_POSITION;
  1713.                vb.flags |= VERTEX_NORMAL;
  1714.                vb.flags |= VERTEX_UV;
  1715.               }
  1716.             else if(vd.vertsize == 0x20) {
  1717.                vb.flags |= VERTEX_POSITION;
  1718.                vb.flags |= VERTEX_NORMAL;
  1719.                vb.flags |= VERTEX_UV;
  1720.               }
  1721.             else if(vd.vertsize == 0x24) {
  1722.                vb.flags |= VERTEX_POSITION;
  1723.                vb.flags |= VERTEX_NORMAL;
  1724.                vb.flags |= VERTEX_UV;
  1725.               }
  1726.             else
  1727.                return error("Unknown vertex format.");
  1728.  
  1729.             // read vertices
  1730.             for(size_t k = 0; k < vd.vertices; k++)
  1731.                {
  1732.                 VERTEX vertex;
  1733.                 if(vd.vertsize == 0x10) { // OK
  1734.                    vertex.vx = BE_read_float16(ss);
  1735.                    vertex.vy = BE_read_float16(ss);
  1736.                    vertex.vz = BE_read_float16(ss);
  1737.                    BE_read_float16(ss);
  1738.                    vertex.nx = BE_read_float16(ss);
  1739.                    vertex.ny = BE_read_float16(ss);
  1740.                    vertex.nz = BE_read_float16(ss);
  1741.                    BE_read_float16(ss);
  1742.                   }
  1743.                 else if(vd.vertsize == 0x14) { // OK
  1744.                    vertex.vx = BE_read_float16(ss);
  1745.                    vertex.vy = BE_read_float16(ss);
  1746.                    vertex.vz = BE_read_float16(ss);
  1747.                    BE_read_float16(ss);
  1748.                    vertex.nx = BE_read_float16(ss);
  1749.                    vertex.ny = BE_read_float16(ss);
  1750.                    vertex.nz = BE_read_float16(ss);
  1751.                    BE_read_float16(ss);
  1752.                    vertex.tu = BE_read_float16(ss);
  1753.                    vertex.tv = 1.0f - BE_read_float16(ss);
  1754.                   }
  1755.                 else if(vd.vertsize == 0x18) { // OK
  1756.                    vertex.vx = BE_read_float16(ss);
  1757.                    vertex.vy = BE_read_float16(ss);
  1758.                    vertex.vz = BE_read_float16(ss);
  1759.                    BE_read_float16(ss);
  1760.                    BE_read_float16(ss);
  1761.                    BE_read_float16(ss);
  1762.                    vertex.nx = BE_read_float16(ss);
  1763.                    vertex.ny = BE_read_float16(ss);
  1764.                    vertex.nz = BE_read_float16(ss);
  1765.                    BE_read_float16(ss);            
  1766.                    vertex.tu = BE_read_float16(ss);
  1767.                    vertex.tv = 1.0f - BE_read_float16(ss);
  1768.                   }
  1769.                 else if(vd.vertsize == 0x1C) { // OK
  1770.                    vertex.vx = BE_read_float16(ss);
  1771.                    vertex.vy = BE_read_float16(ss);
  1772.                    vertex.vz = BE_read_float16(ss);
  1773.                    BE_read_float16(ss);
  1774.                    BE_read_float16(ss);
  1775.                    BE_read_float16(ss);
  1776.                    BE_read_float16(ss);
  1777.                    BE_read_float16(ss);
  1778.                    vertex.nx = BE_read_float16(ss);
  1779.                    vertex.ny = BE_read_float16(ss);
  1780.                    vertex.nz = BE_read_float16(ss);
  1781.                    BE_read_float16(ss);
  1782.                    vertex.tu = BE_read_float16(ss);
  1783.                    vertex.tv = 1.0f - BE_read_float16(ss);
  1784.                   }
  1785.                 else if(vd.vertsize == 0x20) { // OK
  1786.                    vertex.vx = BE_read_float16(ss);
  1787.                    vertex.vy = BE_read_float16(ss);
  1788.                    vertex.vz = BE_read_float16(ss);
  1789.                    BE_read_float16(ss);
  1790.                    BE_read_float32(ss); // ok (sum is 1) possibly weight?
  1791.                    BE_read_float32(ss); // ok (sum is 1) possibly weight?
  1792.                    BE_read_float16(ss);
  1793.                    vertex.nx = BE_read_float16(ss);
  1794.                    vertex.ny = BE_read_float16(ss);
  1795.                    vertex.nz = BE_read_float16(ss);
  1796.                    BE_read_float32(ss);
  1797.                    vertex.tu = BE_read_float16(ss);
  1798.                    vertex.tv = 1.0f - BE_read_float16(ss);
  1799.                   }
  1800.                 else if(vd.vertsize == 0x24) {
  1801.                    vertex.vx = BE_read_float32(ss);
  1802.                    vertex.vy = BE_read_float32(ss);
  1803.                    vertex.vz = BE_read_float32(ss);
  1804.                    vertex.nx = BE_read_float32(ss);
  1805.                    vertex.ny = BE_read_float32(ss);
  1806.                    vertex.nz = BE_read_float32(ss);
  1807.                    BE_read_float32(ss);
  1808.                    vertex.tu = BE_read_float32(ss);
  1809.                    vertex.tv = BE_read_float32(ss);
  1810.                    return error("0x24 VERTEX TYPE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
  1811.                   }
  1812.                 else return error("Unknown vertex format.");
  1813.  
  1814.                 // save vertex
  1815.                 vb.data[k] = vertex;
  1816.                }
  1817.  
  1818.             // save vertex data
  1819.             vdlist.push_back(vb);
  1820.            }
  1821.        }
  1822.      // index buffer section
  1823.      else if(itemdata[i].type == 0x00010007)
  1824.        {
  1825.         // stringstream from data
  1826.         stringstream ss(ios_base::out | ios_base::in | ios_base::binary);
  1827.         ss.write(itemdata[i].data.get(), itemdata[i].size - 0x8);
  1828.         ss.seekg(0);
  1829.  
  1830.         // read face sections
  1831.         uint32 n_meshes = BE_read_uint32(ss);
  1832.         uint32 vb_index = 0;
  1833.         for(size_t j = 0; j < n_meshes; j++)
  1834.            {
  1835.             // read face data
  1836.             G1MG0044_FACEDATA fd;
  1837.             fd.numindex = BE_read_uint32(ss);
  1838.             fd.datatype = BE_read_uint32(ss);
  1839.             fd.unknown1 = BE_read_uint32(ss);
  1840.  
  1841.             // set index buffer properties
  1842.             INDEX_BUFFER ib;
  1843.             ib.type = FACE_TYPE_TRISTRIP;
  1844.             ib.elem = fd.numindex;
  1845.             if(fd.datatype == 0x10) ib.format = FACE_FORMAT_UINT_16;
  1846.             else if(fd.datatype == 0x20) ib.format = FACE_FORMAT_UINT_32;
  1847.             else return error("Unknown index buffer data format.");
  1848.  
  1849.             // set index buffer name
  1850.             stringstream surface;
  1851.             surface << setfill('0') << setw(3) << item << "_" << setw(3) << j << ends;
  1852.             ib.name = surface.str();
  1853.  
  1854.             // determine index buffer data type size
  1855.             unsigned int typesize = 0;
  1856.             if(fd.datatype == 0x10) typesize = sizeof(uint16);
  1857.             else if(fd.datatype == 0x20) typesize = sizeof(uint32);
  1858.             else return error("Unknown index buffer data type.");
  1859.  
  1860.             // read face data
  1861.             unsigned int total_bytes = ib.elem * typesize;
  1862.             ib.data.reset(new char[total_bytes]);
  1863.             if(ib.format == FACE_FORMAT_UINT_16) BE_read_array(ss, reinterpret_cast<uint16*>(ib.data.get()), ib.elem);
  1864.             else if(ib.format == FACE_FORMAT_UINT_32) BE_read_array(ss, reinterpret_cast<uint32*>(ib.data.get()), ib.elem);
  1865.  
  1866.             // test face data
  1867.             uint32 min_index = 0;
  1868.             uint32 max_index = 0;
  1869.             if(ib.format == FACE_FORMAT_UINT_16) {
  1870.                uint16 a; minimum(reinterpret_cast<uint16*>(ib.data.get()), ib.elem, a);
  1871.                uint16 b; maximum(reinterpret_cast<uint16*>(ib.data.get()), ib.elem, b);
  1872.                min_index = a;
  1873.                max_index = b;
  1874.               }
  1875.             else if(ib.format == FACE_FORMAT_UINT_32) {
  1876.                uint32 a; minimum(reinterpret_cast<uint32*>(ib.data.get()), ib.elem, a);
  1877.                uint32 b; maximum(reinterpret_cast<uint32*>(ib.data.get()), ib.elem, b);
  1878.                min_index = a;
  1879.                max_index = b;
  1880.               }
  1881.  
  1882.             // set vertex buffer reference
  1883.             if(min_index == 0) vb_index++;
  1884.             if(vb_index > 0) ib.reference = vb_index - 1;
  1885.             else return error("Unexpected vertex buffer reference.");
  1886.  
  1887.             // save face data
  1888.             fdlist.push_back(ib);
  1889.            }
  1890.        }
  1891.     }
  1892.  
  1893.  // save geometry
  1894.  stringstream objname;
  1895.  objname << "G1MG_" << setfill('0') << setw(3) << item << ends;
  1896.  if(!GeometryToOBJ(path, objname.str().c_str(), vdlist, fdlist)) return false;
  1897.  return true;
  1898. }
  1899.  
  1900. bool ExtractG1TG0060(const binary_stream& bs, const char* path, size_t item)
  1901. {
  1902.  // create a folder for this file
  1903.  if(CreateDirectoryA(path, NULL) == 0)
  1904.     if(GetLastError() == ERROR_PATH_NOT_FOUND)
  1905.        return error("Could not create directory for texture files.");
  1906.  
  1907.  // binary stream iterator and current position
  1908.  binary_stream ss(bs);
  1909.  binary_stream::size_type start = ss.tell();
  1910.  
  1911.  // read header
  1912.  uint32 magic = ss.BE_read_uint32();
  1913.  uint32 version = ss.BE_read_uint32();
  1914.  uint32 section_size = ss.BE_read_uint32();
  1915.  uint32 table_offset = ss.BE_read_uint32();
  1916.  uint32 n_textures = ss.BE_read_uint32();
  1917.  
  1918.  // validate header
  1919.  if(magic != 0x47315447) return error("Expecting G1TG section.");
  1920.  if(!(version == 0x30303530 || version == 0x30303630)) return error("Invalid G1TG version.");
  1921.  if(n_textures == 0) return error("Invalid number of textures.");
  1922.  if(n_textures >= 1000) return error("Excessive number of texture. We really don't expect to have this many in a single file.");
  1923.  
  1924.  // move to table
  1925.  ss.seek(start + table_offset);
  1926.  if(ss.fail()) return error("Stream seek failure.");
  1927.  
  1928.  // read offset table
  1929.  deque<size_t> offset_list;
  1930.  for(size_t i = 0; i < n_textures; i++) {
  1931.      offset_list.push_back(ss.BE_read_uint32());
  1932.      if(ss.fail()) return error("Stream read failure.");
  1933.     }
  1934.  
  1935.  // process textures
  1936.  for(size_t i = 0; i < offset_list.size(); i++)
  1937.     {
  1938.      ss.seek(start + table_offset + offset_list[i]);
  1939.      if(ss.fail()) return error("Stream seek failure.");
  1940.  
  1941.      // read texture information
  1942.      uint08 b1 = ss.BE_read_uint08(); // unknown
  1943.      uint08 b2 = ss.BE_read_uint08(); // texture type
  1944.      uint08 b3 = ss.BE_read_uint08(); // dx/dy
  1945.      uint08 b4 = ss.BE_read_uint08(); // unknown
  1946.      uint16 s1 = ss.BE_read_uint16(); // unknown
  1947.      uint16 s2 = ss.BE_read_uint16(); // unknown
  1948.  
  1949.      // header is extended depending on version
  1950.      size_t header_size = 8;
  1951.      if(version == 0x30303630) {
  1952.         uint32 v1 = ss.BE_read_uint32(); // 12
  1953.         uint32 v2 = ss.BE_read_uint32(); // 0
  1954.         uint32 v3 = ss.BE_read_uint32(); // 0 or 1
  1955.         header_size += 12;
  1956.        }
  1957.  
  1958.      // compute dimensions
  1959.      uint32 temp1 = ((b3 & 0xF0) >> 4);
  1960.      uint32 temp2 = ((b3 & 0x0F));
  1961.      uint32 dx = 1 << temp1;
  1962.      uint32 dy = 1 << temp2;
  1963.  
  1964.      // create texture file
  1965.      stringstream filename;
  1966.      if(item) filename << path << "/" << "G1TG_" << setfill('0') << setw(3) << item << "_" << setfill('0') << setw(3) << i << ".dds" << ends;
  1967.      else filename << path << "/" << "G1TG_" << setfill('0') << setw(3) << i << ".dds" << ends;
  1968.      ofstream ofile(filename.str().c_str(), ios::binary);
  1969.  
  1970.      // save texture
  1971.      if(b2 == 0)
  1972.        {
  1973.         // read texture
  1974.         DWORD filesize = UncompressedDDSFileSize(dx, dy, 0, 0xFF000000, 0xFF0000, 0xFF00, 0xFF);
  1975.         boost::shared_array<char> buffer(new char[filesize]);
  1976.         ss.read((char*)buffer.get(), filesize);
  1977.  
  1978.         // save texture
  1979.         DDS_HEADER ddsh;
  1980.         CreateUncompressedDDSHeader(dx, dy, 0, 0xFF0000, 0xFF00, 0xFF, 0xFF000000, FALSE, &ddsh);
  1981.         DWORD signature = 0x20534444;
  1982.         ofile.write((char*)&signature, sizeof(signature));
  1983.         ofile.write((char*)&ddsh, sizeof(ddsh));
  1984.         ofile.write((char*)buffer.get(), filesize);
  1985.  
  1986.         // LINKDATA_BNS/013/G1TG_000.dds
  1987.         // LINKDATA_BNS/018/G1TG_000.dds
  1988.         // LINKDATA_BNS/027/G1TG_006.dds
  1989.         // LINKDATA_BNS/028/G1TG_000.dds
  1990.         // LINKDATA_BNS/028/G1TG_001.dds
  1991.         // LINKDATA_BNS/028/G1TG_003.dds
  1992.         // LINKDATA_BNS/909/G1TG_000.dds
  1993.  
  1994.        }
  1995.      // UNCOMPRESSED DDS (PS3 works good)
  1996.      else if(b2 == 1)
  1997.        {
  1998.         // read texture
  1999.         DWORD filesize = UncompressedDDSFileSize(dx, dy, 0, 0xFF, 0xFF00, 0xFF0000, 0xFF000000);
  2000.         boost::shared_array<char> buffer(new char[filesize]);
  2001.         ss.read((char*)buffer.get(), filesize);
  2002.  
  2003.         // save texture
  2004.         DDS_HEADER ddsh;
  2005.         CreateUncompressedDDSHeader(dx, dy, 0, 0xFF000000, 0xFF0000, 0xFF00, 0xFF, FALSE, &ddsh);
  2006.         DWORD signature = 0x20534444;
  2007.         ofile.write((char*)&signature, sizeof(signature));
  2008.         ofile.write((char*)&ddsh, sizeof(ddsh));
  2009.         ofile.write((char*)buffer.get(), filesize);
  2010.        }
  2011.      // DXT1 (PS3 works good)
  2012.      else if(b2 == 6)
  2013.        {
  2014.         // read texture
  2015.         DWORD filesize = DXT1Filesize(dx, dy, 0);
  2016.         boost::shared_array<char> buffer(new char[filesize]);
  2017.         ss.read((char*)buffer.get(), filesize);
  2018.  
  2019.         // save texture
  2020.         DDS_HEADER ddsh;
  2021.         CreateDXT1Header(dx, dy, 0, FALSE, &ddsh);
  2022.         DWORD signature = 0x20534444;
  2023.         ofile.write((char*)&signature, sizeof(signature));
  2024.         ofile.write((char*)&ddsh, sizeof(ddsh));
  2025.         ofile.write((char*)buffer.get(), filesize);
  2026.        }
  2027.      // DXT5 (PS3 works good)
  2028.      else if(b2 == 8)
  2029.        {
  2030.         // read texture
  2031.         DWORD filesize = DXT5Filesize(dx, dy, 0);
  2032.         boost::shared_array<char> buffer(new char[filesize]);
  2033.         ss.read((char*)buffer.get(), filesize);
  2034.  
  2035.         // save texture
  2036.         DDS_HEADER ddsh;
  2037.         CreateDXT5Header(dx, dy, 0, FALSE, &ddsh);
  2038.         DWORD signature = 0x20534444;
  2039.         ofile.write((char*)&signature, sizeof(signature));
  2040.         ofile.write((char*)&ddsh, sizeof(ddsh));
  2041.         ofile.write((char*)buffer.get(), filesize);
  2042.        }
  2043.      // ???
  2044.      else if(b2 == 16)
  2045.        {
  2046.         cout << "FAILED" << endl;
  2047.         cout <<  filename.str() << endl;
  2048.  
  2049.         cout << "Unknown texture type = " << (int)b2 << endl;
  2050.         cout << " dx = " << dx << endl;
  2051.         cout << " dy = " << dy << endl;
  2052.        }
  2053.      // ???
  2054.      else if(b2 == 18)
  2055.        {
  2056.         cout << "FAILED" << endl;
  2057.         cout <<  filename.str() << endl;
  2058.  
  2059.         cout << "Unknown texture type = " << (int)b2 << endl;
  2060.         cout << " dx = " << dx << endl;
  2061.         cout << " dy = " << dy << endl;
  2062.        }
  2063.      else {
  2064.         return error("Unsupported texture type.");
  2065.        }
  2066.     }
  2067.  
  2068.  return true;
  2069. }
  2070.  
  2071. };};