From 9deb8fb78630032e6e88c6bf0fd505045965b510 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Lortie Date: Sun, 19 Jan 2020 12:48:45 -0500 Subject: [PATCH 1/8] Fixed child nodes not deleted if the importer failed to add them to the scene root node. --- code/MDL/HalfLife/HL1MDLLoader.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/code/MDL/HalfLife/HL1MDLLoader.cpp b/code/MDL/HalfLife/HL1MDLLoader.cpp index 90a1479a3..ea156316f 100644 --- a/code/MDL/HalfLife/HL1MDLLoader.cpp +++ b/code/MDL/HalfLife/HL1MDLLoader.cpp @@ -124,6 +124,17 @@ void HL1MDLLoader::release_resources() { delete[] anim_headers_; anim_headers_ = nullptr; } + + if (rootnode_children_.size()) { + // Here, it means that the nodes were not added to the + // scene root node. We still have to delete them. + for (auto it = rootnode_children_.begin(); it != rootnode_children_.end(); ++it) { + if (*it) + delete *it; + } + // Ensure this happens only once. + rootnode_children_.clear(); + } } // ------------------------------------------------------------------------------------------------ @@ -171,6 +182,10 @@ void HL1MDLLoader::load_file() { scene_->mRootNode->addChildren( static_cast(rootnode_children_.size()), rootnode_children_.data()); + + // Clear the list of nodes so they will not be destroyed + // when resources are released. + rootnode_children_.clear(); } release_resources(); From b7e51a38ef671aff02878c6dee74b88d4f477f70 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sun, 19 Jan 2020 20:16:13 +0100 Subject: [PATCH 2/8] Update HL1MDLLoader.cpp Minor findings. --- code/MDL/HalfLife/HL1MDLLoader.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/MDL/HalfLife/HL1MDLLoader.cpp b/code/MDL/HalfLife/HL1MDLLoader.cpp index ea156316f..edba58617 100644 --- a/code/MDL/HalfLife/HL1MDLLoader.cpp +++ b/code/MDL/HalfLife/HL1MDLLoader.cpp @@ -125,12 +125,14 @@ void HL1MDLLoader::release_resources() { anim_headers_ = nullptr; } - if (rootnode_children_.size()) { + // Root has some children ndoes. so let's proceed them + if (!rootnode_children_.empty()) { // Here, it means that the nodes were not added to the // scene root node. We still have to delete them. for (auto it = rootnode_children_.begin(); it != rootnode_children_.end(); ++it) { - if (*it) + if (*it) { delete *it; + } } // Ensure this happens only once. rootnode_children_.clear(); From e27b54f504923530f6d302a6725c5008a568f555 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 21 Jan 2020 19:39:29 +0100 Subject: [PATCH 3/8] Update HL1MDLLoader.cpp Fix review findings. --- code/MDL/HalfLife/HL1MDLLoader.cpp | 120 ++++++++++++++++++----------- 1 file changed, 76 insertions(+), 44 deletions(-) diff --git a/code/MDL/HalfLife/HL1MDLLoader.cpp b/code/MDL/HalfLife/HL1MDLLoader.cpp index edba58617..79c7abfc2 100644 --- a/code/MDL/HalfLife/HL1MDLLoader.cpp +++ b/code/MDL/HalfLife/HL1MDLLoader.cpp @@ -125,7 +125,7 @@ void HL1MDLLoader::release_resources() { anim_headers_ = nullptr; } - // Root has some children ndoes. so let's proceed them + // Root has some children nodes. so let's proceed them if (!rootnode_children_.empty()) { // Here, it means that the nodes were not added to the // scene root node. We still have to delete them. @@ -141,7 +141,6 @@ void HL1MDLLoader::release_resources() { // ------------------------------------------------------------------------------------------------ void HL1MDLLoader::load_file() { - try { header_ = (const Header_HL1 *)buffer_; validate_header(header_, false); @@ -151,8 +150,9 @@ void HL1MDLLoader::load_file() { load_texture_file(); - if (import_settings_.read_animations) + if (import_settings_.read_animations) { load_sequence_groups_files(); + } read_textures(); read_skins(); @@ -168,14 +168,17 @@ void HL1MDLLoader::load_file() { read_sequence_transitions(); } - if (import_settings_.read_attachments) + if (import_settings_.read_attachments) { read_attachments(); + } - if (import_settings_.read_hitboxes) + if (import_settings_.read_hitboxes) { read_hitboxes(); + } - if (import_settings_.read_bone_controllers) + if (import_settings_.read_bone_controllers) { read_bone_controllers(); + } read_global_info(); @@ -202,46 +205,58 @@ void HL1MDLLoader::load_file() { void HL1MDLLoader::validate_header(const Header_HL1 *header, bool is_texture_header) { if (is_texture_header) { // Every single Half-Life model is assumed to have at least one texture. - if (!header->numtextures) + if (!header->numtextures) { throw DeadlyImportError(MDL_HALFLIFE_LOG_HEADER "There are no textures in the file"); + } - if (header->numtextures > AI_MDL_HL1_MAX_TEXTURES) + if (header->numtextures > AI_MDL_HL1_MAX_TEXTURES) { log_warning_limit_exceeded(header->numtextures, "textures"); + } - if (header->numskinfamilies > AI_MDL_HL1_MAX_SKIN_FAMILIES) + if (header->numskinfamilies > AI_MDL_HL1_MAX_SKIN_FAMILIES) { log_warning_limit_exceeded(header->numskinfamilies, "skin families"); + } } else { // Every single Half-Life model is assumed to have at least one bodypart. - if (!header->numbodyparts) + if (!header->numbodyparts) { throw DeadlyImportError(MDL_HALFLIFE_LOG_HEADER "Model has no bodyparts"); + } // Every single Half-Life model is assumed to have at least one bone. - if (!header->numbones) + if (!header->numbones) { throw DeadlyImportError(MDL_HALFLIFE_LOG_HEADER "Model has no bones"); + } // Every single Half-Life model is assumed to have at least one sequence group, // which is the "default" sequence group. - if (!header->numseqgroups) + if (!header->numseqgroups) { throw DeadlyImportError(MDL_HALFLIFE_LOG_HEADER "Model has no sequence groups"); + } - if (header->numbodyparts > AI_MDL_HL1_MAX_BODYPARTS) + if (header->numbodyparts > AI_MDL_HL1_MAX_BODYPARTS) { log_warning_limit_exceeded(header->numbodyparts, "bodyparts"); + } - if (header->numbones > AI_MDL_HL1_MAX_BONES) + if (header->numbones > AI_MDL_HL1_MAX_BONES) { log_warning_limit_exceeded(header->numbones, "bones"); + } - if (header->numbonecontrollers > AI_MDL_HL1_MAX_BONE_CONTROLLERS) + if (header->numbonecontrollers > AI_MDL_HL1_MAX_BONE_CONTROLLERS) { log_warning_limit_exceeded(header->numbonecontrollers, "bone controllers"); + } - if (header->numseq > AI_MDL_HL1_MAX_SEQUENCES) + if (header->numseq > AI_MDL_HL1_MAX_SEQUENCES) { log_warning_limit_exceeded(header->numseq, "sequences"); + } - if (header->numseqgroups > AI_MDL_HL1_MAX_SEQUENCE_GROUPS) + if (header->numseqgroups > AI_MDL_HL1_MAX_SEQUENCE_GROUPS) { log_warning_limit_exceeded(header->numseqgroups, "sequence groups"); + } - if (header->numattachments > AI_MDL_HL1_MAX_ATTACHMENTS) + if (header->numattachments > AI_MDL_HL1_MAX_ATTACHMENTS) { log_warning_limit_exceeded(header->numattachments, "attachments"); + } } } @@ -273,8 +288,7 @@ void HL1MDLLoader::load_texture_file() { load_file_into_buffer(texture_file_path, texture_buffer_); } else { - /* Model has no external texture file. This means the texture - is stored inside the main MDL file. */ + // Model has no external texture file. This means the texture is stored inside the main MDL file. texture_buffer_ = const_cast(buffer_); } @@ -301,16 +315,17 @@ void HL1MDLLoader::load_texture_file() { */ void HL1MDLLoader::load_sequence_groups_files() { - if (header_->numseqgroups <= 1) + if (header_->numseqgroups <= 1) { return; + } num_sequence_groups_ = header_->numseqgroups; anim_buffers_ = new unsigned char *[num_sequence_groups_]; anim_headers_ = new SequenceHeader_HL1 *[num_sequence_groups_]; for (int i = 0; i < num_sequence_groups_; ++i) { - anim_buffers_[i] = NULL; - anim_headers_[i] = NULL; + anim_buffers_[i] = nullptr; + anim_headers_[i] = nullptr; } std::string file_path_without_extension = @@ -344,21 +359,24 @@ void HL1MDLLoader::read_texture(const Texture_HL1 *ptexture, aiColor3D &last_palette_color) { int outwidth, outheight; int i, j; - int row1[256], row2[256], col1[256], col2[256]; + static size_t BuffenLen = 256; + int row1[BuffenLen], row2[BuffenLen], col1[BuffenLen], col2[BuffenLen]; unsigned char *pix1, *pix2, *pix3, *pix4; // convert texture to power of 2 for (outwidth = 1; outwidth < ptexture->width; outwidth <<= 1) ; - if (outwidth > 256) - outwidth = 256; + if (outwidth > BuffenLen) { + outwidth = BuffenLen; + } for (outheight = 1; outheight < ptexture->height; outheight <<= 1) ; - if (outheight > 256) - outheight = 256; + if (outheight > BuffenLen) { + outheight = BuffenLen; + } pResult->mFilename = ptexture->name; pResult->mWidth = outwidth; @@ -457,8 +475,9 @@ void HL1MDLLoader::read_textures() { // ------------------------------------------------------------------------------------------------ void HL1MDLLoader::read_skins() { // Read skins, if any. - if (texture_header_->numskinfamilies <= 1) + if (texture_header_->numskinfamilies <= 1) { return; + } // Pointer to base texture index. short *default_skin_ptr = (short *)((uint8_t *)texture_header_ + texture_header_->skinindex); @@ -482,8 +501,9 @@ void HL1MDLLoader::read_bones() { const Bone_HL1 *pbone = (const Bone_HL1 *)((uint8_t *)header_ + header_->boneindex); std::vector unique_bones_names(header_->numbones); - for (int i = 0; i < header_->numbones; ++i) + for (int i = 0; i < header_->numbones; ++i) { unique_bones_names[i] = pbone[i].name; + } // Ensure bones have unique names. unique_name_generator_.set_template_name("Bone"); @@ -600,14 +620,17 @@ void HL1MDLLoader::read_meshes() { } // Display limit infos. - if (total_verts > AI_MDL_HL1_MAX_VERTICES) + if (total_verts > AI_MDL_HL1_MAX_VERTICES) { log_warning_limit_exceeded(total_verts, "vertices"); + } - if (scene_->mNumMeshes > AI_MDL_HL1_MAX_MESHES) + if (scene_->mNumMeshes > AI_MDL_HL1_MAX_MESHES) { log_warning_limit_exceeded(scene_->mNumMeshes, "meshes"); + } - if (total_models_ > AI_MDL_HL1_MAX_MODELS) + if (total_models_ > AI_MDL_HL1_MAX_MODELS) { log_warning_limit_exceeded(total_models_, "models"); + } // Ensure bodyparts have unique names. unique_name_generator_.set_template_name("Bodypart"); @@ -934,8 +957,9 @@ void HL1MDLLoader::read_meshes() { } } - if (total_triangles > AI_MDL_HL1_MAX_TRIANGLES) + if (total_triangles > AI_MDL_HL1_MAX_TRIANGLES) { log_warning_limit_exceeded(total_triangles, "triangles"); + } } // ------------------------------------------------------------------------------------------------ @@ -976,10 +1000,11 @@ void HL1MDLLoader::read_animations() { for (int sequence = 0; sequence < header_->numseq; ++sequence, ++pseqdesc) { pseqgroup = (const SequenceGroup_HL1 *)((uint8_t *)header_ + header_->seqgroupindex) + pseqdesc->seqgroup; - if (pseqdesc->seqgroup == 0) + if (pseqdesc->seqgroup == 0) { panim = (const AnimValueOffset_HL1 *)((uint8_t *)header_ + pseqgroup->unused2 + pseqdesc->animindex); - else + } else { panim = (const AnimValueOffset_HL1 *)((uint8_t *)anim_headers_[pseqdesc->seqgroup] + pseqdesc->animindex); + } for (int blend = 0; blend < pseqdesc->numblends; ++blend, ++scene_animations_ptr) { @@ -1052,8 +1077,9 @@ void HL1MDLLoader::read_sequence_groups_info() { const SequenceGroup_HL1 *pseqgroup = (const SequenceGroup_HL1 *)((uint8_t *)header_ + header_->seqgroupindex); unique_sequence_groups_names_.resize(header_->numseqgroups); - for (int i = 0; i < header_->numseqgroups; ++i) + for (int i = 0; i < header_->numseqgroups; ++i) { unique_sequence_groups_names_[i] = pseqgroup[i].label; + } // Ensure sequence groups have unique names. unique_name_generator_.set_template_name("SequenceGroup"); @@ -1076,8 +1102,9 @@ void HL1MDLLoader::read_sequence_groups_info() { // ------------------------------------------------------------------------------------------------ void HL1MDLLoader::read_sequence_infos() { - if (!header_->numseq) + if (!header_->numseq) { return; + } const SequenceDesc_HL1 *pseqdesc = (const SequenceDesc_HL1 *)((uint8_t *)header_ + header_->seqindex); @@ -1180,8 +1207,9 @@ void HL1MDLLoader::read_sequence_infos() { // ------------------------------------------------------------------------------------------------ void HL1MDLLoader::read_sequence_transitions() { - if (!header_->numtransitions) + if (!header_->numtransitions) { return; + } // Read sequence transition graph. aiNode *transition_graph_node = new aiNode(AI_MDL_HL1_NODE_SEQUENCE_TRANSITION_GRAPH); @@ -1194,8 +1222,9 @@ void HL1MDLLoader::read_sequence_transitions() { } void HL1MDLLoader::read_attachments() { - if (!header_->numattachments) + if (!header_->numattachments) { return; + } const Attachment_HL1 *pattach = (const Attachment_HL1 *)((uint8_t *)header_ + header_->attachmentindex); @@ -1217,8 +1246,9 @@ void HL1MDLLoader::read_attachments() { // ------------------------------------------------------------------------------------------------ void HL1MDLLoader::read_hitboxes() { - if (!header_->numhitboxes) + if (!header_->numhitboxes) { return; + } const Hitbox_HL1 *phitbox = (const Hitbox_HL1 *)((uint8_t *)header_ + header_->hitboxindex); @@ -1243,8 +1273,9 @@ void HL1MDLLoader::read_hitboxes() { // ------------------------------------------------------------------------------------------------ void HL1MDLLoader::read_bone_controllers() { - if (!header_->numbonecontrollers) + if (!header_->numbonecontrollers) { return; + } const BoneController_HL1 *pbonecontroller = (const BoneController_HL1 *)((uint8_t *)header_ + header_->bonecontrollerindex); @@ -1323,10 +1354,11 @@ void HL1MDLLoader::extract_anim_value( } // Bah, missing blend! - if (panimvalue->num.valid > k) + if (panimvalue->num.valid > k) { value = panimvalue[k + 1].value * bone_scale; - else + } else { value = panimvalue[panimvalue->num.valid].value * bone_scale; + } } // ------------------------------------------------------------------------------------------------ From 6a5ab0381d0454422f98aa653d8c06b38f592a78 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 22 Jan 2020 09:46:37 +0100 Subject: [PATCH 4/8] Update HL1MDLLoader.cpp Add missing const --- code/MDL/HalfLife/HL1MDLLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/MDL/HalfLife/HL1MDLLoader.cpp b/code/MDL/HalfLife/HL1MDLLoader.cpp index 79c7abfc2..52a5a87e7 100644 --- a/code/MDL/HalfLife/HL1MDLLoader.cpp +++ b/code/MDL/HalfLife/HL1MDLLoader.cpp @@ -359,7 +359,7 @@ void HL1MDLLoader::read_texture(const Texture_HL1 *ptexture, aiColor3D &last_palette_color) { int outwidth, outheight; int i, j; - static size_t BuffenLen = 256; + static const size_t BuffenLen = 256; int row1[BuffenLen], row2[BuffenLen], col1[BuffenLen], col2[BuffenLen]; unsigned char *pix1, *pix2, *pix3, *pix4; From 3cf7d955f32f014ccaa72d6c0be8ced47e7d07b2 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 22 Jan 2020 10:06:40 +0100 Subject: [PATCH 5/8] Update HL1MDLLoader.cpp Fix compiler warning --- code/MDL/HalfLife/HL1MDLLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/MDL/HalfLife/HL1MDLLoader.cpp b/code/MDL/HalfLife/HL1MDLLoader.cpp index 52a5a87e7..f662c7eec 100644 --- a/code/MDL/HalfLife/HL1MDLLoader.cpp +++ b/code/MDL/HalfLife/HL1MDLLoader.cpp @@ -374,7 +374,7 @@ void HL1MDLLoader::read_texture(const Texture_HL1 *ptexture, for (outheight = 1; outheight < ptexture->height; outheight <<= 1) ; - if (outheight > BuffenLen) { + if (static_cast(outheight) > BuffenLen) { outheight = BuffenLen; } From 5b09758f15716ec81f271465c8d7c488170b3257 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 23 Jan 2020 15:04:07 +0100 Subject: [PATCH 6/8] Update HL1MDLLoader.cpp Fix compiler warning --- code/MDL/HalfLife/HL1MDLLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/MDL/HalfLife/HL1MDLLoader.cpp b/code/MDL/HalfLife/HL1MDLLoader.cpp index f662c7eec..ad4db204f 100644 --- a/code/MDL/HalfLife/HL1MDLLoader.cpp +++ b/code/MDL/HalfLife/HL1MDLLoader.cpp @@ -367,7 +367,7 @@ void HL1MDLLoader::read_texture(const Texture_HL1 *ptexture, for (outwidth = 1; outwidth < ptexture->width; outwidth <<= 1) ; - if (outwidth > BuffenLen) { + if ((size_t)outwidth > BuffenLen) { outwidth = BuffenLen; } From e5698312536cfc3bd3437e465796ab1439c8b8e4 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 23 Jan 2020 16:20:34 +0100 Subject: [PATCH 7/8] Update HL1MDLLoader.cpp Fix possible x64 issue. --- code/MDL/HalfLife/HL1MDLLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/MDL/HalfLife/HL1MDLLoader.cpp b/code/MDL/HalfLife/HL1MDLLoader.cpp index 0e44ff3ac..06ffd7801 100644 --- a/code/MDL/HalfLife/HL1MDLLoader.cpp +++ b/code/MDL/HalfLife/HL1MDLLoader.cpp @@ -367,7 +367,7 @@ void HL1MDLLoader::read_texture(const Texture_HL1 *ptexture, for (outwidth = 1; outwidth < ptexture->width; outwidth <<= 1) ; - if ((size_t)outwidth > BuffenLen) { + if ( outwidth > static_cast(BuffenLen)) { outwidth = BuffenLen; } From 770c82262183c169255f2f1c5a3989fbf02c15b3 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Lortie Date: Thu, 23 Jan 2020 15:26:49 -0500 Subject: [PATCH 8/8] Updated places to achFormatHint referencing array size. --- code/Assbin/AssbinExporter.cpp | 3 ++- code/Assbin/AssbinLoader.cpp | 2 +- code/PostProcessing/ValidateDataStructure.cpp | 2 +- include/assimp/texture.h | 3 +-- tools/assimp_cmd/CompareDump.cpp | 4 ++++ tools/assimp_cmd/WriteDumb.cpp | 3 ++- 6 files changed, 11 insertions(+), 6 deletions(-) diff --git a/code/Assbin/AssbinExporter.cpp b/code/Assbin/AssbinExporter.cpp index aa0c246be..86a42c400 100644 --- a/code/Assbin/AssbinExporter.cpp +++ b/code/Assbin/AssbinExporter.cpp @@ -413,7 +413,8 @@ protected: Write(&chunk,tex->mWidth); Write(&chunk,tex->mHeight); - chunk.Write( tex->achFormatHint, sizeof(char), 4 ); + // Write the texture format, but don't include the null terminator. + chunk.Write( tex->achFormatHint, sizeof(char), HINTMAXTEXTURELEN - 1 ); if(!shortened) { if (!tex->mHeight) { diff --git a/code/Assbin/AssbinLoader.cpp b/code/Assbin/AssbinLoader.cpp index 8a9751018..71e35cb6a 100644 --- a/code/Assbin/AssbinLoader.cpp +++ b/code/Assbin/AssbinLoader.cpp @@ -535,7 +535,7 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) { tex->mWidth = Read(stream); tex->mHeight = Read(stream); - stream->Read( tex->achFormatHint, sizeof(char), 4 ); + stream->Read( tex->achFormatHint, sizeof(char), HINTMAXTEXTURELEN - 1 ); if(!shortened) { if (!tex->mHeight) { diff --git a/code/PostProcessing/ValidateDataStructure.cpp b/code/PostProcessing/ValidateDataStructure.cpp index 36c33b29c..a812efb0b 100644 --- a/code/PostProcessing/ValidateDataStructure.cpp +++ b/code/PostProcessing/ValidateDataStructure.cpp @@ -798,7 +798,7 @@ void ValidateDSProcess::Validate( const aiTexture* pTexture) if (!pTexture->mWidth) { ReportError("aiTexture::mWidth is zero (compressed texture)"); } - if ('\0' != pTexture->achFormatHint[3]) { + if ('\0' != pTexture->achFormatHint[HINTMAXTEXTURELEN - 1]) { ReportWarning("aiTexture::achFormatHint must be zero-terminated"); } else if ('.' == pTexture->achFormatHint[0]) { diff --git a/include/assimp/texture.h b/include/assimp/texture.h index 274185a30..5a4486431 100644 --- a/include/assimp/texture.h +++ b/include/assimp/texture.h @@ -207,8 +207,7 @@ struct aiTexture { , mHeight(0) , pcData(nullptr) , mFilename() { - achFormatHint[0] = achFormatHint[1] = 0; - achFormatHint[2] = achFormatHint[3] = 0; + memset(achFormatHint, 0, sizeof(achFormatHint)); } // Destruction diff --git a/tools/assimp_cmd/CompareDump.cpp b/tools/assimp_cmd/CompareDump.cpp index 3250c528a..86a9cfe4c 100644 --- a/tools/assimp_cmd/CompareDump.cpp +++ b/tools/assimp_cmd/CompareDump.cpp @@ -800,6 +800,10 @@ void CompareOnTheFlyTexture(comparer_context& comp) { comp.cmp("achFormatHint[1]"); comp.cmp("achFormatHint[2]"); comp.cmp("achFormatHint[3]"); + comp.cmp("achFormatHint[4]"); + comp.cmp("achFormatHint[5]"); + comp.cmp("achFormatHint[6]"); + comp.cmp("achFormatHint[7]"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tools/assimp_cmd/WriteDumb.cpp b/tools/assimp_cmd/WriteDumb.cpp index 5b5dfd2a1..b4c22a439 100644 --- a/tools/assimp_cmd/WriteDumb.cpp +++ b/tools/assimp_cmd/WriteDumb.cpp @@ -312,7 +312,8 @@ uint32_t WriteBinaryTexture(const aiTexture* tex) len += Write(tex->mWidth); len += Write(tex->mHeight); - len += static_cast(fwrite(tex->achFormatHint,1,4,out)); + // Write the texture format, but don't include the null terminator. + len += static_cast(fwrite(tex->achFormatHint,sizeof(char),HINTMAXTEXTURELEN - 1,out)); if(!shortened) { if (!tex->mHeight) {