Skip to content

Commit d2cb09d

Browse files
authored
Fix memory corruptions in w3dview (#1129)
1 parent 9a10575 commit d2cb09d

File tree

9 files changed

+72
-54
lines changed

9 files changed

+72
-54
lines changed

src/game/client/w3dassetmanager.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ TextureClass *GameAssetManager::Recolor_Texture_One_Time(TextureClass *texture,
401401
char buffer[512];
402402
Create_Color_Texture_Name(buffer, name, color);
403403
new_texture->Set_Texture_Name(buffer);
404+
captainslog_dbgassert(!m_textureHash.Exists(new_texture), "Texture hash collision occurred"); // Thyme specific
404405
m_textureHash.Insert(new_texture->Get_Name(), new_texture);
405406
new_texture->Add_Ref();
406407
Ref_Ptr_Release(surface);

src/tools/w3dviewer/assetinfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
AssetInfoClass::AssetInfoClass(const char *name, AssetType type, RenderObjClass *robj, TextureClass *texture) :
1919
m_name(name), m_type(type), m_texture(texture), m_renderObj(nullptr)
2020
{
21+
// Note: The reference for m_texture is added and removed externally (bad).
2122
Ref_Ptr_Set(m_renderObj, robj);
2223
GetHierarchyName();
2324
}

src/tools/w3dviewer/datatreeview.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ void CDataTreeView::AddTextures()
458458
m_categoryTreeItems[CATEGORY_MATERIAL],
459459
TVI_SORT);
460460

461+
texture->Add_Ref();
461462
AssetInfoClass *info = new AssetInfoClass(texture->Get_Name(), ASSET_TYPE_TEXTURE, nullptr, texture);
462463
GetTreeCtrl().SetItem(newitem, TVIF_PARAM, nullptr, 0, 0, 0, 0, (LPARAM)info);
463464
}

src/tools/w3dviewer/w3dviewdoc.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,9 @@ void CW3DViewDoc::SetRenderObject(RenderObjClass *robj, bool useRegularCameraRes
467467
}
468468

469469
robj->Set_Animation();
470+
captainslog_dbgassert(m_model == nullptr, "Expected nullptr, otherwise leaks"); // Thyme specific
470471
m_model = robj;
472+
m_model->Add_Ref();
471473
Matrix3D tm(true);
472474
m_model->Set_Transform(tm);
473475
SceneClass *scene;

src/w3d/lib/multilist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "always.h"
1919
#include "autopool.h"
20+
#include "refcount.h"
2021
#include <captainslog.h>
2122

2223
// #TODO investigate C casts in this file.

src/w3d/renderer/assetmgr.cpp

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -357,44 +357,43 @@ TextureClass *W3DAssetManager::Get_Texture(const char *filename,
357357
mip_level_count = MipCountType::MIP_LEVELS_1;
358358
}
359359

360-
if (filename == nullptr || strlen(filename) == 0) {
361-
return nullptr;
362-
}
363-
364-
StringClass name = { filename };
365-
name.To_Lower();
366-
TextureClass *texture = m_textureHash.Get(name);
367-
368-
if (texture != nullptr) {
369-
texture->Add_Ref();
370-
return texture;
371-
}
360+
if (filename != nullptr && strlen(filename) != 0) {
361+
StringClass name = { filename };
362+
name.To_Lower();
363+
364+
TextureClass *new_texture = m_textureHash.Get(name);
365+
366+
if (new_texture == nullptr) {
367+
368+
switch (asset_type) {
369+
case TexAssetType::ASSET_STANDARD:
370+
new_texture = new TextureClass{
371+
name, nullptr, mip_level_count, texture_format, allow_compression, allow_reduction
372+
};
373+
break;
374+
case TexAssetType::ASSET_CUBE:
375+
captainslog_dbgassert(false, "CubeTextureClass is not used");
376+
break;
377+
case TexAssetType::ASSET_VOLUME:
378+
captainslog_dbgassert(false, "VolumeTextureClass is not used");
379+
break;
380+
default:
381+
break;
382+
}
372383

373-
TextureClass *new_texture = nullptr;
384+
if (new_texture == nullptr) {
385+
return nullptr;
386+
}
374387

375-
switch (asset_type) {
376-
case TexAssetType::ASSET_STANDARD:
377-
new_texture =
378-
new TextureClass{ name, nullptr, mip_level_count, texture_format, allow_compression, allow_reduction };
379-
break;
380-
case TexAssetType::ASSET_CUBE:
381-
captainslog_dbgassert(false, "CubeTextureClass is not used");
382-
break;
383-
case TexAssetType::ASSET_VOLUME:
384-
captainslog_dbgassert(false, "VolumeTextureClass is not used");
385-
break;
386-
default:
387-
break;
388-
}
388+
captainslog_dbgassert(!m_textureHash.Exists(new_texture), "Texture hash collision occurred"); // Thyme specific
389+
m_textureHash.Insert(new_texture->Get_Name(), new_texture);
390+
}
389391

390-
if (new_texture == nullptr) {
391-
return nullptr;
392+
new_texture->Add_Ref();
393+
return new_texture;
392394
}
393395

394-
m_textureHash.Insert(new_texture->Get_Name(), new_texture);
395-
396-
new_texture->Add_Ref();
397-
return new_texture;
396+
return nullptr;
398397
}
399398

