From ffcab1cb17f8d8bc23c9c518a590809bcf286919 Mon Sep 17 00:00:00 2001
From: Shon Ferguson <shonferg@users.sourceforge.net>
Date: Fri, 29 Sep 2006 05:30:14 +0000
Subject: [PATCH] Updated from XML.  Adds some new objects from version 3.1,
 but most files still can't be opened.

---
 include/NIF_IO.h                    |   5 +
 include/gen/Header.h                |   4 +
 include/gen/obj_defines.h           |  32 ++++++
 include/nif_basic_types.h           |   4 +
 include/nif_versions.h              |   1 +
 include/obj/NiImage.h               |  47 ++++++++
 include/obj/NiTextureModeProperty.h |  47 ++++++++
 include/obj/NiTextureProperty.h     |  52 +++++++++
 niflib.vcproj                       |  24 ++++
 src/NIF_IO.cpp                      |  15 +++
 src/gen/Header.cpp                  |  22 ++++
 src/gen/obj_factories.cpp           |   9 ++
 src/gen/obj_impl.cpp                | 172 ++++++++++++++++++++++++----
 src/niflib.cpp                      |  32 +++---
 src/obj/NiImage.cpp                 |  37 ++++++
 src/obj/NiTextureModeProperty.cpp   |  37 ++++++
 src/obj/NiTextureProperty.cpp       |  38 ++++++
 17 files changed, 541 insertions(+), 37 deletions(-)
 create mode 100644 include/obj/NiImage.h
 create mode 100644 include/obj/NiTextureModeProperty.h
 create mode 100644 include/obj/NiTextureProperty.h
 create mode 100644 src/obj/NiImage.cpp
 create mode 100644 src/obj/NiTextureModeProperty.cpp
 create mode 100644 src/obj/NiTextureProperty.cpp

diff --git a/include/NIF_IO.h b/include/NIF_IO.h
index 1ed62105..0c4a073d 100644
--- a/include/NIF_IO.h
+++ b/include/NIF_IO.h
@@ -325,6 +325,11 @@ void NifStream( HeaderString & val, istream& in, uint & version ); //Sets the pa
 void NifStream( HeaderString const & val, ostream& out, uint version = 0  );
 ostream & operator<<( ostream & out, HeaderString const & val );
 
+//LineString
+void NifStream( LineString & val, istream& in, uint version );
+void NifStream( LineString const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, LineString const & val );
+
 //ShortString
 void NifStream( ShortString & val, istream& in, uint version = 0 );
 void NifStream( ShortString const & val, ostream& out, uint version = 0  );
