diff --git a/include/gen/Header.h b/include/gen/Header.h index 1aceda4ba90f20dd103ab61386ea631af9cac7e5..378bebb785babeb780a2a6a821942d3e2dd7455b 100644 --- a/include/gen/Header.h +++ b/include/gen/Header.h @@ -44,10 +44,6 @@ struct NIFLIB_API Header { * Number of file objects. */ mutable uint numBlocks; - /*! - * Unknown. - */ - uint unknownInt1; /*! * This also appears to be the extra user version number and must be set * in some circumstances. diff --git a/include/gen/obj_defines.h b/include/gen/obj_defines.h index 5bdd4a43f88a36e4f96e8dc58e3aff2d2c747083..ba1efdfedcc93526d62312bf444cee93e0fefb4d 100644 --- a/include/gen/obj_defines.h +++ b/include/gen/obj_defines.h @@ -3071,10 +3071,10 @@ vector< array<4,float> > unknownFloats3; \ vector< array<10,float> > unknownFloats4; \ vector< array<12,float> > unknownFloats5; \ uint unknownInt1; \ -Ref<NiPSysModifier > modifier; \ +Ref<NiObject > modifier; \ byte unknownByte2; \ mutable uint numUnknownLinks; \ -vector<Ref<NiPSysModifier > > unknownLinks; \ +vector<Ref<NiObject > > unknownLinks; \ ushort unknownShort4; \ uint unknownInt2; \ byte unknownByte12; \ diff --git a/include/nif_versions.h b/include/nif_versions.h index 6d77e1556ba9acc3b84bccc36bac93f5748d4662..30833a6f545b9d049d7afa6bba89649f1110d998 100644 --- a/include/nif_versions.h +++ b/include/nif_versions.h @@ -5,7 +5,9 @@ All rights reserved. Please see niflib.h for licence. */ #define _NIF_VERSIONS_H_ //NIF Version Constants -const unsigned VER_4_0_0_0 = 0X04000000; /*!< NIF Version 4.0.0.0 */ + +const unsigned VER_3_3_0_13 = 0x0303000D; /*!< NIF Version 3.3.0.13 */ +const unsigned VER_4_0_0_0 = 0x04000000; /*!< NIF Version 4.0.0.0 */ const unsigned VER_4_0_0_2 = 0x04000002; /*!< NIF Version 4.0.0.2 */ const unsigned VER_4_1_0_12 = 0x0401000C; /*!< NIF Version 4.1.0.12 */ const unsigned VER_4_2_0_2 = 0x04020002; /*!< NIF Version 4.2.0.2 */ diff --git a/src/NIF_IO.cpp b/src/NIF_IO.cpp index 53222bad2e9fee01a6ae9e1c5c97548e3e59613b..90b0dc5dea12affeae85d2df6637bf1f7c79c038 100644 --- a/src/NIF_IO.cpp +++ b/src/NIF_IO.cpp @@ -5,74 +5,74 @@ All rights reserved. Please see niflib.h for licence. */ #include "../include/niflib.h" namespace Niflib { -int BlockSearch( istream& in ) { - - //Get current file pos - int data_start = in.tellg(); - - //cout << "Current File Pos: " << data_start << endl; - //cout << "Searching for next block..." << endl; - - //Find Next Block - char tmp1 = 0, tmp2 = 0; - uint next_name_len = 0; - while (!in.eof()) { - while (!in.eof() && !((tmp1 == 'N' && tmp2 == 'i') || (tmp1 == 'R' && tmp2 == 'o') || (tmp1 == 'A' && tmp2 == 'v')) ) { - tmp1 = tmp2; - in.read(&tmp2, 1); - } - if (in.eof()) - break; - - //Move back to before the uint that holds the length of the string - in.seekg(-6, ios_base::cur); - - //Read the length of the string - next_name_len = ReadUInt( in ); - - //cout << "Matching Data: " << tmp1 << tmp2 << endl; - - //if name length is > 40, then this is unlikley to be a real node. - if (next_name_len <= 40 && next_name_len >= 5) { - //Read the string - char* next_name = new char[next_name_len]; - in.read( next_name, next_name_len ); - - //cout << "Found Match: " << Str(next_name, next_name_len) << endl; - - //Move back to where we were before we read anything - in.seekg( -(int(next_name_len) - 2), ios_base::cur); - - break; - } - else { - //Move back to where we were before we read anything - in.seekg(2, ios_base::cur); - - tmp1 = tmp2 = 0; - //cout << "Found possible block at: " << int(in.tellg()) - 6 << endl; - } - } - - //Note length of data - int data_length = 0; - if (in.eof()) { - //cout << "Reached End of File. Assuming no more blocks to find." << endl; - in.clear(); - in.seekg(-8, ios_base::end); - data_length = int(in.tellg()) - data_start; - in.seekg(data_start, ios_base::beg); - } - else { - in.seekg(-6, ios_base::cur); - data_length = int(in.tellg()) - data_start; - in.seekg(data_start, ios_base::beg); - } - - //cout << "Unknown area (" << data_length << " bytes):" << endl; - - return data_length; -} +//int BlockSearch( istream& in ) { +// +// //Get current file pos +// int data_start = in.tellg(); +// +// //cout << "Current File Pos: " << data_start << endl; +// //cout << "Searching for next block..." << endl; +// +// //Find Next Block +// char tmp1 = 0, tmp2 = 0; +// uint next_name_len = 0; +// while (!in.eof()) { +// while (!in.eof() && !((tmp1 == 'N' && tmp2 == 'i') || (tmp1 == 'R' && tmp2 == 'o') || (tmp1 == 'A' && tmp2 == 'v')) ) { +// tmp1 = tmp2; +// in.read(&tmp2, 1); +// } +// if (in.eof()) +// break; +// +// //Move back to before the uint that holds the length of the string +// in.seekg(-6, ios_base::cur); +// +// //Read the length of the string +// next_name_len = ReadUInt( in ); +// +// //cout << "Matching Data: " << tmp1 << tmp2 << endl; +// +// //if name length is > 40, then this is unlikley to be a real node. +// if (next_name_len <= 40 && next_name_len >= 5) { +// //Read the string +// char* next_name = new char[next_name_len]; +// in.read( next_name, next_name_len ); +// +// //cout << "Found Match: " << Str(next_name, next_name_len) << endl; +// +// //Move back to where we were before we read anything +// in.seekg( -(int(next_name_len) - 2), ios_base::cur); +// +// break; +// } +// else { +// //Move back to where we were before we read anything +// in.seekg(2, ios_base::cur); +// +// tmp1 = tmp2 = 0; +// //cout << "Found possible block at: " << int(in.tellg()) - 6 << endl; +// } +// } +// +// //Note length of data +// int data_length = 0; +// if (in.eof()) { +// //cout << "Reached End of File. Assuming no more blocks to find." << endl; +// in.clear(); +// in.seekg(-8, ios_base::end); +// data_length = int(in.tellg()) - data_start; +// in.seekg(data_start, ios_base::beg); +// } +// else { +// in.seekg(-6, ios_base::cur); +// data_length = int(in.tellg()) - data_start; +// in.seekg(data_start, ios_base::beg); +// } +// +// //cout << "Unknown area (" << data_length << " bytes):" << endl; +// +// return data_length; +//} /** * Read utility functions @@ -254,7 +254,7 @@ void NifStream( HeaderString & val, istream& in, uint & version ) { version = ParseVersionString( val.header.substr( ver_start ) ); //Temporarily read the next 3 strings if this is a < 4 file - if ( version < VER_4_0_0_0 ) { + if ( version < VER_3_3_0_13 ) { in.getline( tmp, 256 ); in.getline( tmp, 256 ); in.getline( tmp, 256 ); diff --git a/src/gen/Header.cpp b/src/gen/Header.cpp index 6a192a85afdd8215a8112a2a1bfea21970b40b74..db066cab1b57ecaf9ac121b4cf2544232c71f791 100644 --- a/src/gen/Header.cpp +++ b/src/gen/Header.cpp @@ -5,13 +5,13 @@ All rights reserved. Please see niflib.h for licence. */ using namespace Niflib; //Constructor -Header::Header() : version((uint)0x04000002), endianType((byte)1), userVersion((uint)0), numBlocks((uint)0), unknownInt1((uint)1), userVersion2((uint)0), numBlockTypes((ushort)0), unknownInt2((uint)0) {}; +Header::Header() : version((uint)0x04000002), endianType((byte)1), userVersion((uint)0), numBlocks((uint)0), userVersion2((uint)0), numBlockTypes((ushort)0), unknownInt2((uint)0) {}; //Destructor Header::~Header() {}; void Header::Read( istream& in ) { NifStream( headerString, in, version ); - if ( version >= 0x04000000 ) { + if ( version >= 0x0303000D ) { NifStream( version, in, version ); }; if ( version >= 0x14000004 ) { @@ -20,11 +20,11 @@ void Header::Read( istream& in ) { if ( version >= 0x0A010000 ) { NifStream( userVersion, in, version ); }; - if ( version >= 0x04000000 ) { + if ( version >= 0x0303000D ) { NifStream( numBlocks, in, version ); }; if ( ( version >= 0x0A000102 ) && ( version <= 0x0A000102 ) ) { - NifStream( unknownInt1, in, version ); + NifStream( userVersion, in, version ); }; if ( version >= 0x0A010000 ) { if ( (userVersion != 0) ) { @@ -56,7 +56,7 @@ void Header::Write( ostream& out ) const { numBlockTypes = ushort(blockTypes.size()); numBlocks = uint(blockTypeIndex.size()); NifStream( headerString, out, version ); - if ( version >= 0x04000000 ) { + if ( version >= 0x0303000D ) { NifStream( version, out, version ); }; if ( version >= 0x14000004 ) { @@ -65,11 +65,11 @@ void Header::Write( ostream& out ) const { if ( version >= 0x0A010000 ) { NifStream( userVersion, out, version ); }; - if ( version >= 0x04000000 ) { + if ( version >= 0x0303000D ) { NifStream( numBlocks, out, version ); }; if ( ( version >= 0x0A000102 ) && ( version <= 0x0A000102 ) ) { - NifStream( unknownInt1, out, version ); + NifStream( userVersion, out, version ); }; if ( version >= 0x0A010000 ) { if ( (userVersion != 0) ) { @@ -104,7 +104,6 @@ string Header::asString( bool verbose ) const { out << " Endian Type: " << endianType << endl; out << " User Version: " << userVersion << endl; out << " Num Blocks: " << numBlocks << endl; - out << " Unknown Int 1: " << unknownInt1 << endl; if ( (userVersion != 0) ) { out << " User Version 2: " << userVersion2 << endl; out << " Creator: " << creator << endl; diff --git a/src/gen/obj_impl.cpp b/src/gen/obj_impl.cpp index 64610f9691ccd1ee0e67eff449d6393a82712c02..c1cead69ef62b6bfc88eddf5ce79443a49cd5325 100644 --- a/src/gen/obj_impl.cpp +++ b/src/gen/obj_impl.cpp @@ -6385,11 +6385,11 @@ std::string NiMeshPSysData::InternalAsString( bool verbose ) const { void NiMeshPSysData::InternalFixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version ) { APSysData::FixLinks( objects, link_stack, version, user_version ); if ( version <= 0x14000004 ) { - modifier = FixLink<NiPSysModifier>( objects, link_stack, version ); + modifier = FixLink<NiObject>( objects, link_stack, version ); }; if ( ( version >= 0x0A020000 ) && ( version <= 0x14000004 ) ) { for (uint i2 = 0; i2 < unknownLinks.size(); i2++) { - unknownLinks[i2] = FixLink<NiPSysModifier>( objects, link_stack, version ); + unknownLinks[i2] = FixLink<NiObject>( objects, link_stack, version ); }; }; if ( version >= 0x0A020000 ) { diff --git a/src/niflib.cpp b/src/niflib.cpp index 389f2668e565dced16ddf2d335f61ce45625b429..ef9d8bc31b924449b81def87132e9b2245b57716 100644 --- a/src/niflib.cpp +++ b/src/niflib.cpp @@ -133,6 +133,8 @@ vector<NiObjectRef> ReadNifList( string const & file_name, NifInfo * info ) { ifstream in( file_name.c_str(), ifstream::binary ); return ReadNifList( in ); + + in.close(); } //Reads the given input stream and returns a vector of block references @@ -195,9 +197,9 @@ vector<NiObjectRef> ReadNifList( istream & in, NifInfo * info ) { //There are two main ways to read objects //One before version 5.0.0.1 and one after if ( header.version >= 0x05000001 ) { - //From version 5.0.0.1 to version 10.0.1.0 there is a zero byte at the begining of each object + //From version 5.0.0.1 to version 10.0.1.106 there is a zero byte at the begining of each object - if ( header.version <= VER_10_1_0_0 ) { + if ( header.version <= VER_10_1_0_106 ) { uint checkValue = ReadUInt( in ); if ( checkValue != 0 ) { //Throw an exception if it's not zero @@ -215,6 +217,10 @@ vector<NiObjectRef> ReadNifList( istream & in, NifInfo * info ) { // Find which block type this is by using the header arrays objectType = header.blockTypes[ header.blockTypeIndex[i] ]; + +#ifdef PRINT_OBJECT_NAMES + cout << endl << i << ": " << objectType; +#endif } else { // Find which object type this is by reading the string at this location uint objectTypeLength = ReadUInt( in ); @@ -239,7 +245,7 @@ vector<NiObjectRef> ReadNifList( istream & in, NifInfo * info ) { cout << endl << i << ": " << objectType; #endif - if ( header.version < VER_4_0_0_0 ) { + if ( header.version < VER_3_3_0_13 ) { //There can be special commands instead of object names //in these versions @@ -284,7 +290,7 @@ vector<NiObjectRef> ReadNifList( istream & in, NifInfo * info ) { } uint index; - if ( header.version < VER_4_0_0_0 ) { + if ( header.version < VER_3_3_0_13 ) { //These old versions have a pointer value after the name //which is used as the index index = ReadUInt(in); @@ -301,7 +307,7 @@ vector<NiObjectRef> ReadNifList( istream & in, NifInfo * info ) { cout << endl << new_obj->asString() << endl; #endif - if ( header.version >= VER_4_0_0_0 ) { + if ( header.version >= VER_3_3_0_13 ) { //We know the number of objects, so increment the count //and break if we've finished ++i; @@ -340,10 +346,6 @@ vector<NiObjectRef> ReadNifList( istream & in, NifInfo * info ) { cout << "Fixing Links:" << endl; #endif //--Now that all blocks are read, go back and fix the links--// - if ( header.version < VER_4_0_0_0 ) { - //First wen - } - vector<NiObjectRef> obj_list; for ( map<unsigned,NiObjectRef>::iterator it = objects.begin(); it != objects.end(); ++it ) { @@ -1069,6 +1071,7 @@ void MergeNifTrees( const Ref<NiNode> & target, const Ref<NiSequenceStreamHelper bool IsSupportedVersion( unsigned int version ) { switch (version) { + case VER_3_3_0_13: case VER_4_0_0_0: case VER_4_0_0_2: case VER_4_1_0_12: @@ -1130,11 +1133,11 @@ string FormatVersionString(unsigned version) { //Format the version string and return it stringstream out; - if ( int_ver[0] >= 4 ) { - //Version 4+ is in x.x.x.x format. + if ( version >= VER_3_3_0_13 ) { + //Version 3.3.0.13+ is in x.x.x.x format. out << int_ver[0] << "." << int_ver[1] << "." << int_ver[2] << "." << int_ver[3]; } else { - //Versions before 4 are in x.x format. + //Versions before 3.3.0.13 are in x.x format. out << int_ver[0] << "." << int_ver[1]; }