400399
// 0x00815C90

src/w3d/renderer/dx8renderer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ DX8TextureCategoryClass::DX8TextureCategoryClass(
472472
captainslog_assert(pass < DX8FVFCategoryContainer::MAX_PASSES);
473473

474474
for (int i = 0; i < 2; i++) {
475+
m_textures[i] = nullptr;
475476
Ref_Ptr_Set(m_textures[i], texs[i]);
476477
}
477478

src/w3d/renderer/mesh.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,11 @@ class PrimitivePrototypeClass : public W3DMPO, public PrototypeClass
141141
proto->Add_Ref();
142142
}
143143

144-
virtual ~PrimitivePrototypeClass() override { m_proto->Release_Ref(); }
144+
virtual ~PrimitivePrototypeClass() override
145+
{
146+
if (m_proto != nullptr)
147+
m_proto->Release_Ref();
148+
}
145149
virtual const char *Get_Name() const override { return m_proto->Get_Name(); }
146150
virtual int Get_Class_ID() const override { return m_proto->Class_ID(); }
147151
virtual RenderObjClass *Create() override { return m_proto->Clone(); }

src/w3d/renderer/meshmdl.cpp

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -603,14 +603,14 @@ TextureClass *Load_Texture(ChunkLoadClass &cload)
603603

604604
while (cload.Open_Chunk()) {
605605
int id = cload.Cur_Chunk_ID();
606-
if (id == W3D_CHUNK_TEXTURE_NAME) {
607-
cload.Read(name, cload.Cur_Chunk_Length());
608-
} else if (id == W3D_CHUNK_TEXTURE_INFO) {
609-
if (id == 1) {
610-
cload.Read(&info, 12);
611-
}
612-
613-
texinfo = true;
606+
switch (id) {
607+
case W3D_CHUNK_TEXTURE_NAME:
608+
cload.Read(name, cload.Cur_Chunk_Length());
609+
break;
610+
case W3D_CHUNK_TEXTURE_INFO:
611+
cload.Read(&info, sizeof(info));
612+
texinfo = true;
613+
break;
614614
}
615615

616616
cload.Close_Chunk();
@@ -638,6 +638,7 @@ TextureClass *Load_Texture(ChunkLoadClass &cload)
638638
case W3DTEXTURE_MIP_LEVELS_4:
639639
mips = MipCountType::MIP_LEVELS_4;
640640
break;
641+
case W3DTEXTURE_MIP_LEVELS_ALL:
641642
default:
642643
mips = MipCountType::MIP_LEVELS_ALL;
643644
break;
@@ -646,20 +647,27 @@ TextureClass *Load_Texture(ChunkLoadClass &cload)
646647

647648
WW3DFormat format = WW3D_FORMAT_UNKNOWN;
648649

649-
if ((info.Attributes & W3DTEXTURE_TYPE_MASK) == W3DTEXTURE_TYPE_BUMPMAP) {
650-
if (DX8Wrapper::Is_Initted()) {
651-
if (DX8Wrapper::Get_Current_Caps()->Support_Bump_Envmap()) {
652-
mips = MipCountType::MIP_LEVELS_1;
653-
654-
if (DX8Wrapper::Get_Current_Caps()->Supports_Texture_Format(WW3D_FORMAT_U8V8)) {
655-
format = WW3D_FORMAT_U8V8;
656-
} else if (DX8Wrapper::Get_Current_Caps()->Supports_Texture_Format(WW3D_FORMAT_X8L8V8U8)) {
657-
format = WW3D_FORMAT_X8L8V8U8;
658-
} else if (DX8Wrapper::Get_Current_Caps()->Supports_Texture_Format(WW3D_FORMAT_L6V5U5)) {
659-
format = WW3D_FORMAT_L6V5U5;
650+
switch (info.Attributes & W3DTEXTURE_TYPE_MASK) {
651+
case W3DTEXTURE_TYPE_COLORMAP:
652+
break;
653+
case W3DTEXTURE_TYPE_BUMPMAP:
654+
if (DX8Wrapper::Is_Initted()) {
655+
if (DX8Wrapper::Get_Current_Caps()->Support_Bump_Envmap()) {
656+
mips = MipCountType::MIP_LEVELS_1;
657+
658+
if (DX8Wrapper::Get_Current_Caps()->Supports_Texture_Format(WW3D_FORMAT_U8V8)) {
659+
format = WW3D_FORMAT_U8V8;
660+
} else if (DX8Wrapper::Get_Current_Caps()->Supports_Texture_Format(WW3D_FORMAT_X8L8V8U8)) {
661+
format = WW3D_FORMAT_X8L8V8U8;
662+
} else if (DX8Wrapper::Get_Current_Caps()->Supports_Texture_Format(WW3D_FORMAT_L6V5U5)) {
663+
format = WW3D_FORMAT_L6V5U5;
664+
}
660665
}
661666
}
662-
}
667+
break;
668+
default:
669+
captainslog_assert(false);
670+
break;
663671
}
664672

665673
TextureClass *tex = W3DAssetManager::Get_Instance()->Get_Texture(name, mips, format);

0 commit comments

Comments
 (0)