home *** CD-ROM | disk | FTP | other *** search
- #include "xentax.h"
- #include "x_findfile.h"
- #include "x_file.h"
- #include "x_stream.h"
- #include "x_dds.h"
- #include "x_lwo.h"
- #include "x_smc.h"
- #include "x_pssg.h"
-
- namespace PSSG {
-
- struct PSSGPARAMETER {
- std::string name;
- };
-
- struct PSSGATTRIBUTE {
- std::string parameter;
- std::string attribute;
- };
-
- struct BUFFERDATA {
- uint32 elementCount;
- std::string renderType;
- std::string dataType;
- uint32 offset;
- uint32 stride;
- boost::shared_array<char> data;
- };
-
- struct RENDERDATA {
- uint32 streamCount; // RENDERDATASOURCE:streamCount
- std::string primitive; // RENDERINDEXSOURCE:primitive (if any)
- std::string format; // RENDERINDEXSOURCE:format (if any)
- uint32 count; // RENDERINDEXSOURCE:count (if any)
- std::string id; // RENDERINDEXSOURCE:id (if any)
- boost::shared_array<char> buffer; // INDEXSOURCEDATA:data (if any)
- boost::shared_array<std::string> blocks; // RENDERSTREAM[streamCount]:dataBlock (reference to Vertex, Normal, ST buffers)
- };
-
- class extractor {
- private :
- std::string pathname;
- std::string currfile;
- std::ofstream dfile;
- bool debug;
- // tree nodes
- private:
- std::map<uint32, PSSGPARAMETER> nodelist;
- std::map<uint32, PSSGATTRIBUTE> attrlist;
- std::deque<uint32> offsets;
- std::map<uint32, uint32> parent_list;
- // tree
- private :
- typedef std::map<uint32, boost::shared_ptr<TREENODE>> tree_type;
- typedef tree_type::iterator tree_iterator;
- typedef tree_type::value_type tree_node;
- std::map<uint32, boost::shared_ptr<TREENODE>> tree;
- // buffer map (vtx buffers)
- private :
- typedef std::map<std::string, BUFFERDATA> buffer_map_type;
- typedef std::map<std::string, BUFFERDATA>::value_type buffer_map_value_type;
- std::map<std::string, BUFFERDATA> buffer_map; // store buffers by name
- // render map (idx buffers)
- private :
- typedef std::map<std::string, RENDERDATA> render_map_type;
- typedef std::map<std::string, RENDERDATA>::value_type render_map_value_type;
- std::map<std::string, RENDERDATA> render_map; // store buffers by name
- private :
- bool readAttributes(binary_stream& bs, const char* name);
- bool readString(binary_stream& bs, std::string& str) {
- uint32 size = bs.BE_read_uint32();
- if(bs.fail()) return false;
- char buffer[1024];
- bs.read(buffer, size);
- if(bs.fail()) return false;
- buffer[size] = '\0';
- str = buffer;
- return true;
- }
- bool readNumber(binary_stream& bs, uint32& data) {
- data = bs.BE_read_uint32();
- return !bs.fail();
- }
- bool readVector3(binary_stream& bs, real32* data) {
- data[0] = bs.BE_read_real32(); if(bs.fail()) return false;
- data[1] = bs.BE_read_real32(); if(bs.fail()) return false;
- data[2] = bs.BE_read_real32(); if(bs.fail()) return false;
- return true;
- }
- private :
- void clear(void);
- bool processFile(const char* filename);
- bool processParameter(const binary_stream& bs);
- bool processChildren(const binary_stream& bs, boost::shared_ptr<TREENODE> node, uint32 parent, uint32 limit);
- bool processTree(unsigned int node, unsigned int level);
- bool processVertexBuffer(tree_iterator iter);
- bool processRenderBuffer(tree_iterator iter);
- bool processModel(void)const;
- private :
- bool processPSSGDATABASE(const binary_stream& bs, uint32 position);
- bool processANIMATION(const binary_stream& bs, uint32 position);
- bool processANIMATIONCHANNEL(const binary_stream& bs, uint32 position);
- bool processANIMATIONCHANNELDATABLOCK(const binary_stream& bs, uint32 position);
- bool processANIMATIONREF(const binary_stream& bs, uint32 position);
- bool processANIMATIONSET(const binary_stream& bs, uint32 position);
- bool processBOUNDINGBOX(const binary_stream& bs, uint32 position);
- bool processCAMERANODE(const binary_stream& bs, uint32 position);
- bool processCGSTREAM(const binary_stream& bs, uint32 position);
- bool processCHANNELREF(const binary_stream& bs, uint32 position);
- bool processCONSTANTCHANNEL(const binary_stream& bs, uint32 position);
- bool processCUBEMAPTEXTURE(const binary_stream& bs, uint32 position);
- bool processDATABLOCK(const binary_stream& bs, uint32 position);
- bool processDATABLOCKDATA(const binary_stream& bs, uint32 position);
- bool processDATABLOCKSTREAM(const binary_stream& bs, uint32 position);
- bool processGLPASS(const binary_stream& bs, uint32 position);
- bool processGLSHADER(const binary_stream& bs, uint32 position);
- bool processGLSTATE(const binary_stream& bs, uint32 position);
- bool processINDEXSOURCEDATA(const binary_stream& bs, uint32 position);
- bool processINVERSEBINDMATRIX(const binary_stream& bs, uint32 position);
- bool processJOINTNODE(const binary_stream& bs, uint32 position);
- bool processKEYS(const binary_stream& bs, uint32 position);
- bool processLIBRARY(const binary_stream& bs, uint32 position);
- bool processLIGHTNODE(const binary_stream& bs, uint32 position);
- bool processMODIFIERNETWORK(const binary_stream& bs, uint32 position);
- bool processMODIFIERNETWORKCONNECTION(const binary_stream& bs, uint32 position);
- bool processMODIFIERNETWORKENTRY(const binary_stream& bs, uint32 position);
- bool processMODIFIERNETWORKINSTANCE(const binary_stream& bs, uint32 position);
- bool processMODIFIERNETWORKINSTANCECOMPILE(const binary_stream& bs, uint32 position);
- bool processMODIFIERNETWORKINSTANCEDYNAMICSTREAM(const binary_stream& bs, uint32 position);
- bool processMODIFIERNETWORKINSTANCEDYNAMICSTREAMTYPE(const binary_stream& bs, uint32 position);
- bool processMODIFIERNETWORKINSTANCEMODIFIERINPUT(const binary_stream& bs, uint32 position);
- bool processMODIFIERNETWORKINSTANCEUNIQUEINPUT(const binary_stream& bs, uint32 position);
- bool processMODIFIERNETWORKINSTANCEUNIQUEMODIFIERINPUT(const binary_stream& bs, uint32 position);
- bool processMORPHMODIFIERWEIGHTS(const binary_stream& bs, uint32 position);
- bool processNODE(const binary_stream& bs, uint32 position);
- bool processRENDERDATASOURCE(const binary_stream& bs, uint32 position);
- bool processRENDERINDEXSOURCE(const binary_stream& bs, uint32 position);
- bool processRENDERINSTANCE(const binary_stream& bs, uint32 position);
- bool processRENDERINSTANCESOURCE(const binary_stream& bs, uint32 position);
- bool processRENDERINSTANCESTREAM(const binary_stream& bs, uint32 position);
- bool processRENDERINTERFACEBOUND(const binary_stream& bs, uint32 position);
- bool processRENDERNODE(const binary_stream& bs, uint32 position);
- bool processRENDERSTREAM(const binary_stream& bs, uint32 position);
- bool processRENDERSTREAMINSTANCE(const binary_stream& bs, uint32 position);
- bool processRISTREAM(const binary_stream& bs, uint32 position);
- bool processROOTNODE(const binary_stream& bs, uint32 position);
- bool processSEGMENTSET(const binary_stream& bs, uint32 position);
- bool processSHADER(const binary_stream& bs, uint32 position);
- bool processSHADERGROUP(const binary_stream& bs, uint32 position);
- bool processSHADERGROUPPASS(const binary_stream& bs, uint32 position);
- bool processSHADERINPUT(const binary_stream& bs, uint32 position);
- bool processSHADERINPUTDEFINITION(const binary_stream& bs, uint32 position);
- bool processSHADERINSTANCE(const binary_stream& bs, uint32 position);
- bool processSHADERPROGRAM(const binary_stream& bs, uint32 position);
- bool processSHADERPROGRAMCODE(const binary_stream& bs, uint32 position);
- bool processSHADERPROGRAMCODEBLOCK(const binary_stream& bs, uint32 position);
- bool processSHADERSTREAMDEFINITION(const binary_stream& bs, uint32 position);
- bool processSKELETON(const binary_stream& bs, uint32 position);
- bool processSKINJOINT(const binary_stream& bs, uint32 position);
- bool processSKINNODE(const binary_stream& bs, uint32 position);
- bool processTEXTURE(const binary_stream& bs, uint32 position);
- bool processTEXTUREIMAGEBLOCK(const binary_stream& bs, uint32 position);
- bool processTEXTUREIMAGEBLOCKDATA(const binary_stream& bs, uint32 position);
- bool processTRANSFORM(const binary_stream& bs, uint32 position);
- bool processTYPEINFO(const binary_stream& bs, uint32 position);
- bool processUSERATTRIBUTE(const binary_stream& bs, uint32 position);
- bool processUSERATTRIBUTELIST(const binary_stream& bs, uint32 position);
- bool processUSERDATA(const binary_stream& bs, uint32 position);
- bool processWEIGHTS(const binary_stream& bs, uint32 position);
- bool processXXX(const binary_stream& bs, uint32 position);
- public :
- bool extract(void);
- public :
- extractor(const char* pn);
- ~extractor();
- };
-
- };
-
- namespace PSSG {
-
- extractor::extractor(const char* pn) : pathname(pn), debug(true)
- {
- }
-
- extractor::~extractor()
- {
- }
-
- bool extractor::extract(void)
- {
- //
- std::deque<std::string> filelist;
- BuildFilenameList(filelist, "pssg", pathname.c_str());
- for(size_t i = 0; i < filelist.size(); i++) {
- std::cout << "Processing file " << (i + 1) << " of " << filelist.size() << ": " << filelist[i] << "." << std::endl;
- if(!processFile(filelist[i].c_str())) return false;
- }
- std::cout << std::endl;
-
- return true;
- }
-
- void extractor::clear(void)
- {
- // clear buffers
- buffer_map.clear();
- render_map.clear();
-
- // clear previous data
- nodelist.clear();
- attrlist.clear();
- tree.clear();
-
- // clear node stack
- offsets.clear();
-
- // clear <node, parent node> map
- parent_list.clear();
-
- // clear current filename
- currfile.clear();
- }
-
- bool extractor::processFile(const char* filename)
- {
- using namespace std;
-
- // clear previous data and set current filename
- clear();
- currfile = filename;
-
- // create output file
- if(debug) {
- stringstream ss;
- ss << GetPathnameFromFilename(currfile) << GetShortFilenameWithoutExtension(currfile) << ".txt";
- dfile.close();
- dfile.open(ss.str().c_str());
- if(!dfile) return error("Failed to create debug file.");
- }
-
- // open file
- ifstream ifile(currfile.c_str(), std::ios::binary);
- if(!ifile) return error("Failed to open PSSG file.");
-
- // compute filesize
- ifile.seekg(0, ios::end);
- uint32 filesize = (uint32)ifile.tellg();
- ifile.seekg(0, ios::beg);
-
- // read file
- boost::shared_array<char> filedata(new char[filesize]);
- ifile.read(filedata.get(), filesize);
- if(ifile.fail()) return error("Read failure.");
-
- // create binary stream
- binary_stream bs(filedata, filesize);
-
- // read PSSG
- unsigned int chunkname = bs.BE_read_uint32();
- if(chunkname != 0x50535347) return error("Expecting PSSG chunk.");
-
- // read PSSG chunksize
- unsigned int chunksize = bs.BE_read_uint32();
- if(chunksize == 0) return error("Invalid PSSG chunksize.");
-
- // number of properties + 1
- unsigned int n_properties = bs.BE_read_uint32();
- if(n_properties > 9999) return error("Read an unexpected number of PSSG properties.");
-
- // number of parameters (each parameter has 0 or more properties)
- unsigned int n_parameters = bs.BE_read_uint32();
- if(n_parameters > 9999) return error("Read an unexpected number of PSSG parameters.");
-
- // read parameters
- for(unsigned int i = 0; i < n_parameters; i++)
- {
- // read parameter index
- uint32 index = bs.BE_read_uint32();
- if(bs.fail()) return error("Read failure.");
- if(index != i + 1) return error("Integer parameter index does not match.");
-
- // read parameter length
- uint32 length = bs.BE_read_uint32();
- if(bs.fail()) return error("Read failure.");
-
- // read parameter name
- char parameter_name[128];
- bs.BE_read_array(¶meter_name[0], length);
- if(bs.fail()) return error("Read failure.");
- parameter_name[length] = '\0';
-
- // debug
- if(debug) dfile << parameter_name << " [" << index << "]" << endl;
-
- // macros
- #define FIRST_TEST(TESTNAME) if(strcmp(parameter_name, TESTNAME) == 0) { if(!readAttributes(bs, TESTNAME)) return false; }
- #define OTHER_TEST(TESTNAME) else if(strcmp(parameter_name, TESTNAME) == 0) { if(!readAttributes(bs, TESTNAME)) return false; }
- #define FINAL_TEST else { stringstream ss; ss << "Unknown parameter type " << parameter_name << "." << ends; return error(ss.str().c_str()); }
-
- // read properties
- FIRST_TEST("ANIMATION")
- OTHER_TEST("ANIMATIONCHANNEL")
- OTHER_TEST("ANIMATIONCHANNELDATABLOCK")
- OTHER_TEST("ANIMATIONREF")
- OTHER_TEST("ANIMATIONSET")
- OTHER_TEST("BOUNDINGBOX")
- OTHER_TEST("CAMERANODE")
- OTHER_TEST("CGSTREAM")
- OTHER_TEST("CHANNELREF")
- OTHER_TEST("CONSTANTCHANNEL")
- OTHER_TEST("CUBEMAPTEXTURE") // new
- OTHER_TEST("DATABLOCK")
- OTHER_TEST("DATABLOCKDATA")
- OTHER_TEST("DATABLOCKSTREAM")
- OTHER_TEST("GLPASS") // new
- OTHER_TEST("GLSHADER") // new
- OTHER_TEST("GLSTATE") // new
- OTHER_TEST("INDEXSOURCEDATA")
- OTHER_TEST("INVERSEBINDMATRIX")
- OTHER_TEST("JOINTNODE")
- OTHER_TEST("KEYS")
- OTHER_TEST("LIBRARY")
- OTHER_TEST("LIGHTNODE")
- OTHER_TEST("MODIFIERNETWORK")
- OTHER_TEST("MODIFIERNETWORKCONNECTION")
- OTHER_TEST("MODIFIERNETWORKENTRY")
- OTHER_TEST("MODIFIERNETWORKINSTANCE")
- OTHER_TEST("MODIFIERNETWORKINSTANCECOMPILE")
- OTHER_TEST("MODIFIERNETWORKINSTANCEDYNAMICSTREAM")
- OTHER_TEST("MODIFIERNETWORKINSTANCEDYNAMICSTREAMTYPE")
- OTHER_TEST("MODIFIERNETWORKINSTANCEMODIFIERINPUT")
- OTHER_TEST("MODIFIERNETWORKINSTANCEUNIQUEINPUT")
- OTHER_TEST("MODIFIERNETWORKINSTANCEUNIQUEMODIFIERINPUT")
- OTHER_TEST("MORPHMODIFIERWEIGHTS")
- OTHER_TEST("NODE")
- OTHER_TEST("PSSGDATABASE")
- OTHER_TEST("RENDERDATASOURCE")
- OTHER_TEST("RENDERINDEXSOURCE")
- OTHER_TEST("RENDERINSTANCE")
- OTHER_TEST("RENDERINSTANCESOURCE")
- OTHER_TEST("RENDERINSTANCESTREAM")
- OTHER_TEST("RENDERINTERFACEBOUND")
- OTHER_TEST("RENDERNODE")
- OTHER_TEST("RENDERSTREAM")
- OTHER_TEST("RENDERSTREAMINSTANCE")
- OTHER_TEST("RISTREAM")
- OTHER_TEST("ROOTNODE")
- OTHER_TEST("SEGMENTSET")
- OTHER_TEST("SHADER") // new
- OTHER_TEST("SHADERGROUP")
- OTHER_TEST("SHADERGROUPPASS")
- OTHER_TEST("SHADERINPUT")
- OTHER_TEST("SHADERINPUTDEFINITION")
- OTHER_TEST("SHADERINSTANCE")
- OTHER_TEST("SHADERPROGRAM")
- OTHER_TEST("SHADERPROGRAMCODE")
- OTHER_TEST("SHADERPROGRAMCODEBLOCK")
- OTHER_TEST("SHADERSTREAMDEFINITION")
- OTHER_TEST("SKELETON")
- OTHER_TEST("SKINJOINT")
- OTHER_TEST("SKINNODE")
- OTHER_TEST("TEXTURE")
- OTHER_TEST("TEXTUREIMAGEBLOCK")
- OTHER_TEST("TEXTUREIMAGEBLOCKDATA")
- OTHER_TEST("TRANSFORM")
- OTHER_TEST("TYPEINFO")
- OTHER_TEST("USERATTRIBUTE")
- OTHER_TEST("USERATTRIBUTELIST")
- OTHER_TEST("USERDATA")
- OTHER_TEST("WEIGHTS")
- OTHER_TEST("XXX")
- FINAL_TEST
-
- // add parameter to map
- typedef map<uint32, PSSGPARAMETER>::value_type value_type;
- PSSGPARAMETER temp;
- temp.name = parameter_name;
- nodelist.insert(value_type(index, temp));
- }
-
- // process offsets
- uint32 root = (uint32)bs.tell();
- offsets.push_back(root);
- while(offsets.size()) { if(!processParameter(bs)) return false; }
-
- // traverse tree
- if(debug) dfile << endl;
- if(debug) dfile << "-----------" << endl;
- if(debug) dfile << " PSSG TREE " << endl;
- if(debug) dfile << "-----------" << endl;
-
- unsigned int level = 0;
- if(!processTree(root, level)) return false;
-
- // save model
- return processModel();
- }
-
- bool extractor::readAttributes(binary_stream& bs, const char* name)
- {
- using namespace std;
-
- // get number of attributes
- uint32 items = bs.BE_read_uint32();
- if(items > 9999) return error("Read an unexpected number of attributes.");
-
- // read attributes
- for(size_t i = 0; i < items; i++)
- {
- // read attribute index
- uint32 index = bs.BE_read_uint32();
- if(bs.fail()) return error("Read failure.");
-
- // read attribute string length
- uint32 namesize = bs.BE_read_uint32();
- if(bs.fail()) return error("Read failure.");
-
- // read attribute name
- boost::shared_array<char> attribute_name(new char[namesize + 1]);
- bs.read(attribute_name.get(), namesize);
- if(bs.fail()) return error("Read failure.");
- attribute_name[namesize] = '\0';
-
- // set attribute
- PSSGATTRIBUTE attr;
- attr.parameter = name;
- attr.attribute = attribute_name.get();
- attrlist.insert(map<uint32, PSSGATTRIBUTE>::value_type(index, attr));
-
- // debug
- if(debug) dfile << " " << attr.attribute << " [" << index << "]" << endl;
- }
-
- return true;
- }
-
- bool extractor::processChildren(const binary_stream& bs, boost::shared_ptr<TREENODE> node, uint32 parent, uint32 limit)
- {
- // copy stream
- using namespace std;
- binary_stream stream(bs);
-
- // add child chunks to stack
- uint32 bytes_read = 0;
- while(bytes_read < limit)
- {
- // save offset
- uint32 offset = (uint32)stream.tell();
- offsets.push_back(offset);
- node->children.push_back(offset);
-
- // save child/parent
- typedef map<unsigned int, unsigned int>::value_type value_type;
- parent_list.insert(value_type(offset, parent));
-
- // read chunk data
- unsigned int chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failure.");
- unsigned int chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failure.");
- bytes_read += 4;
- bytes_read += 4;
- bytes_read += chunksize;
-
- // debug information
- typedef map<uint32, PSSGPARAMETER>::iterator iterator;
- iterator iter = nodelist.find(chunktype);
- if(iter == nodelist.end()) return error("Typename not found during scan for child chunks.");
- if(debug) dfile << "(offset, name, parent) = " << "(" << offset << "," << iter->second.name << "," << parent << ")" << endl;
-
- // skip data
- stream.move(chunksize);
- }
-
- return true;
- }
-
- bool extractor::processParameter(const binary_stream& bs)
- {
- using namespace std;
-
- // read offset from top of stack
- unsigned position = offsets.front();
- offsets.pop_front();
-
- // seek position
- binary_stream stream(bs);
- stream.seek(position);
-
- // read chunktype
- unsigned int chunktype = stream.BE_read_uint32();
- if(stream.at_end()) return true;
- else if(stream.fail()) return error("Read failure.");
-
- // find parameter
- typedef map<uint32, PSSGPARAMETER>::iterator iterator;
- iterator iter = nodelist.find(chunktype);
- if(iter == nodelist.end()) {
- stringstream ss;
- ss << "Could not find parameter at index " << chunktype << "." << ends;
- return error(ss.str().c_str());
- }
-
- #define FIRST_PARAMETER_TEST(nodename) if(iter->second.name == #nodename) return process##nodename##(stream, position)
- #define OTHER_PARAMETER_TEST(nodename) else if(iter->second.name == #nodename) return process##nodename##(stream, position)
-
- // process parameter
- FIRST_PARAMETER_TEST(PSSGDATABASE);
- OTHER_PARAMETER_TEST(ANIMATION);
- OTHER_PARAMETER_TEST(ANIMATIONCHANNEL);
- OTHER_PARAMETER_TEST(ANIMATIONCHANNELDATABLOCK);
- OTHER_PARAMETER_TEST(ANIMATIONREF);
- OTHER_PARAMETER_TEST(ANIMATIONSET);
- OTHER_PARAMETER_TEST(BOUNDINGBOX);
- OTHER_PARAMETER_TEST(CAMERANODE);
- OTHER_PARAMETER_TEST(CGSTREAM);
- OTHER_PARAMETER_TEST(CHANNELREF);
- OTHER_PARAMETER_TEST(CONSTANTCHANNEL);
- OTHER_PARAMETER_TEST(CUBEMAPTEXTURE); // new
- OTHER_PARAMETER_TEST(DATABLOCK);
- OTHER_PARAMETER_TEST(DATABLOCKDATA);
- OTHER_PARAMETER_TEST(DATABLOCKSTREAM);
- OTHER_PARAMETER_TEST(GLPASS); // new
- OTHER_PARAMETER_TEST(GLSHADER); // new
- OTHER_PARAMETER_TEST(GLSTATE); // new
- OTHER_PARAMETER_TEST(INDEXSOURCEDATA);
- OTHER_PARAMETER_TEST(INVERSEBINDMATRIX);
- OTHER_PARAMETER_TEST(JOINTNODE);
- OTHER_PARAMETER_TEST(KEYS);
- OTHER_PARAMETER_TEST(LIBRARY);
- OTHER_PARAMETER_TEST(LIGHTNODE);
- OTHER_PARAMETER_TEST(MODIFIERNETWORK);
- OTHER_PARAMETER_TEST(MODIFIERNETWORKCONNECTION);
- OTHER_PARAMETER_TEST(MODIFIERNETWORKENTRY);
- OTHER_PARAMETER_TEST(MODIFIERNETWORKINSTANCE);
- OTHER_PARAMETER_TEST(MODIFIERNETWORKINSTANCECOMPILE);
- OTHER_PARAMETER_TEST(MODIFIERNETWORKINSTANCEDYNAMICSTREAM);
- OTHER_PARAMETER_TEST(MODIFIERNETWORKINSTANCEDYNAMICSTREAMTYPE);
- OTHER_PARAMETER_TEST(MODIFIERNETWORKINSTANCEMODIFIERINPUT);
- OTHER_PARAMETER_TEST(MODIFIERNETWORKINSTANCEUNIQUEINPUT);
- OTHER_PARAMETER_TEST(MODIFIERNETWORKINSTANCEUNIQUEMODIFIERINPUT);
- OTHER_PARAMETER_TEST(MORPHMODIFIERWEIGHTS);
- OTHER_PARAMETER_TEST(NODE);
- OTHER_PARAMETER_TEST(RENDERDATASOURCE);
- OTHER_PARAMETER_TEST(RENDERINDEXSOURCE);
- OTHER_PARAMETER_TEST(RENDERINSTANCE);
- OTHER_PARAMETER_TEST(RENDERINSTANCESOURCE);
- OTHER_PARAMETER_TEST(RENDERINSTANCESTREAM);
- OTHER_PARAMETER_TEST(RENDERINTERFACEBOUND);
- OTHER_PARAMETER_TEST(RENDERNODE);
- OTHER_PARAMETER_TEST(RENDERSTREAM);
- OTHER_PARAMETER_TEST(RENDERSTREAMINSTANCE);
- OTHER_PARAMETER_TEST(RISTREAM);
- OTHER_PARAMETER_TEST(ROOTNODE);
- OTHER_PARAMETER_TEST(SEGMENTSET);
- OTHER_PARAMETER_TEST(SHADER); // new
- OTHER_PARAMETER_TEST(SHADERGROUP);
- OTHER_PARAMETER_TEST(SHADERGROUPPASS);
- OTHER_PARAMETER_TEST(SHADERINPUT);
- OTHER_PARAMETER_TEST(SHADERINPUTDEFINITION);
- OTHER_PARAMETER_TEST(SHADERINSTANCE);
- OTHER_PARAMETER_TEST(SHADERPROGRAM);
- OTHER_PARAMETER_TEST(SHADERPROGRAMCODE);
- OTHER_PARAMETER_TEST(SHADERPROGRAMCODEBLOCK);
- OTHER_PARAMETER_TEST(SHADERSTREAMDEFINITION);
- OTHER_PARAMETER_TEST(SKELETON);
- OTHER_PARAMETER_TEST(SKINJOINT);
- OTHER_PARAMETER_TEST(SKINNODE);
- OTHER_PARAMETER_TEST(TEXTURE);
- OTHER_PARAMETER_TEST(TEXTUREIMAGEBLOCK);
- OTHER_PARAMETER_TEST(TEXTUREIMAGEBLOCKDATA);
- OTHER_PARAMETER_TEST(TRANSFORM);
- OTHER_PARAMETER_TEST(TYPEINFO);
- OTHER_PARAMETER_TEST(USERATTRIBUTE);
- OTHER_PARAMETER_TEST(USERATTRIBUTELIST);
- OTHER_PARAMETER_TEST(USERDATA);
- OTHER_PARAMETER_TEST(WEIGHTS);
- OTHER_PARAMETER_TEST(XXX);
-
- // error
- stringstream ss;
- ss << "Unimplemented parameter test " << iter->second.name << ends;
- return error(ss.str().c_str());
- }
-
- bool extractor::processTree(unsigned int node, unsigned int level)
- {
- using namespace std;
-
- // find node
- tree_iterator iter = tree.find(node);
- if(iter == tree.end()) return true;
-
- // find property name
- typedef std::map<uint32, PSSGPARAMETER>::iterator parameter_iterator;
- parameter_iterator pi = nodelist.find(iter->second->chunktype);
- if(pi == nodelist.end()) {
- stringstream ss;
- ss << "Failed to find parameter for chunktype " << iter->second->chunktype << "." << ends;
- return error(ss.str().c_str());
- }
-
- // print tree node
- if(debug) for(size_t i = 0; i < level; i++) dfile << " ";
- if(debug) dfile << pi->second.name << endl;
-
- // process important nodes
- if(pi->second.name == "DATABLOCK") processVertexBuffer(iter);
- if(pi->second.name == "RENDERDATASOURCE") processRenderBuffer(iter);
- if(pi->second.name == "SKELETON") {}
-
- // traverse children
- deque<unsigned int>& children = iter->second->children;
- for(size_t i = 0; i < children.size(); i++) processTree(children[i], level + 1);
- return true;
- }
-
- bool extractor::processVertexBuffer(tree_iterator iter)
- {
- using namespace std;
-
- // convert TREENODE to DATABLOCK
- DATABLOCK* info = static_cast<DATABLOCK*>(iter->second.get());
- if(!info) return error("Failed to case from TREENODE to DATABLOCK.");
-
- // check number of streams
- if(info->streamCount != 1) return error("Expecting only one DATABLOCK stream.");
-
- // validate children
- deque<uint32>& children = info->children;
- if(children.size() != 2) return error("Expecting DATABLOCKSTREAM and DATABLOCKDATA.");
-
- // child #1: DATABLOCKSTREAM
- tree_iterator dbs_iter = tree.find(children[0]);
- if(dbs_iter == tree.end()) return error("Could not find DATABLOCKSTREAM.");
- map<uint32, PSSGPARAMETER>::iterator p1_iter = nodelist.find(dbs_iter->second->chunktype);
- if(p1_iter == nodelist.end()) return error("Expecting DATABLOCKSTREAM parameter.");
- if(p1_iter->second.name != "DATABLOCKSTREAM") return error("Expecting DATABLOCKSTREAM.");
- DATABLOCKSTREAM* dbs = static_cast<DATABLOCKSTREAM*>(dbs_iter->second.get());
- if(!dbs) return error("Failed to case from TREENODE to DATABLOCKSTREAM.");
-
- // child #2: DATABLOCKDATA
- tree_iterator dbd_iter = tree.find(children[1]);
- if(dbd_iter == tree.end()) return error("Could not find DATABLOCKDATA");
- map<uint32, PSSGPARAMETER>::iterator p2_iter = nodelist.find(dbd_iter->second->chunktype);
- if(p2_iter == nodelist.end()) return error("Expecting DATABLOCKDATA parameter.");
- if(p2_iter->second.name != "DATABLOCKDATA") return error("Expecting DATABLOCKDATA.");
- DATABLOCKDATA* dbd = static_cast<DATABLOCKDATA*>(dbd_iter->second.get());
- if(!dbd) return error("Failed to case from TREENODE to DATABLOCKDATA.");
-
- // create buffer data
- BUFFERDATA vd;
- vd.elementCount = info->elementCount;
- vd.renderType = dbs->renderType;
- vd.dataType = dbs->dataType;
- vd.offset = dbs->offset;
- vd.stride = dbs->stride;
- vd.data = dbd->data;
-
- // insert buffer data
- buffer_map.insert(buffer_map_value_type(info->id, vd));
- return true;
- }
-
- bool extractor::processRenderBuffer(tree_iterator iter)
- {
- using namespace std;
-
- // convert TREENODE to RENDERDATASOURCE
- RENDERDATASOURCE* info = static_cast<RENDERDATASOURCE*>(iter->second.get());
- if(!info) return error("Failed to case from TREENODE to RENDERDATASOURCE.");
- if(!info->streamCount) return error("RENDERDATASOURCE must contain at least one stream.");
- if(info->children.size() < 2) return error("RENDERDATASOURCE must have at least two children.");
-
- // prepare RENDERDATA
- RENDERDATA rd;
- rd.streamCount = info->streamCount;
- rd.blocks.reset(new string[info->streamCount]);
-
- // first RENDERDATASOURCE
- if(info->streamCount == info->children.size() - 1)
- {
- // find RENDERINDEXSOURCE node
- tree_iterator node = tree.find(info->children[0]);
- if(node == tree.end()) return error("Could not find RENDERINDEXSOURCE node.");
-
- // find RENDERINDEXSOURCE parameter
- map<uint32, PSSGPARAMETER>::iterator param = nodelist.find(node->second->chunktype);
- if(param == nodelist.end()) return error("Could not find parameter.");
- if(param->second.name != "RENDERINDEXSOURCE") return error("Expecting RENDERINDEXSOURCE.");
-
- // safe to cast
- RENDERINDEXSOURCE* ris = static_cast<RENDERINDEXSOURCE*>(node->second.get());
- if(!ris) return error("Failed to cast from TREENODE to RENDERINDEXSOURCE.");
- if(!ris->children.size()) return error("Invalid RENDERINDEXSOURCE.");
-
- // find INDEXSOURCEDATA node
- node = tree.find(ris->children[0]);
- if(node == tree.end()) return error("Could not find INDEXSOURCEDATA node.");
-
- // find INDEXSOURCEDATA parameter
- param = nodelist.find(node->second->chunktype);
- if(param == nodelist.end()) return error("Could not find parameter.");
- if(param->second.name != "INDEXSOURCEDATA") return error("Expecting INDEXSOURCEDATA.");
-
- // safe to cast
- INDEXSOURCEDATA* isd = static_cast<INDEXSOURCEDATA*>(node->second.get());
- if(!isd) return error("Failed to cast from TREENODE to INDEXSOURCEDATA.");
-
- // prepare RENDERDATA
- rd.primitive = ris->primitive;
- rd.format = ris->format;
- rd.count = ris->count;
- rd.id = ris->id;
- rd.buffer = isd->data;
-
- // read render streams
- for(size_t i = 0; i < info->streamCount; i++)
- {
- // find RENDERSTREAM node
- tree_iterator node = tree.find(info->children[i + 1]);
- if(node == tree.end()) return error("Could not find node.");
-
- // find RENDERSTREAM parameter
- map<uint32, PSSGPARAMETER>::iterator param = nodelist.find(node->second->chunktype);
- if(param == nodelist.end()) return error("Could not find parameter.");
- if(param->second.name != "RENDERSTREAM") {
- stringstream ss;
- ss << "Expecting RENDERSTREAM node but found " << param->second.name << " instead." << ends;
- return error(ss.str().c_str());
- }
-
- // safe to cast
- RENDERSTREAM* rs = static_cast<RENDERSTREAM*>(node->second.get());
- if(!rs) return error("Failed to cast from TREENODE to RENDERSTREAM.");
-
- // save blocks
- rd.blocks[i] = string(rs->dataBlock.c_str() + 1); // remove # from front
- }
- }
- // other RENDERDATASOURCE (TOTORI and MERURU)
- else if(info->streamCount == info->children.size())
- {
- if(info->primitive == "triangles")
- {
- cout << "LOL #1" << endl;
- }
- else if(info->primitive.length() == 0)
- {
- cout << "LOL #2" << endl;
- }
- else
- return error("Unexpected RENDERDATASOURCE processing error.");
- }
- else
- {
- return error("Unexpected RENDERDATASOURCE stream count.");
- }
-
- // insert render data
- render_map.insert(render_map_value_type(info->id, rd));
- return true;
- }
-
- bool extractor::processModel(void)const
- {
- using namespace std;
- typedef map<string, BUFFERDATA>::const_iterator buffer_map_iterator;
- typedef map<string, RENDERDATA>::const_iterator render_map_iterator;
-
- // for each Vertex or SkinnableVertex
- typedef map<string, deque<RENDERDATA>> maptype;
- maptype assocmap;
- for(buffer_map_iterator iter = buffer_map.begin(); iter != buffer_map.end(); iter++) {
- const BUFFERDATA& bd = iter->second;
- if(bd.renderType == "Vertex") assocmap.insert(maptype::value_type(iter->first, deque<RENDERDATA>()));
- else if(bd.renderType == "SkinnableVertex") assocmap.insert(maptype::value_type(iter->first, deque<RENDERDATA>()));
- }
-
- // fill association map
- for(render_map_iterator iter = render_map.begin(); iter != render_map.end(); iter++)
- {
- // count number of vertex streams seen
- uint32 vstreams = 0;
-
- // for each stream in RENDERDATA
- const RENDERDATA& rd = iter->second;
- for(uint32 streamIndex = 0; streamIndex < rd.streamCount; streamIndex++)
- {
- // find BUFFERDATA
- buffer_map_iterator bmi = buffer_map.find(rd.blocks[streamIndex]);
- if(bmi == buffer_map.end()) {
- stringstream ss;
- ss << "Blockname " << rd.blocks[streamIndex] << " lookup failed.";
- return error(ss.str().c_str());
- }
-
- // BUFFERDATA is vertex or SkinnableVertex
- const BUFFERDATA& bd = bmi->second;
- if(bd.renderType == "Vertex" || bd.renderType == "SkinnableVertex") {
- maptype::iterator item = assocmap.find(rd.blocks[streamIndex]);
- if(item == assocmap.end()) return error("A RENDERDATASOURCE that refers to an unknown vertex DATABLOCK.");
- item->second.push_back(rd);
- }
-
- // make sure there is only one vertex stream
- if(bd.renderType == "Vertex") vstreams++;
- else if(bd.renderType == "SkinnableVertex") vstreams++;
- if(vstreams > 1) return error("Multiple vertex streams in RENDERDATASOURCE.");
- }
- }
-
- // create lightwave object
- lwFileSaver saver;
- saver.insertLayr(0, nullptr);
-
- // for each point set
- uint32 currpnts = 0;
- for(maptype::iterator iter = assocmap.begin(); iter != assocmap.end(); iter++)
- {
- // get BUFFERDATA
- const buffer_map_iterator bmi = buffer_map.find(iter->first);
- if(bmi == buffer_map.end()) return error("BUFFERDATA lookup failed.");
-
- // get BUFFERDATA
- const BUFFERDATA& bd = bmi->second;
- if(bd.elementCount == 0) return error("BUFFERDATA point set contains no vertices.");
-
- // OK to save points
- if(!(bd.renderType == "Vertex" || bd.renderType == "SkinnableVertex"))
- return error("Expecting Vertex or SkinnableVertex.");
-
- // initialize data pointer
- boost::shared_array<lwVertex3D> data(new lwVertex3D[bd.elementCount]);
- char* ptr = bd.data.get();
- ptr += bd.offset;
-
- // convert points
- for(size_t i = 0; i < bd.elementCount; i++)
- {
- if(bd.dataType == "float3") {
- float* v = reinterpret_cast<float*>(ptr);
- float a = v[0];
- float b = v[1];
- float c = v[2];
- reverse_byte_order(&a);
- reverse_byte_order(&b);
- reverse_byte_order(&c);
- data[i].x = a;
- data[i].y = b;
- data[i].z = c;
- }
- else {
- stringstream ss;
- ss << "Unknown Vertex data type " << bd.dataType << "." << endl;
- return error(ss.str().c_str());
- }
- ptr += bd.stride;
- }
-
- // insert points
- saver.insertPnts(0, currpnts, data, bd.elementCount);
-
- // for each RENDERDATA source associated with this point set
- for(size_t rdIndex = 0; rdIndex < iter->second.size(); rdIndex++)
- {
- const RENDERDATA& rd = iter->second[rdIndex];
- for(size_t streamIndex = 0; streamIndex < rd.streamCount; streamIndex++)
- {
- // find buffer data
- buffer_map_iterator iter = buffer_map.find(rd.blocks[streamIndex]);
- if(iter == buffer_map.end()) return error("Blockname lookup failed.");
-
- // buffer data pointer
- BUFFERDATA bmi = iter->second;
- char* ptr = bmi.data.get();
- ptr += bmi.offset;
-
- // UV vertex map
- if(bmi.renderType == "ST")
- {
- boost::shared_array<lwRefVertex2D> data(new lwRefVertex2D[bmi.elementCount]);
- for(size_t i = 0; i < bmi.elementCount; i++) {
- if(bmi.dataType == "float2") {
- float* v = reinterpret_cast<float*>(ptr);
- float a = v[0];
- float b = v[1];
- reverse_byte_order(&a);
- reverse_byte_order(&b);
- data[i].reference = i;
- data[i].x = a;
- data[i].y = 1.0f - b;
- }
- else if(bmi.dataType == "half2") {
- unsigned short* v = reinterpret_cast<unsigned short*>(ptr);
- unsigned short a = v[0];
- unsigned short b = v[1];
- reverse_byte_order(&a);
- reverse_byte_order(&b);
- data[i].reference = i;
- data[i].x = float_16_to_32(a);
- data[i].y = 1.0f - float_16_to_32(b);
- }
- else if(bmi.dataType == "float3") {
- float* v = reinterpret_cast<float*>(ptr);
- float a = v[0];
- float b = v[1];
- reverse_byte_order(&a);
- reverse_byte_order(&b);
- data[i].reference = i;
- data[i].x = a;
- data[i].y = 1.0f - b;
- }
- else {
- stringstream ss;
- ss << "Unknown ST data type " << bmi.dataType << "." << endl;
- return error(ss.str().c_str());
- }
- ptr += bmi.stride;
- }
-
- saver.insertTxuv(0, currpnts, rd.id.c_str(), data, bmi.elementCount);
- }
- // normal vertex map
- else if(bmi.renderType == "Normal" || bmi.renderType == "SkinnableNormal")
- {
- }
- // weight vertex map
-
- // polygons
- if(rd.primitive == "triangles")
- {
- // create triangle buffer
- if(rd.count % 3) return error("Face buffer element count must be divisible by three.");
- uint32 triangles = rd.count/3;
- boost::shared_array<lwTriangle> tribuffer(new lwTriangle[triangles]);
-
- // extract triangles from RENDERDATA
- char* ptr = rd.buffer.get();
- uint32 index = 0;
- if(rd.format == "uchar") {
- for(uint32 i = 0; i < triangles; i++) {
- unsigned char* temp = reinterpret_cast<unsigned char*>(ptr);
- tribuffer[i].a = (uint32)(temp[index++]);
- tribuffer[i].b = (uint32)(temp[index++]);
- tribuffer[i].c = (uint32)(temp[index++]);
- }
- }
- else if(rd.format == "ushort") {
- for(uint32 i = 0; i < triangles; i++) {
- unsigned short* temp = reinterpret_cast<unsigned short*>(ptr);
- unsigned short a = temp[index++];
- unsigned short b = temp[index++];
- unsigned short c = temp[index++];
- reverse_byte_order(&a);
- reverse_byte_order(&b);
- reverse_byte_order(&c);
- tribuffer[i].a = (uint32)a;
- tribuffer[i].b = (uint32)b;
- tribuffer[i].c = (uint32)c;
- }
- }
- else {
- stringstream ss;
- ss << "Unknown face format " << rd.format << "." << endl;
- return error(ss.str().c_str());
- }
-
- // save polygons
- saver.insertSurf(rd.id.c_str());
- saver.insertPols(0, currpnts, rd.id.c_str(), tribuffer, triangles);
- }
- }
- }
-
- // increment point set
- currpnts++;
- }
-
- string savename = GetPathnameFromFilename(currfile);
- savename += GetShortFilenameWithoutExtension(currfile);
- savename += ".lwo";
- saver.save(savename.c_str());
-
- return true;
- }
-
- bool extractor::processPSSGDATABASE(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "--------------" << endl;
- if(debug) dfile << " PSSGDATABASE " << endl;
- if(debug) dfile << "--------------" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // create node
- boost::shared_ptr<TREENODE> node(new PSSGDATABASE);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- PSSGDATABASE* info = static_cast<PSSGDATABASE*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // validate
- if(info->propbytes > 1000) return error("Unexpected number of property table bytes.");
- if(info->propbytes == 0) return error("Property table expected.");
-
- // read properties
- uint32 bytes_read = 0;
- while(bytes_read < info->propbytes)
- {
- // read index
- uint32 type = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
-
- // data bytes
- uint32 size = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
- bytes_read += size;
-
- // find index
- typedef map<uint32, PSSGATTRIBUTE>::iterator iterator;
- iterator iter = attrlist.find(type);
- if(iter == attrlist.end()) {
- stringstream ss;
- ss << "Failed to find property for index " << type << "." << ends;
- return error(ss.str().c_str());
- }
-
- // read attributes
- const string& parameter = iter->second.parameter;
- const string& attribute = iter->second.attribute;
- if(parameter == "PSSGDATABASE" && attribute == "creator") {
- if(!readString(stream, info->creator)) return false;
- if(debug) dfile << "info->creator = " << info->creator << endl;
- }
- else if(parameter == "PSSGDATABASE" && attribute == "creationMachine") {
- if(!readString(stream, info->creationMachine)) return false;
- if(debug) dfile << "creationMachine = " << info->creationMachine << endl;
- }
- else if(parameter == "PSSGDATABASE" && attribute == "creationDate") {
- if(!readString(stream, info->creationDate)) return false;
- if(debug) dfile << "creationDate = " << info->creationDate << endl;
- }
- else if(parameter == "PSSGDATABASE" && attribute == "scale") {
- if(!readVector3(stream, &info->scale[0])) return false;
- if(debug) dfile << "scale = " << "<" << info->scale[0] << "," << info->scale[1] << "," << info->scale[2] << ">" << endl;
- }
- else if(parameter == "PSSGDATABASE" && attribute == "up") {
- if(!readVector3(stream, &info->up[0])) return false;
- if(debug) dfile << "up = " << "<" << info->up[0] << "," << info->up[1] << "," << info->up[2] << ">" << endl;
- }
- else {
- stringstream ss;
- ss << "Unknown block property " << parameter << ":" << attribute << "." << ends;
- return error(ss.str().c_str());
- }
- }
-
- // add child chunks to stack
- if(info->chunksize == info->propbytes + 4) return true;
- return processChildren(stream, node, position, info->chunksize - bytes_read - 4);
- }
-
- bool extractor::processANIMATION(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processANIMATIONCHANNEL(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processANIMATIONCHANNELDATABLOCK(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processANIMATIONREF(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processANIMATIONSET(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processBOUNDINGBOX(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processCAMERANODE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processCGSTREAM(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processCHANNELREF(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processCONSTANTCHANNEL(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processCUBEMAPTEXTURE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processDATABLOCK(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "-----------" << endl;
- if(debug) dfile << " DATABLOCK " << endl;
- if(debug) dfile << "-----------" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // insert node
- boost::shared_ptr<TREENODE> node(new DATABLOCK);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- DATABLOCK* info = static_cast<DATABLOCK*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // initialize attributes
- info->streamCount = 0;
- info->size = 0;
- info->elementCount = 0;
- info->allocationStrategy = 0;
- info->id = "";
-
- // validate
- if(info->propbytes > 1000) return error("Unexpected number of property table bytes.");
- if(info->propbytes == 0) return error("Property table expected.");
-
- // read properties
- uint32 bytes_read = 0;
- while(bytes_read < info->propbytes)
- {
- // read index
- uint32 type = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
-
- // data bytes
- uint32 size = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
- bytes_read += size;
-
- // find index
- typedef map<uint32, PSSGATTRIBUTE>::iterator iterator;
- iterator iter = attrlist.find(type);
- if(iter == attrlist.end()) {
- stringstream ss;
- ss << "Failed to find property for index " << type << "." << ends;
- return error(ss.str().c_str());
- }
-
- // read attributes
- const string& parameter = iter->second.parameter;
- const string& attribute = iter->second.attribute;
- if(parameter == "DATABLOCK" && attribute == "streamCount") {
- if(!readNumber(stream, info->streamCount)) return false;
- if(debug) dfile << "info->streamCount = " << info->streamCount << endl;
- }
- else if(parameter == "DATABLOCK" && attribute == "size") {
- if(!readNumber(stream, info->size)) return false;
- if(debug) dfile << "info->size = " << info->size << endl;
- }
- else if(parameter == "DATABLOCK" && attribute == "elementCount") {
- if(!readNumber(stream, info->elementCount)) return false;
- if(debug) dfile << "info->elementCount = " << info->elementCount << endl;
- }
- else if(parameter == "RENDERINTERFACEBOUND" && attribute == "allocationStrategy") {
- if(!readNumber(stream, info->allocationStrategy)) return false;
- if(debug) dfile << "info->allocationStrategy = " << info->allocationStrategy << endl;
- }
- else if(parameter == "XXX" && attribute == "id") {
- if(!readString(stream, info->id)) return false;
- if(debug) dfile << "info->id = " << info->id << endl;
- }
- else {
- stringstream ss;
- ss << "Unknown block property " << parameter << ":" << attribute << "." << ends;
- return error(ss.str().c_str());
- }
- }
-
- // add child chunks to stack
- if(info->chunksize == info->propbytes + 4) return true;
- return processChildren(stream, node, position, info->chunksize - bytes_read - 4);
- }
-
- bool extractor::processDATABLOCKDATA(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "---------------" << endl;
- if(debug) dfile << " DATABLOCKDATA " << endl;
- if(debug) dfile << "---------------" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // insert node
- boost::shared_ptr<TREENODE> node(new DATABLOCKDATA);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- DATABLOCKDATA* info = static_cast<DATABLOCKDATA*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // validate
- if(info->propbytes) return error("Property table unexpected.");
-
- // create chunk data
- unsigned int datasize = info->chunksize - 4;
- info->data.reset(new char[datasize]);
-
- // read chunk data
- stream.read((char*)info->data.get(), datasize);
- if(stream.fail()) return error("Read failed.");
-
- // no children
- return true;
- }
-
- bool extractor::processDATABLOCKSTREAM(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "-----------------" << endl;
- if(debug) dfile << " DATABLOCKSTREAM " << endl;
- if(debug) dfile << "-----------------" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // insert node
- boost::shared_ptr<TREENODE> node(new DATABLOCKSTREAM);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- DATABLOCKSTREAM* info = static_cast<DATABLOCKSTREAM*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // initialize attributes
- info->renderType = "";
- info->dataType = "";
- info->offset = 0;
- info->stride = 0;
-
- // validate
- if(info->propbytes > 1000) return error("Unexpected number of property table bytes.");
- if(info->propbytes == 0) return error("Property table expected.");
-
- // read properties
- uint32 bytes_read = 0;
- while(bytes_read < info->propbytes)
- {
- // read index
- uint32 type = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
-
- // data bytes
- uint32 size = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
- bytes_read += size;
-
- // find index
- typedef map<uint32, PSSGATTRIBUTE>::iterator iterator;
- iterator iter = attrlist.find(type);
- if(iter == attrlist.end()) {
- stringstream ss;
- ss << "Failed to find property for index " << type << "." << ends;
- return error(ss.str().c_str());
- }
-
- // read attributes
- const string& parameter = iter->second.parameter;
- const string& attribute = iter->second.attribute;
- if(parameter == "DATABLOCKSTREAM" && attribute == "renderType") {
- if(!readString(stream, info->renderType)) return false;
- if(debug) dfile << "info->renderType = " << info->renderType << endl;
- }
- else if(parameter == "DATABLOCKSTREAM" && attribute == "dataType") {
- if(!readString(stream, info->dataType)) return false;
- if(debug) dfile << "info->dataType = " << info->dataType << endl;
- }
- else if(parameter == "DATABLOCKSTREAM" && attribute == "offset") {
- if(!readNumber(stream, info->offset)) return false;
- if(debug) dfile << "info->offset = " << info->offset << endl;
- }
- else if(parameter == "DATABLOCKSTREAM" && attribute == "stride") {
- if(!readNumber(stream, info->stride)) return false;
- if(debug) dfile << "info->stride = " << info->stride << endl;
- }
- else {
- stringstream ss;
- ss << "Unknown block property " << parameter << ":" << attribute << "." << ends;
- return error(ss.str().c_str());
- }
- }
-
- // add child chunks to stack
- if(info->chunksize == info->propbytes + 4) return true;
- return processChildren(stream, node, position, info->chunksize - bytes_read - 4);
- }
-
- bool extractor::processGLPASS(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processGLSHADER(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processGLSTATE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processINDEXSOURCEDATA(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "-----------------" << endl;
- if(debug) dfile << " INDEXSOURCEDATA " << endl;
- if(debug) dfile << "-----------------" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // insert node
- boost::shared_ptr<TREENODE> node(new INDEXSOURCEDATA);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- INDEXSOURCEDATA* info = static_cast<INDEXSOURCEDATA*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // validate
- if(info->propbytes) return error("Property table unexpected.");
-
- // create chunk data
- uint32 datasize = info->chunksize - 4;
- info->data.reset(new char[datasize]);
-
- // read chunk data
- stream.read(info->data.get(), datasize);
- if(stream.fail()) return error("Read failed.");
-
- return true;
- }
-
- bool extractor::processINVERSEBINDMATRIX(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processJOINTNODE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processKEYS(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processLIBRARY(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "---------" << endl;
- if(debug) dfile << " LIBRARY " << endl;
- if(debug) dfile << "---------" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // insert node
- boost::shared_ptr<TREENODE> node(new LIBRARY);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- LIBRARY* info = static_cast<LIBRARY*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // validate
- if(info->propbytes > 1000) return error("Unexpected number of property table bytes.");
- if(info->propbytes == 0) return error("Property table expected.");
-
- // read properties
- uint32 bytes_read = 0;
- while(bytes_read < info->propbytes)
- {
- // read index
- uint32 type = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
-
- // data bytes
- uint32 size = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
- bytes_read += size;
-
- // find index
- typedef map<uint32, PSSGATTRIBUTE>::iterator iterator;
- iterator iter = attrlist.find(type);
- if(iter == attrlist.end()) {
- stringstream ss;
- ss << "Failed to find property for index " << type << "." << ends;
- return error(ss.str().c_str());
- }
-
- // aliases
- const string& parameter = iter->second.parameter;
- const string& attribute = iter->second.attribute;
-
- if(parameter == "LIBRARY" && attribute == "type") {
- if(!readString(stream, info->type)) return false;
- if(debug) dfile << "type = " << info->type << endl;
- }
- else {
- stringstream ss;
- ss << "Unknown block property " << parameter << ":" << attribute << "." << ends;
- return error(ss.str().c_str());
- }
- }
-
- // add child chunks to stack
- if(info->chunksize == info->propbytes + 4) return true;
- return processChildren(stream, node, position, info->chunksize - bytes_read - 4);
- }
-
- bool extractor::processLIGHTNODE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processMODIFIERNETWORK(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processMODIFIERNETWORKCONNECTION(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processMODIFIERNETWORKENTRY(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processMODIFIERNETWORKINSTANCE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processMODIFIERNETWORKINSTANCECOMPILE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processMODIFIERNETWORKINSTANCEDYNAMICSTREAM(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processMODIFIERNETWORKINSTANCEDYNAMICSTREAMTYPE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processMODIFIERNETWORKINSTANCEMODIFIERINPUT(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processMODIFIERNETWORKINSTANCEUNIQUEINPUT(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processMODIFIERNETWORKINSTANCEUNIQUEMODIFIERINPUT(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processMORPHMODIFIERWEIGHTS(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processNODE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processRENDERDATASOURCE(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "------------------" << endl;
- if(debug) dfile << " RENDERDATASOURCE " << endl;
- if(debug) dfile << "------------------" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // insert node
- boost::shared_ptr<TREENODE> node(new RENDERDATASOURCE);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- RENDERDATASOURCE* info = static_cast<RENDERDATASOURCE*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // initialize attributes
- info->streamCount = 0;
- info->primitive = "";
- info->id = "";
-
- // validate
- if(info->propbytes > 1000) return error("Unexpected number of property table bytes.");
- if(info->propbytes == 0) return error("Property table expected.");
-
- // read properties
- uint32 bytes_read = 0;
- while(bytes_read < info->propbytes)
- {
- // read index
- uint32 type = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
-
- // data bytes
- uint32 size = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
- bytes_read += size;
-
- // find index
- typedef map<uint32, PSSGATTRIBUTE>::iterator iterator;
- iterator iter = attrlist.find(type);
- if(iter == attrlist.end()) {
- stringstream ss;
- ss << "Failed to find property for index " << type << "." << ends;
- return error(ss.str().c_str());
- }
-
- // read attributes
- const string& parameter = iter->second.parameter;
- const string& attribute = iter->second.attribute;
- if(parameter == "RENDERDATASOURCE" && attribute == "streamCount") {
- if(!readNumber(stream, info->streamCount)) return false;
- if(debug) dfile << "info->streamCount = " << info->streamCount << endl;
- }
- else if(parameter == "RENDERDATASOURCE" && attribute == "primitive") {
- if(!readString(stream, info->primitive)) return false;
- if(debug) dfile << "info->primitive = " << info->primitive << endl;
- }
- else if(parameter == "XXX" && attribute == "id") {
- if(!readString(stream, info->id)) return false;
- if(debug) dfile << "info->id = " << info->id << endl;
- }
- else {
- stringstream ss;
- ss << "Unknown block property " << parameter << ":" << attribute << "." << ends;
- return error(ss.str().c_str());
- }
- }
-
- // add child chunks to stack
- if(info->chunksize == info->propbytes + 4) return true;
- return processChildren(stream, node, position, info->chunksize - bytes_read - 4);
- }
-
- bool extractor::processRENDERINDEXSOURCE(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "-------------------" << endl;
- if(debug) dfile << " RENDERINDEXSOURCE " << endl;
- if(debug) dfile << "-------------------" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // insert node
- boost::shared_ptr<TREENODE> node(new RENDERINDEXSOURCE);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- RENDERINDEXSOURCE* info = static_cast<RENDERINDEXSOURCE*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // initialize attributes
- info->primitive = "";
- info->format = "";
- info->count = 0;
- info->maximumIndex = 0;
- info->allocationStrategy = 0;
- info->id = "";
- info->size = 0;
-
- // validate
- if(info->propbytes > 1000) return error("Unexpected number of property table bytes.");
- if(info->propbytes == 0) return error("Property table expected.");
-
- // read properties
- uint32 bytes_read = 0;
- while(bytes_read < info->propbytes)
- {
- // read index
- uint32 type = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
-
- // data bytes
- uint32 size = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
- bytes_read += size;
-
- // find index
- typedef map<uint32, PSSGATTRIBUTE>::iterator iterator;
- iterator iter = attrlist.find(type);
- if(iter == attrlist.end()) {
- stringstream ss;
- ss << "Failed to find property for index " << type << "." << ends;
- return error(ss.str().c_str());
- }
-
- // read attributes
- const string& parameter = iter->second.parameter;
- const string& attribute = iter->second.attribute;
- if(parameter == "RENDERINDEXSOURCE" && attribute == "primitive") {
- if(!readString(stream, info->primitive)) return false;
- if(debug) dfile << "info->primitive = " << info->primitive << endl;
- }
- else if(parameter == "RENDERINDEXSOURCE" && attribute == "format") {
- if(!readString(stream, info->format)) return false;
- if(debug) dfile << "info->format = " << info->format << endl;
- }
- else if(parameter == "RENDERINDEXSOURCE" && attribute == "count") {
- if(!readNumber(stream, info->count)) return false;
- if(debug) dfile << "info->count = " << info->count << endl;
- }
- else if(parameter == "RENDERINDEXSOURCE" && attribute == "maximumIndex") {
- if(!readNumber(stream, info->maximumIndex)) return false;
- if(debug) dfile << "info->maximumIndex = " << info->maximumIndex << endl;
- }
- else if(parameter == "RENDERINTERFACEBOUND" && attribute == "allocationStrategy") {
- if(!readNumber(stream, info->allocationStrategy)) return false;
- if(debug) dfile << "info->allocationStrategy = " << info->allocationStrategy << endl;
- }
- else if(parameter == "XXX" && attribute == "id") {
- if(!readString(stream, info->id)) return false;
- if(debug) dfile << "info->id = " << info->id << endl;
- }
- else {
- stringstream ss;
- ss << "Unknown block property " << parameter << ":" << attribute << "." << ends;
- return error(ss.str().c_str());
- }
- }
-
- // add child chunks to stack
- if(info->chunksize == info->propbytes + 4) return true;
- return processChildren(stream, node, position, info->chunksize - bytes_read - 4);
- }
-
- bool extractor::processRENDERINSTANCE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processRENDERINSTANCESOURCE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processRENDERINSTANCESTREAM(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processRENDERINTERFACEBOUND(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processRENDERNODE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processRENDERSTREAM(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "--------------" << endl;
- if(debug) dfile << " RENDERSTREAM " << endl;
- if(debug) dfile << "--------------" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // insert node
- boost::shared_ptr<TREENODE> node(new RENDERSTREAM);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- RENDERSTREAM* info = static_cast<RENDERSTREAM*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // initialize attributes
- info->dataBlock = "";
- info->subStream = 0;
- info->id = "";
-
- // validate
- if(info->propbytes > 1000) return error("Unexpected number of property table bytes.");
- if(info->propbytes == 0) return error("Property table expected.");
-
- // read properties
- uint32 bytes_read = 0;
- while(bytes_read < info->propbytes)
- {
- // read index
- uint32 type = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
-
- // data bytes
- uint32 size = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
- bytes_read += size;
-
- // find index
- typedef map<uint32, PSSGATTRIBUTE>::iterator iterator;
- iterator iter = attrlist.find(type);
- if(iter == attrlist.end()) {
- stringstream ss;
- ss << "Failed to find property for index " << type << "." << ends;
- return error(ss.str().c_str());
- }
-
- // read attributes
- const string& parameter = iter->second.parameter;
- const string& attribute = iter->second.attribute;
- if(parameter == "RENDERSTREAM" && attribute == "dataBlock") {
- if(!readString(stream, info->dataBlock)) return false;
- if(debug) dfile << "info->dataBlock = " << info->dataBlock << endl;
- }
- else if(parameter == "RENDERSTREAM" && attribute == "subStream") {
- if(!readNumber(stream, info->subStream)) return false;
- if(debug) dfile << "info->subStream = " << info->subStream << endl;
- }
- else if(parameter == "XXX" && attribute == "id") {
- if(!readString(stream, info->id)) return false;
- if(debug) dfile << "info->id = " << info->id << endl;
- }
- else {
- stringstream ss;
- ss << "Unknown block property " << parameter << ":" << attribute << "." << ends;
- return error(ss.str().c_str());
- }
- }
-
- // no children
- return true;
- }
-
- bool extractor::processRENDERSTREAMINSTANCE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processRISTREAM(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processROOTNODE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processSEGMENTSET(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "------------" << endl;
- if(debug) dfile << " SEGMENTSET " << endl;
- if(debug) dfile << "------------" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // insert node
- boost::shared_ptr<TREENODE> node(new SEGMENTSET);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- SEGMENTSET* info = static_cast<SEGMENTSET*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // validate
- if(info->propbytes > 1000) return error("Unexpected number of property table bytes.");
- if(info->propbytes == 0) return error("Property table expected.");
-
- // read properties
- uint32 bytes_read = 0;
- while(bytes_read < info->propbytes)
- {
- // read index
- uint32 type = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
-
- // data bytes
- uint32 size = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
- bytes_read += size;
-
- // find index
- typedef map<uint32, PSSGATTRIBUTE>::iterator iterator;
- iterator iter = attrlist.find(type);
- if(iter == attrlist.end()) {
- stringstream ss;
- ss << "Failed to find property for index " << type << "." << ends;
- return error(ss.str().c_str());
- }
-
- // read attributes
- const string& parameter = iter->second.parameter;
- const string& attribute = iter->second.attribute;
- if(parameter == "SEGMENTSET" && attribute == "segmentCount") {
- if(!readNumber(stream, info->segmentCount)) return false;
- if(debug) dfile << "info->segmentCount = " << info->segmentCount << endl;
- }
- else if(parameter == "XXX" && attribute == "id") {
- if(!readString(stream, info->id)) return false;
- if(debug) dfile << "info->id = " << info->id << endl;
- }
- else {
- stringstream ss;
- ss << "Unknown block property " << parameter << ":" << attribute << "." << ends;
- return error(ss.str().c_str());
- }
- }
-
- // add child chunks to stack
- if(info->chunksize == info->propbytes + 4) return true;
- return processChildren(stream, node, position, info->chunksize - bytes_read - 4);
- }
-
- bool extractor::processSHADER(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processSHADERGROUP(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processSHADERGROUPPASS(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processSHADERINPUT(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processSHADERINPUTDEFINITION(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processSHADERINSTANCE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processSHADERPROGRAM(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processSHADERPROGRAMCODE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processSHADERPROGRAMCODEBLOCK(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processSHADERSTREAMDEFINITION(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processSKELETON(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processSKINJOINT(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processSKINNODE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processTEXTURE(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "---------" << endl;
- if(debug) dfile << " TEXTURE " << endl;
- if(debug) dfile << "---------" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // insert node
- boost::shared_ptr<TREENODE> node(new TEXTURE);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- TEXTURE* info = static_cast<TEXTURE*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // initialize properties
- info->width = 0;
- info->height = 0;
- info->transient = 0;
- info->wrapS = 0;
- info->wrapT = 0;
- info->wrapR = 0;
- info->minFilter = 0;
- info->magFilter = 0;
- info->automipmap = 0;
- info->numberMipMapLevels = 0;
- info->gammaRemapR = 0;
- info->gammaRemapG = 0;
- info->gammaRemapB = 0;
- info->gammaRemapA = 0;
- info->lodBias = 0;
- info->resolveMSAA = 0;
- info->imageBlockCount = 0;
- info->allocationStrategy = 0;
-
- // validate
- if(info->propbytes > 1000) return error("Unexpected number of property table bytes.");
- if(info->propbytes == 0) return error("Property table expected.");
-
- // read properties
- uint32 bytes_read = 0;
- while(bytes_read < info->propbytes)
- {
- // read index
- uint32 type = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
-
- // data bytes
- uint32 size = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
- bytes_read += size;
-
- // find index
- typedef map<uint32, PSSGATTRIBUTE>::iterator iterator;
- iterator iter = attrlist.find(type);
- if(iter == attrlist.end()) {
- stringstream ss;
- ss << "Failed to find property for index " << type << "." << ends;
- return error(ss.str().c_str());
- }
-
- // read attributes
- const string& parameter = iter->second.parameter;
- const string& attribute = iter->second.attribute;
- if(parameter == "TEXTURE" && attribute == "width") {
- if(!readNumber(stream, info->width)) return false;
- if(debug) dfile << "info->width = " << info->width << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "height") {
- if(!readNumber(stream, info->height)) return false;
- if(debug) dfile << "info->height = " << info->height << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "texelFormat") {
- if(!readString(stream, info->texelFormat)) return false;
- if(debug) dfile << "info->texelFormat = " << info->texelFormat << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "transient") {
- if(!readNumber(stream, info->transient)) return false;
- if(debug) dfile << "info->transient = " << info->transient << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "wrapS") {
- if(!readNumber(stream, info->wrapS)) return false;
- if(debug) dfile << "info->wrapS = " << info->wrapS << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "wrapT") {
- if(!readNumber(stream, info->wrapT)) return false;
- if(debug) dfile << "info->wrapT = " << info->wrapT << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "wrapR") {
- if(!readNumber(stream, info->wrapR)) return false;
- if(debug) dfile << "info->wrapR = " << info->wrapR << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "minFilter") {
- if(!readNumber(stream, info->minFilter)) return false;
- if(debug) dfile << "info->minFilter = " << info->minFilter << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "magFilter") {
- if(!readNumber(stream, info->magFilter)) return false;
- if(debug) dfile << "info->magFilter = " << info->magFilter << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "automipmap") {
- if(!readNumber(stream, info->automipmap)) return false;
- if(debug) dfile << "info->automipmap = " << info->automipmap << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "numberMipMapLevels") {
- if(!readNumber(stream, info->numberMipMapLevels)) return false;
- if(debug) dfile << "info->numberMipMapLevels = " << info->numberMipMapLevels << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "gammaRemapR") {
- if(!readNumber(stream, info->gammaRemapR)) return false;
- if(debug) dfile << "info->gammaRemapR = " << info->gammaRemapR << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "gammaRemapG") {
- if(!readNumber(stream, info->gammaRemapG)) return false;
- if(debug) dfile << "info->gammaRemapG = " << info->gammaRemapG << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "gammaRemapB") {
- if(!readNumber(stream, info->gammaRemapB)) return false;
- if(debug) dfile << "info->gammaRemapB = " << info->gammaRemapB << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "gammaRemapA") {
- if(!readNumber(stream, info->gammaRemapA)) return false;
- if(debug) dfile << "info->gammaRemapA = " << info->gammaRemapA << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "lodBias") {
- if(!readNumber(stream, info->lodBias)) return false;
- if(debug) dfile << "info->lodBias = " << info->lodBias << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "resolveMSAA") {
- if(!readNumber(stream, info->resolveMSAA)) return false;
- if(debug) dfile << "info->resolveMSAA = " << info->resolveMSAA << endl;
- }
- else if(parameter == "TEXTURE" && attribute == "imageBlockCount") {
- if(!readNumber(stream, info->imageBlockCount)) return false;
- if(debug) dfile << "info->imageBlockCount = " << info->imageBlockCount << endl;
- }
- else if(parameter == "RENDERINTERFACEBOUND" && attribute == "allocationStrategy") {
- if(!readNumber(stream, info->allocationStrategy)) return false;
- if(debug) dfile << "info->allocationStrategy = " << info->allocationStrategy << endl;
- }
- else if(parameter == "XXX" && attribute == "id") {
- if(!readString(stream, info->filename)) return false;
- if(debug) dfile << "info->filename = " << info->filename << endl;
- }
- else {
- stringstream ss;
- ss << "Unknown block property " << parameter << ":" << attribute << "." << ends;
- return error(ss.str().c_str());
- }
- }
-
- // add child chunks to stack
- if(info->chunksize == info->propbytes + 4) return true;
- return processChildren(stream, node, position, info->chunksize - bytes_read - 4);
- }
-
- bool extractor::processTEXTUREIMAGEBLOCK(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "--------------------" << endl;
- if(debug) dfile << " TEXTUREIMAGEBLOCK " << endl;
- if(debug) dfile << "--------------------" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // insert node
- boost::shared_ptr<TREENODE> node(new TEXTUREIMAGEBLOCK);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- TEXTUREIMAGEBLOCK* info = static_cast<TEXTUREIMAGEBLOCK*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // validate
- if(info->propbytes > 1000) return error("Unexpected number of property table bytes.");
- if(info->propbytes == 0) return error("Property table expected.");
-
- // read properties
- uint32 bytes_read = 0;
- while(bytes_read < info->propbytes)
- {
- // read index
- uint32 type = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
-
- // data bytes
- uint32 size = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
- bytes_read += size;
-
- // find index
- typedef map<uint32, PSSGATTRIBUTE>::iterator iterator;
- iterator iter = attrlist.find(type);
- if(iter == attrlist.end()) {
- stringstream ss;
- ss << "Failed to find property for index " << type << "." << ends;
- return error(ss.str().c_str());
- }
-
- // read attributes
- const string& parameter = iter->second.parameter;
- const string& attribute = iter->second.attribute;
- if(parameter == "TEXTUREIMAGEBLOCK" && attribute == "typename") {
- if(!readString(stream, info->name)) return false;
- if(debug) dfile << "info->name = " << info->name << endl;
- }
- else if(parameter == "TEXTUREIMAGEBLOCK" && attribute == "size") {
- if(!readNumber(stream, info->size)) return false;
- if(debug) dfile << "info->size = " << info->size << endl;
- }
- else {
- stringstream ss;
- ss << "Unknown block property " << parameter << ":" << attribute << "." << ends;
- return error(ss.str().c_str());
- }
- }
-
- // add child chunks to stack
- if(info->chunksize == info->propbytes + 4) return true;
- return processChildren(stream, node, position, info->chunksize - bytes_read - 4);
- }
-
- bool extractor::processTEXTUREIMAGEBLOCKDATA(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "-----------------------" << endl;
- if(debug) dfile << " TEXTUREIMAGEBLOCKDATA " << endl;
- if(debug) dfile << "-----------------------" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // insert node
- boost::shared_ptr<TREENODE> node(new TEXTUREIMAGEBLOCKDATA);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- TEXTUREIMAGEBLOCKDATA* info = static_cast<TEXTUREIMAGEBLOCKDATA*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // validate
- if(info->propbytes) return error("Property table unexpected.");
-
- // get TEXTUREIMAGEBLOCK
- tree_iterator parent_ptr = tree.find(parent);
- if(parent_ptr == tree.end()) return error("Expecting TEXTUREIMAGEBLOCKDATA to have TEXTUREIMAGEBLOCK parent.");
- TEXTUREIMAGEBLOCK* tib = static_cast<TEXTUREIMAGEBLOCK*>(parent_ptr->second.get());
- if(!tib) return error("Static cast failed.");
-
- // get TEXTURE
- parent_ptr = tree.find(tib->parent);
- if(parent_ptr == tree.end()) return error("Expecting TEXTUREIMAGEBLOCK to have TEXTURE parent.");
- TEXTURE* texture = static_cast<TEXTURE*>(parent_ptr->second.get());
- if(!tib) return error("Static cast failed.");
-
- // read texture data
- info->data.reset(new unsigned char[tib->size]);
- stream.read((char*)info->data.get(), tib->size);
- if(stream.fail()) return error("Read failure.");
-
- // create filename
- if(!HasExtension(texture->filename, ".dds")) texture->filename += ".dds";
- stringstream filename;
- filename << GetPathnameFromFilename(currfile) << texture->filename;
-
- // save DDS file
- DDS_HEADER ddsh;
- if(texture->texelFormat == "dxt1") {
- CreateDXT1Header(texture->width, texture->height, texture->numberMipMapLevels, FALSE, &ddsh);
- ofstream ofile(filename.str().c_str(), ios::binary);
- if(!ofile) return error("Failed to create DDS file.");
- ofile.write("DDS ", 4);
- ofile.write((char*)&ddsh, sizeof(ddsh));
- ofile.write((char*)info->data.get(), tib->size);
- if(ofile.fail()) return error("Failed to write DDS data.");
- }
- else if(texture->texelFormat == "dxt2") {
- CreateDXT2Header(texture->width, texture->height, texture->numberMipMapLevels, FALSE, &ddsh);
- ofstream ofile(filename.str().c_str(), ios::binary);
- if(!ofile) return error("Failed to create DDS file.");
- ofile.write("DDS ", 4);
- ofile.write((char*)&ddsh, sizeof(ddsh));
- ofile.write((char*)info->data.get(), tib->size);
- if(ofile.fail()) return error("Failed to write DDS data.");
- }
- else if(texture->texelFormat == "dxt3") {
- CreateDXT3Header(texture->width, texture->height, texture->numberMipMapLevels, FALSE, &ddsh);
- ofstream ofile(filename.str().c_str(), ios::binary);
- if(!ofile) return error("Failed to create DDS file.");
- ofile.write("DDS ", 4);
- ofile.write((char*)&ddsh, sizeof(ddsh));
- ofile.write((char*)info->data.get(), tib->size);
- if(ofile.fail()) return error("Failed to write DDS data.");
- }
- else if(texture->texelFormat == "dxt4") {
- CreateDXT4Header(texture->width, texture->height, texture->numberMipMapLevels, FALSE, &ddsh);
- ofstream ofile(filename.str().c_str(), ios::binary);
- if(!ofile) return error("Failed to create DDS file.");
- ofile.write("DDS ", 4);
- ofile.write((char*)&ddsh, sizeof(ddsh));
- ofile.write((char*)info->data.get(), tib->size);
- }
- else if(texture->texelFormat == "dxt5") {
- CreateDXT5Header(texture->width, texture->height, texture->numberMipMapLevels, FALSE, &ddsh);
- ofstream ofile(filename.str().c_str(), ios::binary);
- if(!ofile) return error("Failed to create DDS file.");
- ofile.write("DDS ", 4);
- ofile.write((char*)&ddsh, sizeof(ddsh));
- ofile.write((char*)info->data.get(), tib->size);
- if(ofile.fail()) return error("Failed to write DDS data.");
- }
- else if(texture->texelFormat == "u8x4") {
- CreateUncompressedDDSHeader(texture->width, texture->height, texture->numberMipMapLevels, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000, FALSE, &ddsh);
- ofstream ofile(filename.str().c_str(), ios::binary);
- if(!ofile) return error("Failed to create DDS file.");
- ofile.write("DDS ", 4);
- ofile.write((char*)&ddsh, sizeof(ddsh));
- ofile.write((char*)info->data.get(), tib->size);
- if(ofile.fail()) return error("Failed to write DDS data.");
- }
- else if(texture->texelFormat == "ui8x4") {
- CreateUncompressedDDSHeader(texture->width, texture->height, texture->numberMipMapLevels, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000, FALSE, &ddsh);
- ofstream ofile(filename.str().c_str(), ios::binary);
- if(!ofile) return error("Failed to create DDS file.");
- ofile.write("DDS ", 4);
- ofile.write((char*)&ddsh, sizeof(ddsh));
- ofile.write((char*)info->data.get(), tib->size);
- if(ofile.fail()) return error("Failed to write DDS data.");
- }
- else {
- stringstream ss;
- ss << "Invalid texture compression method " << texture->texelFormat << ".";
- return error(ss.str().c_str());
- }
-
- // no children
- return true;
- }
-
- bool extractor::processTRANSFORM(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processTYPEINFO(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "----------" << endl;
- if(debug) dfile << " TYPEINFO " << endl;
- if(debug) dfile << "----------" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // insert node
- boost::shared_ptr<TREENODE> node(new TYPEINFO);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- TYPEINFO* info = static_cast<TYPEINFO*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // validate
- if(info->propbytes > 1000) return error("Unexpected number of property table bytes.");
- if(info->propbytes == 0) return error("Property table expected.");
-
- // read properties
- uint32 bytes_read = 0;
- while(bytes_read < info->propbytes)
- {
- // read index
- uint32 type = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
-
- // data bytes
- uint32 size = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
- bytes_read += size;
-
- // find index
- typedef map<uint32, PSSGATTRIBUTE>::iterator iterator;
- iterator iter = attrlist.find(type);
- if(iter == attrlist.end()) {
- stringstream ss;
- ss << "Failed to find property for index " << type << "." << ends;
- return error(ss.str().c_str());
- }
-
- // read attributes
- const string& parameter = iter->second.parameter;
- const string& attribute = iter->second.attribute;
- if(parameter == "TYPEINFO" && attribute == "typeName") {
- if(!readString(stream, info->typeName)) return false;
- if(debug) dfile << "info->typeName = " << info->typeName << endl;
- }
- else if(parameter == "TYPEINFO" && attribute == "typeCount") {
- if(!readNumber(stream, info->typeCount)) return false;
- if(debug) dfile << "info->typeCount = " << info->typeCount << endl;
- }
- else {
- stringstream ss;
- ss << "Unknown block property " << parameter << ":" << attribute << "." << ends;
- return error(ss.str().c_str());
- }
- }
-
- // add child chunks to stack
- if(info->chunksize == info->propbytes + 4) return true;
- return processChildren(stream, node, position, info->chunksize - bytes_read - 4);
- }
-
- bool extractor::processUSERATTRIBUTE(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processUSERATTRIBUTELIST(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processUSERDATA(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processWEIGHTS(const binary_stream& bs, uint32 position)
- {
- return true;
- }
-
- bool extractor::processXXX(const binary_stream& bs, uint32 position)
- {
- using namespace std;
- if(debug) dfile << endl;
- if(debug) dfile << "-----" << endl;
- if(debug) dfile << " XXX " << endl;
- if(debug) dfile << "-----" << endl;
- if(debug) dfile << "offset = " << position << endl;
-
- // set stream position
- binary_stream stream(bs);
- stream.seek(position);
-
- // insert node
- boost::shared_ptr<TREENODE> node(new XXX);
- typedef map<uint32, boost::shared_ptr<TREENODE>>::value_type value_type;
- tree.insert(value_type(position, node));
-
- // set parent
- uint32 parent = 0;
- map<uint32, uint32>::iterator iter = parent_list.find(position);
- if(iter != parent_list.end()) parent = iter->second;
- if(debug) dfile << "parent = " << parent << endl;
- node->parent = parent;
-
- // read chunk properties
- XXX* info = static_cast<XXX*>(node.get());
- info->chunktype = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->chunksize = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- info->propbytes = stream.BE_read_uint32(); if(stream.fail()) return error("Read failed.");
- if(debug) dfile << "chunktype = " << info->chunktype << endl;
- if(debug) dfile << "chunksize = " << info->chunksize << endl;
- if(debug) dfile << "propbytes = " << info->propbytes << endl;
-
- // initialize attributes
- info->id = "";
-
- // validate
- if(info->propbytes > 1000) return error("Unexpected number of property table bytes.");
- if(info->propbytes == 0) return error("Property table expected.");
-
- // read properties
- uint32 bytes_read = 0;
- while(bytes_read < info->propbytes)
- {
- // read index
- uint32 type = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
-
- // data bytes
- uint32 size = stream.BE_read_uint32();
- if(stream.fail()) return error("Read failed.");
- bytes_read += 4;
- bytes_read += size;
-
- // find index
- typedef map<uint32, PSSGATTRIBUTE>::iterator iterator;
- iterator iter = attrlist.find(type);
- if(iter == attrlist.end()) {
- stringstream ss;
- ss << "Failed to find property for index " << type << "." << ends;
- return error(ss.str().c_str());
- }
-
- // read attributes
- const string& parameter = iter->second.parameter;
- const string& attribute = iter->second.attribute;
- if(parameter == "XXX" && attribute == "id") {
- if(!readString(stream, info->id)) return false;
- if(debug) dfile << "info->id = " << info->id << endl;
- }
- else {
- stringstream ss;
- ss << "Unknown block property " << parameter << ":" << attribute << "." << ends;
- return error(ss.str().c_str());
- }
- }
-
- // add child chunks to stack
- if(info->chunksize == info->propbytes + 4) return true;
- return processChildren(stream, node, position, info->chunksize - bytes_read - 4);
- }
-
- };
-
- namespace PSSG {
-
- bool extract(void)
- {
- std::string pathname = GetModulePathname();
- return extract(pathname.c_str());
- }
-
- bool extract(const char* pathname)
- {
- return extractor(pathname).extract();
- }
-
- };