diff --git a/include/gen/Header.h b/include/gen/Header.h
index 378bebb7..b15e6630 100644
--- a/include/gen/Header.h
+++ b/include/gen/Header.h
@@ -24,6 +24,10 @@ struct NIFLIB_API Header {
 	 * written out. Ends with a newline character (0x0A).
 	 */
 	HeaderString headerString;
+	/*!
+	 * Unknown.
+	 */
+	array<3,LineString> copyright;
 	/*!
 	 * The NIF version, in hexadecimal notation: 0x04000002, 0x0401000C,
 	 * 0x04020002, 0x04020100, 0x04020200, 0x0A000100, 0x0A010000,
diff --git a/include/gen/obj_defines.h b/include/gen/obj_defines.h
index 9fddef74..474271ec 100644
--- a/include/gen/obj_defines.h
+++ b/include/gen/obj_defines.h
@@ -1121,6 +1121,18 @@ TexType textureSlot; \
 uint operation; \
 Ref<NiFloatData > data; \
 
+#define NI_TEXTURE_MODE_PROPERTY_MEMBERS \
+array<3,short> unknown3Shorts; \
+
+#define NI_IMAGE_MEMBERS \
+byte external_; \
+string file; \
+array<4,short> unknown4Shorts; \
+
+#define NI_TEXTURE_PROPERTY_MEMBERS \
+ushort flags; \
+Ref<NiImage > image; \
+
 #define NI_TEXTURING_PROPERTY_MEMBERS \
 ushort flags; \
 ApplyMode applyMode; \
@@ -1425,6 +1437,9 @@ CompareMode function; \
 #define NI_TEXT_KEY_EXTRA_DATA_MEMBERS
 #define NI_TEXTURE_EFFECT_MEMBERS
 #define NI_TEXTURE_TRANSFORM_CONTROLLER_MEMBERS
+#define NI_TEXTURE_MODE_PROPERTY_MEMBERS
+#define NI_IMAGE_MEMBERS
+#define NI_TEXTURE_PROPERTY_MEMBERS
 #define NI_TEXTURING_PROPERTY_MEMBERS
 #define NI_TRANSFORM_CONTROLLER_MEMBERS
 #define NI_TRANSFORM_DATA_MEMBERS
@@ -2582,6 +2597,23 @@ CompareMode function; \
 
 #define NI_TEXTURE_TRANSFORM_CONTROLLER_CONSTRUCT  : unknown2((byte)0), operation((uint)0), data(NULL)
 
+#define NI_TEXTURE_MODE_PROPERTY_INCLUDE "NiProperty.h"
+
+#define NI_TEXTURE_MODE_PROPERTY_PARENT NiProperty
+
+#define NI_TEXTURE_MODE_PROPERTY_CONSTRUCT 
+#define NI_IMAGE_INCLUDE "NiObject.h"
+
+#define NI_IMAGE_PARENT NiObject
+
+#define NI_IMAGE_CONSTRUCT  : external_((byte)0)
+
+#define NI_TEXTURE_PROPERTY_INCLUDE "NiProperty.h"
+
+#define NI_TEXTURE_PROPERTY_PARENT NiProperty
+
+#define NI_TEXTURE_PROPERTY_CONSTRUCT  : flags((ushort)0), image(NULL)
+
 #define NI_TEXTURING_PROPERTY_INCLUDE "NiProperty.h"
 
 #define NI_TEXTURING_PROPERTY_PARENT NiProperty
diff --git a/include/nif_basic_types.h b/include/nif_basic_types.h
index a339d0be..c597d2a0 100644
--- a/include/nif_basic_types.h
+++ b/include/nif_basic_types.h
@@ -17,6 +17,10 @@ struct ShortString {
 	string str;
 };
 
+struct LineString {
+	string line;
+};
+
 //--Non-mathematical Basic Types--//
 
 typedef unsigned char	byte;
diff --git a/include/nif_versions.h b/include/nif_versions.h
index 30833a6f..4abb0ff4 100644
--- a/include/nif_versions.h
+++ b/include/nif_versions.h
@@ -6,6 +6,7 @@ All rights reserved.  Please see niflib.h for licence. */
 
 //NIF Version Constants
 
+const unsigned VER_3_1         = 0x03010000; /*!< NIF Version 3.3.0.13 */
 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 */ 
diff --git a/include/obj/NiImage.h b/include/obj/NiImage.h
new file mode 100644
index 00000000..0015d772
--- /dev/null
+++ b/include/obj/NiImage.h
@@ -0,0 +1,47 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for licence. */
+
+#ifndef _NIIMAGE_H_
+#define _NIIMAGE_H_
+
+#include "NiObject.h"
+namespace Niflib {
+
+
+#include "../gen/obj_defines.h"
+
+class NiImage;
+typedef Ref<NiImage> NiImageRef;
+
+/*!
+ * NiImage -
+ */
+
+class NIFLIB_API NiImage : public NI_IMAGE_PARENT {
+public:
+	NiImage();
+	~NiImage();
+	//Run-Time Type Information
+	static const Type & TypeConst() { return TYPE; }
+private:
+	static const Type TYPE;
+public:
+	virtual void Read( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version );
+	virtual void Write( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const;
+	virtual string asString( bool verbose = false ) const;
+	virtual void FixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version );
+	virtual list<NiObjectRef> GetRefs() const;
+	virtual const Type & GetType() const;
+
+protected:
+	NI_IMAGE_MEMBERS
+private:
+	void InternalRead( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version );
+	void InternalWrite( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const;
+	string InternalAsString( bool verbose ) const;
+	void InternalFixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version );
+	list<NiObjectRef> InternalGetRefs() const;
+};
+
+}
+#endif
diff --git a/include/obj/NiTextureModeProperty.h b/include/obj/NiTextureModeProperty.h
new file mode 100644
index 00000000..f1124a40
--- /dev/null
+++ b/include/obj/NiTextureModeProperty.h
@@ -0,0 +1,47 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for licence. */
+
+#ifndef _NITEXTUREMODEPROPERTY_H_
+#define _NITEXTUREMODEPROPERTY_H_
+
+#include "NiProperty.h"
+namespace Niflib {
+
+
+#include "../gen/obj_defines.h"
+
+class NiTextureModeProperty;
+typedef Ref<NiTextureModeProperty> NiTextureModePropertyRef;
+
+/*!
+ * NiTextureModeProperty - Unknown
+ */
+
+class NIFLIB_API NiTextureModeProperty : public NI_TEXTURE_MODE_PROPERTY_PARENT {
+public:
+	NiTextureModeProperty();
+	~NiTextureModeProperty();
+	//Run-Time Type Information
+	static const Type & TypeConst() { return TYPE; }
+private:
+	static const Type TYPE;
+public:
+	virtual void Read( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version );
+	virtual void Write( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const;
+	virtual string asString( bool verbose = false ) const;
+	virtual void FixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version );
+	virtual list<NiObjectRef> GetRefs() const;
+	virtual const Type & GetType() const;
+
+protected:
+	NI_TEXTURE_MODE_PROPERTY_MEMBERS
+private:
+	void InternalRead( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version );
+	void InternalWrite( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const;
+	string InternalAsString( bool verbose ) const;
+	void InternalFixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version );
+	list<NiObjectRef> InternalGetRefs() const;
+};
+
+}
+#endif
diff --git a/include/obj/NiTextureProperty.h b/include/obj/NiTextureProperty.h
new file mode 100644
index 00000000..0769a19a
--- /dev/null
+++ b/include/obj/NiTextureProperty.h
@@ -0,0 +1,52 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for licence. */
+
+#ifndef _NITEXTUREPROPERTY_H_
+#define _NITEXTUREPROPERTY_H_
+
+#include "NiProperty.h"
+
+// Include structures
+#include "../Ref.h"
+namespace Niflib {
+
+// Forward define of referenced blocks
+class NiImage;
+
+#include "../gen/obj_defines.h"
+
+class NiTextureProperty;
+typedef Ref<NiTextureProperty> NiTexturePropertyRef;
+
+/*!
+ * NiTextureProperty -
+ */
+
+class NIFLIB_API NiTextureProperty : public NI_TEXTURE_PROPERTY_PARENT {
+public:
+	NiTextureProperty();
+	~NiTextureProperty();
+	//Run-Time Type Information
+	static const Type & TypeConst() { return TYPE; }
+private:
+	static const Type TYPE;
+public:
+	virtual void Read( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version );
+	virtual void Write( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const;
+	virtual string asString( bool verbose = false ) const;
+	virtual void FixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version );
+	virtual list<NiObjectRef> GetRefs() const;
+	virtual const Type & GetType() const;
+
+protected:
+	NI_TEXTURE_PROPERTY_MEMBERS
+private:
+	void InternalRead( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version );
+	void InternalWrite( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const;
+	string InternalAsString( bool verbose ) const;
+	void InternalFixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version );
+	list<NiObjectRef> InternalGetRefs() const;
+};
+
+}
+#endif
diff --git a/niflib.vcproj b/niflib.vcproj
index a3ccfbd0..5da87071 100644
--- a/niflib.vcproj
+++ b/niflib.vcproj
@@ -930,6 +930,10 @@
 					RelativePath=".\src\obj\NiGravity.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiImage.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiIntegerExtraData.cpp"
 					>
@@ -1302,6 +1306,14 @@
 					RelativePath=".\src\obj\NiTextureEffect.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiTextureModeProperty.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\src\obj\NiTextureProperty.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiTextureTransformController.cpp"
 					>
@@ -2024,6 +2036,10 @@
 					RelativePath=".\include\obj\NiGravity.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiImage.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiIntegerExtraData.h"
 					>
@@ -2396,6 +2412,14 @@
 					RelativePath=".\include\obj\NiTextureEffect.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiTextureModeProperty.h"
+					>
+				</File>
+				<File
+					RelativePath=".\include\obj\NiTextureProperty.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiTextureTransformController.h"
 					>
diff --git a/src/NIF_IO.cpp b/src/NIF_IO.cpp
index 338f1dd8..06242f11 100644
--- a/src/NIF_IO.cpp
+++ b/src/NIF_IO.cpp
@@ -284,6 +284,21 @@ ostream & operator<<( ostream & out, HeaderString const & val ) {
 	return out << val.header;
 }
 
+//LineString
+void NifStream( LineString & val, istream& in, uint version ) {
+	char tmp[256];
+	in.getline( tmp, 256 );
+	val.line = tmp;
+};
+
+void NifStream( LineString const & val, ostream& out, uint version ) {
+	out << val.line << "\n";
+};
+
+ostream & operator<<( ostream & out, LineString const & val ) {
+	return out << val.line;
+}
+
 //ShortString
 void NifStream( ShortString & val, istream& in, uint version ) {
 	byte len = ReadByte( in );
diff --git a/src/gen/Header.cpp b/src/gen/Header.cpp
index 3005a802..2d24fdca 100644
--- a/src/gen/Header.cpp
+++ b/src/gen/Header.cpp
@@ -11,6 +11,11 @@ Header::Header() : version((uint)0x04000002), endianType((byte)1), userVersion((
 Header::~Header() {};
 void Header::Read( istream& in ) {
 	NifStream( headerString, in, version );
+	if ( version <= 0x03010000 ) {
+		for (uint i2 = 0; i2 < 3; i2++) {
+			NifStream( copyright[i2], in, version );
+		};
+	};
 	if ( version >= 0x0303000D ) {
 		NifStream( version, in, version );
 	};
@@ -56,6 +61,11 @@ void Header::Write( ostream& out ) const {
 	numBlockTypes = ushort(blockTypes.size());
 	numBlocks = uint(blockTypeIndex.size());
 	NifStream( headerString, out, version );
+	if ( version <= 0x03010000 ) {
+		for (uint i2 = 0; i2 < 3; i2++) {
+			NifStream( copyright[i2], out, version );
+		};
+	};
 	if ( version >= 0x0303000D ) {
 		NifStream( version, out, version );
 	};
@@ -101,6 +111,18 @@ string Header::asString( bool verbose ) const {
 	numBlockTypes = ushort(blockTypes.size());
 	numBlocks = uint(blockTypeIndex.size());
 	out << "  Header String:  " << headerString << endl;
+	array_output_count = 0;
+	for (uint i1 = 0; i1 < 3; i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			break;
+		};
+		out << "    Copyright[" << i1 << "]:  " << copyright[i1] << endl;
+		array_output_count++;
+	};
 	out << "  Version:  " << version << endl;
 	out << "  Endian Type:  " << endianType << endl;
 	out << "  User Version:  " << userVersion << endl;
diff --git a/src/gen/obj_factories.cpp b/src/gen/obj_factories.cpp
index d652ab2d..69dd5237 100644
--- a/src/gen/obj_factories.cpp
+++ b/src/gen/obj_factories.cpp
@@ -335,6 +335,12 @@ NiObject * CreateNiTextKeyExtraData() { return new NiTextKeyExtraData; }
 NiObject * CreateNiTextureEffect() { return new NiTextureEffect; }
 #include "../../include/obj/NiTextureTransformController.h"
 NiObject * CreateNiTextureTransformController() { return new NiTextureTransformController; }
+#include "../../include/obj/NiTextureModeProperty.h"
+NiObject * CreateNiTextureModeProperty() { return new NiTextureModeProperty; }
+#include "../../include/obj/NiImage.h"
+NiObject * CreateNiImage() { return new NiImage; }
+#include "../../include/obj/NiTextureProperty.h"
+NiObject * CreateNiTextureProperty() { return new NiTextureProperty; }
 #include "../../include/obj/NiTexturingProperty.h"
 NiObject * CreateNiTexturingProperty() { return new NiTexturingProperty; }
 #include "../../include/obj/NiTransformController.h"
@@ -542,6 +548,9 @@ void RegisterBlockFactories() {
 	global_block_map["NiTextKeyExtraData"] = CreateNiTextKeyExtraData;
 	global_block_map["NiTextureEffect"] = CreateNiTextureEffect;
 	global_block_map["NiTextureTransformController"] = CreateNiTextureTransformController;
+	global_block_map["NiTextureModeProperty"] = CreateNiTextureModeProperty;
+	global_block_map["NiImage"] = CreateNiImage;
+	global_block_map["NiTextureProperty"] = CreateNiTextureProperty;
 	global_block_map["NiTexturingProperty"] = CreateNiTexturingProperty;
 	global_block_map["NiTransformController"] = CreateNiTransformController;
 	global_block_map["NiTransformData"] = CreateNiTransformData;
diff --git a/src/gen/obj_impl.cpp b/src/gen/obj_impl.cpp
index 9871c534..de9f2607 100644
--- a/src/gen/obj_impl.cpp
+++ b/src/gen/obj_impl.cpp
@@ -168,6 +168,9 @@ using namespace std;
 #include "../../include/obj/NiTextKeyExtraData.h"
 #include "../../include/obj/NiTextureEffect.h"
 #include "../../include/obj/NiTextureTransformController.h"
+#include "../../include/obj/NiTextureModeProperty.h"
+#include "../../include/obj/NiImage.h"
+#include "../../include/obj/NiTextureProperty.h"
 #include "../../include/obj/NiTexturingProperty.h"
 #include "../../include/obj/NiTransformController.h"
 #include "../../include/obj/NiTransformData.h"
@@ -1619,8 +1622,10 @@ void NiGeometry::InternalRead( istream& in, list<uint> & link_stack, unsigned in
 	NiAVObject::Read( in, link_stack, version, user_version );
 	NifStream( block_num, in, version );
 	link_stack.push_back( block_num );
-	NifStream( block_num, in, version );
-	link_stack.push_back( block_num );
+	if ( version >= 0x0303000D ) {
+		NifStream( block_num, in, version );
+		link_stack.push_back( block_num );
+	};
 	if ( version >= 0x0A000100 ) {
 		NifStream( hasShader, in, version );
 		if ( (hasShader != 0) ) {
@@ -1637,10 +1642,12 @@ void NiGeometry::InternalWrite( ostream& out, map<NiObjectRef,uint> link_map, un
 		NifStream( link_map[StaticCast<NiObject>(data)], out, version );
 	else
 		NifStream( 0xffffffff, out, version );
-	if ( skinInstance != NULL )
-		NifStream( link_map[StaticCast<NiObject>(skinInstance)], out, version );
-	else
-		NifStream( 0xffffffff, out, version );
+	if ( version >= 0x0303000D ) {
+		if ( skinInstance != NULL )
+			NifStream( link_map[StaticCast<NiObject>(skinInstance)], out, version );
+		else
+			NifStream( 0xffffffff, out, version );
+	};
 	if ( version >= 0x0A000100 ) {
 		NifStream( hasShader, out, version );
 		if ( (hasShader != 0) ) {
@@ -1670,7 +1677,9 @@ std::string NiGeometry::InternalAsString( bool verbose ) const {
 void NiGeometry::InternalFixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
 	NiAVObject::FixLinks( objects, link_stack, version, user_version );
 	data = FixLink<NiGeometryData>( objects, link_stack, version );
-	skinInstance = FixLink<NiSkinInstance>( objects, link_stack, version );
+	if ( version >= 0x0303000D ) {
+		skinInstance = FixLink<NiSkinInstance>( objects, link_stack, version );
+	};
 	if ( version >= 0x0A000100 ) {
 		if ( (hasShader != 0) ) {
 			unknownLink = FixLink<NiObject>( objects, link_stack, version );
@@ -5195,16 +5204,12 @@ void NiControllerSequence::InternalRead( istream& in, list<uint> & link_stack, u
 	for (uint i1 = 0; i1 < controlledBlocks.size(); i1++) {
 		if ( version <= 0x0A010000 ) {
 			NifStream( controlledBlocks[i1].targetName, in, version );
-		};
-		if ( version <= 0x0A01006A ) {
 			NifStream( block_num, in, version );
 			link_stack.push_back( block_num );
 		};
-		if ( version >= 0x0A020000 ) {
+		if ( version >= 0x0A01006A ) {
 			NifStream( block_num, in, version );
 			link_stack.push_back( block_num );
-		};
-		if ( version >= 0x0A01006A ) {
 			NifStream( block_num, in, version );
 			link_stack.push_back( block_num );
 		};
@@ -5303,20 +5308,16 @@ void NiControllerSequence::InternalWrite( ostream& out, map<NiObjectRef,uint> li
 	for (uint i1 = 0; i1 < controlledBlocks.size(); i1++) {
 		if ( version <= 0x0A010000 ) {
 			NifStream( controlledBlocks[i1].targetName, out, version );
-		};
-		if ( version <= 0x0A01006A ) {
 			if ( controlledBlocks[i1].controller != NULL )
 				NifStream( link_map[StaticCast<NiObject>(controlledBlocks[i1].controller)], out, version );
 			else
 				NifStream( 0xffffffff, out, version );
 		};
-		if ( version >= 0x0A020000 ) {
+		if ( version >= 0x0A01006A ) {
 			if ( controlledBlocks[i1].interpolator != NULL )
 				NifStream( link_map[StaticCast<NiObject>(controlledBlocks[i1].interpolator)], out, version );
 			else
 				NifStream( 0xffffffff, out, version );
-		};
-		if ( version >= 0x0A01006A ) {
 			if ( controlledBlocks[i1].controller != NULL )
 				NifStream( link_map[StaticCast<NiObject>(controlledBlocks[i1].controller)], out, version );
 			else
@@ -5463,13 +5464,11 @@ void NiControllerSequence::InternalFixLinks( const map<unsigned,NiObjectRef> & o
 		textKeys = FixLink<NiTextKeyExtraData>( objects, link_stack, version );
 	};
 	for (uint i1 = 0; i1 < controlledBlocks.size(); i1++) {
-		if ( version <= 0x0A01006A ) {
+		if ( version <= 0x0A010000 ) {
 			controlledBlocks[i1].controller = FixLink<NiTimeController>( objects, link_stack, version );
 		};
-		if ( version >= 0x0A020000 ) {
-			controlledBlocks[i1].interpolator = FixLink<NiInterpolator>( objects, link_stack, version );
-		};
 		if ( version >= 0x0A01006A ) {
+			controlledBlocks[i1].interpolator = FixLink<NiInterpolator>( objects, link_stack, version );
 			controlledBlocks[i1].controller = FixLink<NiTimeController>( objects, link_stack, version );
 		};
 		if ( ( version >= 0x0A01006A ) && ( version <= 0x0A01006A ) ) {
@@ -11619,6 +11618,137 @@ std::list<NiObjectRef> NiTextureTransformController::InternalGetRefs() const {
 	return refs;
 }
 
+void NiTextureModeProperty::InternalRead( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
+	NiProperty::Read( in, link_stack, version, user_version );
+	for (uint i1 = 0; i1 < 3; i1++) {
+		NifStream( unknown3Shorts[i1], in, version );
+	};
+}
+
+void NiTextureModeProperty::InternalWrite( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const {
+	NiProperty::Write( out, link_map, version, user_version );
+	for (uint i1 = 0; i1 < 3; i1++) {
+		NifStream( unknown3Shorts[i1], out, version );
+	};
+}
+
+std::string NiTextureModeProperty::InternalAsString( bool verbose ) const {
+	stringstream out;
+	uint array_output_count = 0;
+	out << NiProperty::asString();
+	array_output_count = 0;
+	for (uint i1 = 0; i1 < 3; i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			break;
+		};
+		out << "    Unknown 3 Shorts[" << i1 << "]:  " << unknown3Shorts[i1] << endl;
+		array_output_count++;
+	};
+	return out.str();
+}
+
+void NiTextureModeProperty::InternalFixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
+	NiProperty::FixLinks( objects, link_stack, version, user_version );
+}
+
+std::list<NiObjectRef> NiTextureModeProperty::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiProperty::GetRefs();
+	return refs;
+}
+
+void NiImage::InternalRead( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
+	NiObject::Read( in, link_stack, version, user_version );
+	NifStream( external_, in, version );
+	NifStream( file, in, version );
+	for (uint i1 = 0; i1 < 4; i1++) {
+		NifStream( unknown4Shorts[i1], in, version );
+	};
+}
+
+void NiImage::InternalWrite( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const {
+	NiObject::Write( out, link_map, version, user_version );
+	NifStream( external_, out, version );
+	NifStream( file, out, version );
+	for (uint i1 = 0; i1 < 4; i1++) {
+		NifStream( unknown4Shorts[i1], out, version );
+	};
+}
+
+std::string NiImage::InternalAsString( bool verbose ) const {
+	stringstream out;
+	uint array_output_count = 0;
+	out << NiObject::asString();
+	out << "  External ?:  " << external_ << endl;
+	out << "  File:  " << file << endl;
+	array_output_count = 0;
+	for (uint i1 = 0; i1 < 4; i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			break;
+		};
+		out << "    Unknown 4 Shorts[" << i1 << "]:  " << unknown4Shorts[i1] << endl;
+		array_output_count++;
+	};
+	return out.str();
+}
+
+void NiImage::InternalFixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
+	NiObject::FixLinks( objects, link_stack, version, user_version );
+}
+
+std::list<NiObjectRef> NiImage::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiObject::GetRefs();
+	return refs;
+}
+
+void NiTextureProperty::InternalRead( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
+	uint block_num;
+	NiProperty::Read( in, link_stack, version, user_version );
+	NifStream( flags, in, version );
+	NifStream( block_num, in, version );
+	link_stack.push_back( block_num );
+}
+
+void NiTextureProperty::InternalWrite( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const {
+	NiProperty::Write( out, link_map, version, user_version );
+	NifStream( flags, out, version );
+	if ( image != NULL )
+		NifStream( link_map[StaticCast<NiObject>(image)], out, version );
+	else
+		NifStream( 0xffffffff, out, version );
+}
+
+std::string NiTextureProperty::InternalAsString( bool verbose ) const {
+	stringstream out;
+	uint array_output_count = 0;
+	out << NiProperty::asString();
+	out << "  Flags:  " << flags << endl;
+	out << "  Image:  " << image << endl;
+	return out.str();
+}
+
+void NiTextureProperty::InternalFixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
+	NiProperty::FixLinks( objects, link_stack, version, user_version );
+	image = FixLink<NiImage>( objects, link_stack, version );
+}
+
+std::list<NiObjectRef> NiTextureProperty::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiProperty::GetRefs();
+	if ( image != NULL )
+		refs.push_back(StaticCast<NiObject>(image));
+	return refs;
+}
+
 void NiTexturingProperty::InternalRead( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
 	uint block_num;
 	NiProperty::Read( in, link_stack, version, user_version );
diff --git a/src/niflib.cpp b/src/niflib.cpp
index 80f4de7e..001f4a18 100644
--- a/src/niflib.cpp
+++ b/src/niflib.cpp
@@ -1059,22 +1059,22 @@ 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:
-   case VER_4_2_0_2:
-   case VER_4_2_1_0:
-   case VER_4_2_2_0:
-   case VER_10_0_1_0:
-   case VER_10_1_0_0:
-   case VER_10_1_0_106:
-   case VER_10_2_0_0:
-   case VER_20_0_0_4:
-   case VER_20_0_0_5:
-      return true;
+	switch (version) {
+		//case VER_3_1:
+		case VER_3_3_0_13:
+		case VER_4_0_0_0:
+		case VER_4_0_0_2:
+		case VER_4_1_0_12:
+		case VER_4_2_0_2:
+		case VER_4_2_1_0:
+		case VER_4_2_2_0:
+		case VER_10_0_1_0:
+		case VER_10_1_0_0:
+		case VER_10_1_0_106:
+		case VER_10_2_0_0:
+		case VER_20_0_0_4:
+		case VER_20_0_0_5:
+			return true;
    }
    return false;
 }
diff --git a/src/obj/NiImage.cpp b/src/obj/NiImage.cpp
new file mode 100644
index 00000000..20a04955
--- /dev/null
+++ b/src/obj/NiImage.cpp
@@ -0,0 +1,37 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for licence. */
+
+#include "../../include/obj/NiImage.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiImage::TYPE("NiImage", &NI_IMAGE_PARENT::TypeConst() );
+
+NiImage::NiImage() NI_IMAGE_CONSTRUCT {}
+
+NiImage::~NiImage() {}
+
+void NiImage::Read( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
+	InternalRead( in, link_stack, version, user_version );
+}
+
+void NiImage::Write( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const {
+	InternalWrite( out, link_map, version, user_version );
+}
+
+string NiImage::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiImage::FixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
+	InternalFixLinks( objects, link_stack, version, user_version );
+}
+
+list<NiObjectRef> NiImage::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiImage::GetType() const {
+	return TYPE;
+};
+
diff --git a/src/obj/NiTextureModeProperty.cpp b/src/obj/NiTextureModeProperty.cpp
new file mode 100644
index 00000000..c880d3cc
--- /dev/null
+++ b/src/obj/NiTextureModeProperty.cpp
@@ -0,0 +1,37 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for licence. */
+
+#include "../../include/obj/NiTextureModeProperty.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiTextureModeProperty::TYPE("NiTextureModeProperty", &NI_TEXTURE_MODE_PROPERTY_PARENT::TypeConst() );
+
+NiTextureModeProperty::NiTextureModeProperty() NI_TEXTURE_MODE_PROPERTY_CONSTRUCT {}
+
+NiTextureModeProperty::~NiTextureModeProperty() {}
+
+void NiTextureModeProperty::Read( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
+	InternalRead( in, link_stack, version, user_version );
+}
+
+void NiTextureModeProperty::Write( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const {
+	InternalWrite( out, link_map, version, user_version );
+}
+
+string NiTextureModeProperty::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiTextureModeProperty::FixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
+	InternalFixLinks( objects, link_stack, version, user_version );
+}
+
+list<NiObjectRef> NiTextureModeProperty::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiTextureModeProperty::GetType() const {
+	return TYPE;
+};
+
diff --git a/src/obj/NiTextureProperty.cpp b/src/obj/NiTextureProperty.cpp
new file mode 100644
index 00000000..9611baad
--- /dev/null
+++ b/src/obj/NiTextureProperty.cpp
@@ -0,0 +1,38 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for licence. */
+
+#include "../../include/obj/NiTextureProperty.h"
+#include "../../include/obj/NiImage.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiTextureProperty::TYPE("NiTextureProperty", &NI_TEXTURE_PROPERTY_PARENT::TypeConst() );
+
+NiTextureProperty::NiTextureProperty() NI_TEXTURE_PROPERTY_CONSTRUCT {}
+
+NiTextureProperty::~NiTextureProperty() {}
+
+void NiTextureProperty::Read( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
+	InternalRead( in, link_stack, version, user_version );
+}
+
+void NiTextureProperty::Write( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const {
+	InternalWrite( out, link_map, version, user_version );
+}
+
+string NiTextureProperty::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiTextureProperty::FixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
+	InternalFixLinks( objects, link_stack, version, user_version );
+}
+
+list<NiObjectRef> NiTextureProperty::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiTextureProperty::GetType() const {
+	return TYPE;
+};
+
-- 
GitLab