diff LOD.cpp @ 0:8b8875f5b359

Initial commit
author Nomad
date Fri, 05 Oct 2012 16:07:14 +0200
parents
children ac0fb48cd27a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LOD.cpp	Fri Oct 05 16:07:14 2012 +0200
@@ -0,0 +1,3169 @@
+#include "LOD.h"
+#include "Render.h"
+#include "Allocator.h"
+#include "PaletteManager.h"
+#include "Viewport.h"
+
+#include "mm7_data.h"
+
+
+
+
+
+
+
+LODFile_IconsBitmaps *pEvents_LOD;
+LODFile_IconsBitmaps *pIcons_LOD;
+LODFile_Sprites *pSprites_LOD;
+LODFile_IconsBitmaps *pBitmaps_LOD;
+
+LODWriteableFile *pNew_LOD;
+LODWriteableFile *pGames_LOD;
+
+
+
+
+int _6A0CA4_lod_binary_search; // weak
+int _6A0CA8_lod_unused; // weak
+
+
+
+
+
+//----- (004355F7) --------------------------------------------------------
+void LODFile_IconsBitmaps::_4355F7()
+{
+  LODFile_IconsBitmaps *v1; // esi@1
+  int v2; // edi@2
+  Texture *v3; // ebp@3
+  struct IDirect3DTexture2 **v4; // eax@4
+  struct IDirect3DTexture2 *v5; // eax@5
+  struct IDirectDrawSurface **v6; // eax@7
+  struct IDirectDrawSurface *v7; // eax@8
+  int v8; // eax@11
+
+  v1 = this;
+  if ( this->uTexturePacksCount )
+  {
+    v2 = this->uNumLoadedFiles - 1;
+    if ( v2 >= this->uNumPrevLoadedFiles )
+    {
+      v3 = &this->pTextures[v2];
+      do
+      {
+        v3->Release();
+        v4 = v1->pHardwareTextures;
+        if ( v4 )
+        {
+          v5 = v4[v2];
+          if ( v5 )
+          {
+            v5->Release();
+            v1->pHardwareTextures[v2] = 0;
+          }
+        }
+        v6 = v1->pHardwareSurfaces;
+        if ( v6 )
+        {
+          v7 = v6[v2];
+          if ( v7 )
+          {
+            v7->Release();
+            v1->pHardwareSurfaces[v2] = 0;
+          }
+        }
+        --v2;
+        --v3;
+      }
+      while ( v2 >= v1->uNumPrevLoadedFiles );
+    }
+    v8 = v1->uNumPrevLoadedFiles;
+    v1->uNumPrevLoadedFiles = 0;
+    v1->uNumLoadedFiles = v8;
+    v1->uTexturePacksCount = 0;
+  }
+}
+
+//----- (004114F2) --------------------------------------------------------
+void LODFile_IconsBitmaps::_4114F2()
+{
+  LODFile_IconsBitmaps *v1; // esi@1
+  int *pTexturePacksCount; // eax@1
+  int v3; // ecx@1
+  int v4; // ecx@2
+  int v5; // edi@3
+  Texture *v6; // ebx@4
+  struct IDirect3DTexture2 **v7; // eax@5
+  struct IDirect3DTexture2 *v8; // eax@6
+  struct IDirectDrawSurface **v9; // eax@8
+  struct IDirectDrawSurface *v10; // eax@9
+  int v11; // eax@12
+
+  v1 = this;
+  pTexturePacksCount = &this->uTexturePacksCount;
+  v3 = this->uTexturePacksCount;
+  if ( v3 )
+  {
+    v4 = v3 - 1;
+    *pTexturePacksCount = v4;
+    if ( !v4 )
+    {
+      v5 = v1->uNumLoadedFiles - 1;
+      if ( v5 >= v1->uNumPrevLoadedFiles )
+      {
+        v6 = &v1->pTextures[v5];
+        do
+        {
+          v6->Release();
+          v7 = v1->pHardwareTextures;
+          if ( v7 )
+          {
+            v8 = v7[v5];
+            if ( v8 )
+            {
+              v8->Release();
+              v1->pHardwareTextures[v5] = 0;
+            }
+          }
+          v9 = v1->pHardwareSurfaces;
+          if ( v9 )
+          {
+            v10 = v9[v5];
+            if ( v10 )
+            {
+              v10->Release();
+              v1->pHardwareSurfaces[v5] = 0;
+            }
+          }
+          --v5;
+          --v6;
+        }
+        while ( v5 >= v1->uNumPrevLoadedFiles );
+      }
+      v11 = v1->uNumPrevLoadedFiles;
+      v1->uNumPrevLoadedFiles = 0;
+      v1->uNumLoadedFiles = v11;
+    }
+  }
+}
+
+//----- (004AC67E) --------------------------------------------------------
+int LODFile_Sprites::LoadSpriteFromFile(LODSprite *pSpriteHeader, const char *pContainer)
+{
+  FILE *v3; // eax@1
+  FILE *v4; // ebx@1
+  int result; // eax@2
+  LODSprite *v6; // esi@3
+  LODSprite_stru0 *v7; // eax@3
+  size_t v8; // ST10_4@3
+  int *v9; // ebx@3
+  int v10; // eax@3
+  void *v11; // eax@5
+  LODSprite_stru0 *v12; // eax@6
+  void *v13; // ecx@6
+  LODSprite_stru0 *i; // edx@6
+  FILE *File; // [sp+4h] [bp-4h]@1
+  void *DstBufa; // [sp+10h] [bp+8h]@4
+  int Sizea; // [sp+14h] [bp+Ch]@3
+
+  v3 = FindContainer(pContainer, 0);
+  v4 = v3;
+  File = v3;
+  if ( v3 )
+  {
+    v6 = pSpriteHeader;
+    fread(pSpriteHeader, 1u, 0x20u, v3);
+    strcpy(pSpriteHeader->pName, pContainer);
+    Sizea = pSpriteHeader->uSpriteSize;
+    v7 = (LODSprite_stru0 *)pAllocator->AllocNamedChunk(v6->pSpriteLines, 8 * v6->uHeight, v6->pName);
+    v8 = 8 * pSpriteHeader->uHeight;
+    pSpriteHeader->pSpriteLines = v7;
+    fread(v7, 1u, v8, v4);
+    v9 = &pSpriteHeader->uDecompressedSize;
+    v10 = pSpriteHeader->uDecompressedSize;
+    if ( v10 )
+    {
+      pSpriteHeader->pDecompressedBytes = pAllocator->AllocNamedChunk(
+                                            pSpriteHeader->pDecompressedBytes,
+                                            v10,
+                                            pSpriteHeader->pName);
+      DstBufa = pAllocator->AllocNamedChunk(0, Sizea, pSpriteHeader->pName);
+      fread(DstBufa, 1u, Sizea, File);
+      zlib::MemUnzip(v6->pDecompressedBytes, (unsigned int *)&v6->uDecompressedSize, DstBufa, v6->uSpriteSize);
+      v6->uSpriteSize = *v9;
+      pAllocator->FreeChunk(DstBufa);
+    }
+    else
+    {
+      v11 = pAllocator->AllocNamedChunk(pSpriteHeader->pDecompressedBytes, Sizea, pSpriteHeader->pName);
+      pSpriteHeader->pDecompressedBytes = v11;
+      fread(v11, 1u, Sizea, File);
+    }
+    v12 = v6->pSpriteLines;
+    v13 = v6->pDecompressedBytes;
+    for ( i = &v12[v6->uHeight]; v12 < i; i = &v6->pSpriteLines[v6->uHeight] )
+    {
+      v12->ptr_4 = (char *)v12->ptr_4 + (unsigned int)v13;
+      ++v12;
+    }
+    result = 1;
+  }
+  else
+  {
+    result = -1;
+  }
+  return result;
+}
+
+//----- (004AC795) --------------------------------------------------------
+bool LODFile_Sprites::LoadSprites(const char *pFilename)
+{
+  if (LoadHeader(pFilename, 1))
+    return false;
+  else
+    return LoadSubIndices("sprites08") == 0;
+}
+
+//----- (004AC7C0) --------------------------------------------------------
+int LODFile_Sprites::LoadSprite(const char *pContainerName, unsigned int uPaletteID)
+{  signed int v3; // edi@1
+  LODFile_Sprites *v4; // esi@1
+  unsigned int v5; // eax@6
+  signed int v6; // ecx@10
+  Sprite *v7; // eax@11
+  FILE *v8; // eax@12
+  Sprite *v10; // edx@21
+  int v11; // eax@21
+  int v12; // eax@22
+  unsigned __int8 v13; // zf@23
+  unsigned __int8 v14; // sf@23
+  LODSprite DstBuf; // [sp+Ch] [bp-3Ch]@12
+  char *Str1; // [sp+34h] [bp-14h]@24
+  LODSprite *v17; // [sp+38h] [bp-10h]@3
+  int v18; // [sp+44h] [bp-4h]@12
+
+  auto a3 = uPaletteID;
+  v3 = 0;
+  v4 = this;
+  if ( pRenderer->pRenderD3D )
+  {
+    if ( (signed int)this->uNumLoadedSprites > 0 )
+    {
+      v17 = 0;
+      while ( _strcmpi(*(const char **)&v17->pName[(unsigned int)v4->pHardwareSprites], pContainerName) )
+      {
+        ++v17;
+        ++v3;
+        if ( v3 >= (signed int)v4->uNumLoadedSprites )
+          goto LABEL_6;
+      }
+      return v3;
+    }
+  }
+  else
+  {
+    if ( (signed int)this->uNumLoadedSprites > 0 )
+    {
+      v17 = this->pSpriteHeaders;
+      while ( _strcmpi(v17->pName, pContainerName) )
+      {
+        ++v17;
+        ++v3;
+        if ( v3 >= (signed int)v4->uNumLoadedSprites )
+          goto LABEL_6;
+      }
+      return v3;
+    }
+  }
+LABEL_6:
+  v5 = v4->uNumLoadedSprites;
+  if ( v5 == 1500 )
+    return -1;
+  if ( pRenderer->pRenderD3D && v4->field_ECAC )
+  {
+    if ( !v4->pHardwareSprites )
+    {
+      v4->pHardwareSprites = (Sprite *)pAllocator->AllocNamedChunk(0, 0xEA60u, "hardSprites");
+      v6 = 0;
+      do
+      {
+        v7 = &v4->pHardwareSprites[v6];
+        ++v6;
+        v7->pName = 0;
+        v7->pTextureSurface = 0;
+        v7->pTexture = 0;
+      }
+      while ( v6 < 1500 );
+    }
+    DstBuf.uHeight = 0;
+    DstBuf.uPaletteId = 0;
+    DstBuf.word_1A = 0;
+    DstBuf.pSpriteLines = 0;
+    DstBuf.pDecompressedBytes = 0;
+    v18 = 0;
+    v8 = FindContainer(pContainerName, 0);
+    if ( !v8 )
+    {
+      v18 = -1;
+      //LODSprite::dtor(&DstBuf);
+      return -1;
+    }
+    fread(&DstBuf, 1u, 0x20u, v8);
+    v10 = v4->pHardwareSprites;
+    v11 = 5 * v4->uNumLoadedSprites;
+    v18 = -1;
+    pHardwareSprites[uNumLoadedSprites].uBufferWidth = DstBuf.uWidth;
+    pHardwareSprites[uNumLoadedSprites].uBufferHeight = DstBuf.uHeight;
+    pSpriteHeaders[uNumLoadedSprites].uWidth = DstBuf.uWidth;
+    pSpriteHeaders[uNumLoadedSprites].uHeight = DstBuf.uHeight;
+    //LODSprite::dtor(&DstBuf);
+    goto LABEL_29;
+  }
+  v12 = LoadSpriteFromFile( &v4->pSpriteHeaders[v5], pContainerName);
+  v4->pSpriteHeaders[v4->uNumLoadedSprites].word_1A = 0;
+  if ( v12 != -1 )
+  {
+LABEL_28:
+    v4->pSpriteHeaders[v4->uNumLoadedSprites].uPaletteId = pPaletteManager->LoadPalette(
+                                                             v4->pSpriteHeaders[v4->uNumLoadedSprites].uPaletteId);
+LABEL_29:
+    if ( pRenderer->pRenderD3D )
+    {
+      v4->pHardwareSprites[v4->uNumLoadedSprites].pName = (const char *)pAllocator->AllocNamedChunk(
+                                                                          v4->pHardwareSprites[v4->uNumLoadedSprites].pName,
+                                                                          0x14u,
+                                                                          pContainerName);
+      strcpy((char *)pHardwareSprites[uNumLoadedSprites].pName, pContainerName);
+      v4->pHardwareSprites[v4->uNumLoadedSprites].uPaletteID = uPaletteID;
+      pRenderer->MoveSpriteToDevice(&pHardwareSprites[uNumLoadedSprites]);
+    }
+    ++v4->uNumLoadedSprites;
+    return v4->uNumLoadedSprites - 1;
+  }
+  v13 = v4->uNumLoadedSprites == 0;
+  v14 = (v4->uNumLoadedSprites & 0x80000000u) != 0;
+  v17 = 0;
+  if ( v14 | v13 )
+  {
+LABEL_27:
+    if ( LoadSpriteFromFile(&v4->pSpriteHeaders[v4->uNumLoadedSprites], "pending") == -1 )
+      return -1;
+    goto LABEL_28;
+  }
+  Str1 = (char *)v4->pSpriteHeaders;
+  while ( _strcmpi(Str1, "pending") )
+  {
+    v17 = (LODSprite *)((char *)v17 + 1);
+    Str1 += 40;
+    if ( (signed int)v17 >= (signed int)v4->uNumLoadedSprites )
+      goto LABEL_27;
+  }
+  return (int)v17;
+}
+
+//----- (004ACADA) --------------------------------------------------------
+void LODFile_Sprites::ReleaseLostHardwareSprites()
+{
+  LODFile_Sprites *v1; // esi@1
+  signed int v2; // ebx@2
+  int v3; // edi@3
+  IDirectDrawSurface *v4; // eax@4
+  IDirect3DTexture2 *v5; // eax@6
+  IDirectDrawSurface *v6; // ST00_4@8
+
+  v1 = this;
+  if ( this->pHardwareSprites )
+  {
+    v2 = 0;
+    if ( (signed int)this->uNumLoadedSprites > 0 )
+    {
+      v3 = 0;
+      do
+      {
+        v4 = v1->pHardwareSprites[v3].pTextureSurface;
+        if ( v4 && v4->IsLost() == DDERR_SURFACELOST )
+        {
+          v5 = v1->pHardwareSprites[v3].pTexture;
+          if ( v5 )
+          {
+            v5->Release();
+            v1->pHardwareSprites[v3].pTexture = 0;
+          }
+          v6 = v1->pHardwareSprites[v3].pTextureSurface;
+          v6->Release();
+          v1->pHardwareSprites[v3].pTextureSurface = 0;
+          pRenderer->MoveSpriteToDevice(&v1->pHardwareSprites[v3]);
+        }
+        ++v2;
+        ++v3;
+      }
+      while ( v2 < (signed int)v1->uNumLoadedSprites );
+    }
+  }
+}
+
+//----- (004ACB70) --------------------------------------------------------
+void LODFile_Sprites::ReleaseAll()
+{
+  LODFile_Sprites *v1; // esi@1
+  signed int v2; // ebx@2
+  int v3; // edi@3
+  Sprite *v4; // eax@4
+  IDirect3DTexture2 *v5; // eax@5
+  Sprite *v6; // eax@7
+  IDirectDrawSurface *v7; // eax@8
+
+  v1 = this;
+  if ( this->pHardwareSprites )
+  {
+    v2 = 0;
+    if ( (signed int)this->uNumLoadedSprites > 0 )
+    {
+      v3 = 0;
+      do
+      {
+        v4 = v1->pHardwareSprites;
+        if ( v4 )
+        {
+          v5 = v4[v3].pTexture;
+          if ( v5 )
+          {
+            v5->Release();
+            v1->pHardwareSprites[v3].pTexture = 0;
+          }
+          v6 = v1->pHardwareSprites;
+          if ( v6 )
+          {
+            v7 = v6[v3].pTextureSurface;
+            if ( v7 )
+            {
+              v7->Release();
+              v1->pHardwareSprites[v3].pTextureSurface = 0;
+            }
+          }
+        }
+        ++v2;
+        ++v3;
+      }
+      while ( v2 < (signed int)v1->uNumLoadedSprites );
+    }
+  }
+}
+
+//----- (004ACBE0) --------------------------------------------------------
+void LODFile_Sprites::MoveSpritesToVideoMemory()
+{
+  LODFile_Sprites *v1; // esi@1
+  int v2; // ebx@1
+  signed int v3; // edi@2
+
+  v1 = this;
+  v2 = 0;
+  if ( this->pHardwareSprites )
+  {
+    v3 = 0;
+    if ( (signed int)this->uNumLoadedSprites > 0 )
+    {
+      do
+      {
+        pRenderer->MoveSpriteToDevice(&v1->pHardwareSprites[v2]);
+        ++v3;
+        ++v2;
+      }
+      while ( v3 < (signed int)v1->uNumLoadedSprites );
+    }
+  }
+}
+
+//----- (004ACC38) --------------------------------------------------------
+int LODSprite::_4ACC38(RenderBillboardTransform_local0 *a2, char a3)
+{
+  RenderBillboardTransform_local0 *v3; // edi@1
+  int result; // eax@1
+  int v5; // esi@2
+  int v6; // ST18_4@2
+  signed int v7; // eax@2
+  signed int v8; // ebx@2
+  int v9; // ebx@2
+  int *v10; // ecx@2
+  int v11; // esi@2
+  unsigned int v12; // edx@4
+  int v13; // esi@13
+  int v14; // esi@17
+  int v15; // ecx@17
+  char *v16; // edx@17
+  int v17; // esi@17
+  int v18; // ecx@18
+  int v19; // esi@18
+  LODSprite_stru0 *v20; // edx@21
+  int v21; // eax@22
+  int v22; // esi@22
+  int v23; // eax@25
+  int v24; // ecx@25
+  signed __int64 v25; // qtt@27
+  int v26; // eax@27
+  unsigned __int16 *v27; // eax@29
+  LODSprite_stru0 *v28; // edx@29
+  signed int v29; // ecx@30
+  int v30; // ecx@37
+  int v31; // ecx@38
+  signed int v32; // ecx@41
+  int v33; // ecx@47
+  int v34; // ecx@56
+  int v35; // esi@58
+  __int16 v36; // ax@58
+  int v37; // ecx@59
+  int v38; // eax@59
+  int v39; // ecx@62
+  signed int v40; // ST30_4@64
+  signed __int64 v41; // qtt@64
+  int v42; // ecx@64
+  unsigned __int16 *v43; // eax@66
+  LODSprite_stru0 *v44; // ecx@66
+  int v45; // edx@69
+  int v46; // edx@77
+  unsigned __int16 *pTarget; // [sp+Ch] [bp-50h]@2
+  signed int v48; // [sp+10h] [bp-4Ch]@2
+  signed int v49; // [sp+14h] [bp-48h]@2
+  int v50; // [sp+14h] [bp-48h]@19
+  int v51; // [sp+14h] [bp-48h]@57
+  int v52; // [sp+18h] [bp-44h]@13
+  int v53; // [sp+1Ch] [bp-40h]@2
+  int v54; // [sp+1Ch] [bp-40h]@22
+  int v55; // [sp+1Ch] [bp-40h]@32
+  int v56; // [sp+1Ch] [bp-40h]@69
+  int v57; // [sp+20h] [bp-3Ch]@2
+  int v58; // [sp+24h] [bp-38h]@1
+  int v59; // [sp+28h] [bp-34h]@2
+  int v60; // [sp+28h] [bp-34h]@13
+  unsigned __int16 *v61; // [sp+2Ch] [bp-30h]@2
+  int v62; // [sp+30h] [bp-2Ch]@2
+  void *v63; // [sp+30h] [bp-2Ch]@29
+  void *v64; // [sp+30h] [bp-2Ch]@66
+  int v65; // [sp+34h] [bp-28h]@2
+  int v66; // [sp+34h] [bp-28h]@22
+  int v67; // [sp+34h] [bp-28h]@59
+  int v68; // [sp+38h] [bp-24h]@13
+  unsigned int v69; // [sp+3Ch] [bp-20h]@2
+  int v70; // [sp+40h] [bp-1Ch]@2
+  signed int v71; // [sp+40h] [bp-1Ch]@15
+  int v72; // [sp+44h] [bp-18h]@2
+  unsigned __int16 *v73; // [sp+44h] [bp-18h]@29
+  unsigned __int16 *v74; // [sp+44h] [bp-18h]@66
+  int v75; // [sp+48h] [bp-14h]@4
+  int v76; // [sp+48h] [bp-14h]@22
+  int v77; // [sp+48h] [bp-14h]@59
+  LODSprite *v78; // [sp+4Ch] [bp-10h]@1
+  int v79; // [sp+50h] [bp-Ch]@4
+  int v80; // [sp+50h] [bp-Ch]@21
+  int v81; // [sp+50h] [bp-Ch]@62
+  int v82; // [sp+50h] [bp-Ch]@67
+  int v83; // [sp+50h] [bp-Ch]@75
+  int *pTargetZ; // [sp+54h] [bp-8h]@4
+  int v85; // [sp+58h] [bp-4h]@18
+  int v86; // [sp+58h] [bp-4h]@56
+  signed int v87; // [sp+64h] [bp+8h]@2
+  int v88; // [sp+68h] [bp+Ch]@18
+  int v89; // [sp+68h] [bp+Ch]@56
+
+  v3 = a2;
+  v78 = this;
+  result = a2->field_10;
+  v58 = a2->field_10;
+  if ( result <= 0 )
+    return result;
+  v5 = a2->field_14;
+  v6 = a2->field_10;
+  v87 = (signed __int64)0x100000000ui64 / result;
+  v48 = (signed __int64)0x100000000ui64 / result;
+  v62 = (signed __int64)0x100000000ui64 / v5;
+  v7 = this->uHeight;
+  v8 = (signed int)((signed __int64)0x100000000ui64 / v5) >> 1;
+  v53 = v8;
+  v70 = (this->uHeight << 16) - v8;
+  v49 = v7;
+  v69 = v3->uTargetPitch;
+  pTarget = v3->pTarget;
+  v57 = v3->field_28;
+  v61 = v3->pPalette;
+  v9 = (v6 * this->uWidth + 32768) >> 16;
+  v72 = v3->field_C;
+  result = (v5 * v7 + 32768) >> 16;
+  v10 = (int *)(v72 - result + 1);
+  v11 = v3->field_8 - (v9 >> 1) + 1;
+  v65 = v72 - result + 1;
+  v59 = v11 + v9 - 1;
+  if ( BYTE1(v3->uFlags) & 8 )
+  {
+    v10 = (int *)((char *)v10 + (v49 >> 1));
+    v72 += v49 >> 1;
+    v65 = (int)v10;
+  }
+  v12 = v72;
+  pTargetZ = v10;
+  v75 = v3->field_8 - (v9 >> 1) + 1;
+  v79 = v11 + v9 - 1;
+  if ( !(v3->uFlags & 8) )
+  {
+    if ( v65 < (signed int)v3->uViewportY )
+      pTargetZ = (int *)v3->uViewportY;
+    if ( v72 > (signed int)v3->uViewportW )
+      v12 = v3->uViewportW;
+    if ( v11 < (signed int)v3->uViewportX )
+      v75 = v3->uViewportX;
+    if ( v59 > (signed int)v3->uViewportZ )
+      v79 = v3->uViewportZ;
+  }
+  v68 = v75 - v11;
+  v13 = -v62;
+  v60 = v59 - v79;
+  v52 = -v62;
+  if ( v3->uFlags & 1 )
+  {
+    v13 = v62;
+    v70 = v53;
+    v52 = v62;
+  }
+  v71 = v13 * (v72 - v12) + v70;
+  if ( LOBYTE(viewparams->field_20) )
+  {
+    if ( a3 )
+      return result;
+  }
+  v14 = 5 * v12;
+  v15 = v69 * v12;
+  result = v12 - v72 + result - 1;
+  v16 = (char *)pTargetZ - v65;
+  v17 = v14 << 7;
+  if ( v3->uFlags & 4 )
+  {
+    v34 = v79 + v15;
+    v89 = v34;
+    v86 = v79 + v17;
+    if ( result < (signed int)v16 )
+      return result;
+    v51 = result - (int)v16 + 1;
+    while ( 1 )
+    {
+      v35 = v71 >> 16;
+      v36 = LOWORD(v78->pSpriteLines[v35].dword_0);
+      if ( v36 == -1 )
+      {
+        v34 -= v69;
+        v89 = v34;
+        goto LABEL_84;
+      }
+      v37 = v9 - ((unsigned __int64)(v36 * (signed __int64)v58) >> 16);
+      v67 = v87 * ((unsigned __int64)(LOWORD(v78->pSpriteLines[v35].dword_0) * (signed __int64)v58) >> 16);
+      v38 = v9 - v60;
+      v77 = v9 - v60;
+      if ( v9 - v60 <= (signed int)(v9
+                                  - ((unsigned __int64)(HIWORD(v78->pSpriteLines[v35].dword_0) * (signed __int64)v58) >> 16))
+        || v68 >= v37 )
+      {
+        v89 -= v69;
+        v34 = v89;
+LABEL_84:
+        v86 -= 640;
+        goto LABEL_85;
+      }
+      if ( v38 < v37 )
+      {
+        v81 = (v87 >> 1) + v87 * (v37 - v38);
+      }
+      else
+      {
+        v77 = v37;
+        v81 = v87 >> 1;
+        v39 = v37 - v9;
+        v89 += v39 + v60;
+        v86 += v60 + v39;
+      }
+      v40 = ((HIWORD(v78->pSpriteLines[v35].dword_0) + 1) << 16) - v81 - v67;
+      LODWORD(v41) = v40 << 16;
+      HIDWORD(v41) = v40 >> 16;
+      v42 = v77 - (((signed int)((unsigned __int64)(v41 / v48) - 32768) >> 16) + 1);
+      if ( v68 >= v42 )
+        v42 = v68;
+      v43 = &pTarget[v89];
+      v74 = &v43[v42 - v77 + 1];
+      v44 = &v78->pSpriteLines[v35];
+      v64 = v44->ptr_4;
+      if ( !v57 )
+      {
+        v83 = v67 + v81;
+        if ( ((v83 - (LOWORD(v44->dword_0) << 16)) & 0xFFFF0000) < 0 )
+        {
+          v83 += v87;
+          --v43;
+          --pTargetZ;
+        }
+        while ( v43 >= v74 )
+        {
+          v46 = (v83 - ((signed int)LOWORD(v78->pSpriteLines[v35].dword_0) << 16)) >> 16;
+          if ( *((char *)v64 + v46) )
+            *v43 = v61[*((char *)v64 + v46)];
+          v83 += v87;
+          --v43;
+        }
+        goto LABEL_81;
+      }
+      pTargetZ = &v3->pTargetZ[v86];
+      v82 = v67 + v81;
+      if ( ((v82 - (LOWORD(v44->dword_0) << 16)) & 0xFFFF0000) < 0 )
+        goto LABEL_72;
+LABEL_73:
+      if ( v43 >= v74 )
+        break;
+LABEL_81:
+      v89 += v9 - v77 - v60 - v69;
+      v34 = v89;
+      v86 = v86 + v9 - v77 - v60 - 640;
+LABEL_85:
+      result = v52;
+      v71 += v52;
+      --v51;
+      if ( !v51 )
+        return result;
+    }
+    v45 = (v82 - ((signed int)LOWORD(v78->pSpriteLines[v35].dword_0) << 16)) >> 16;
+    v56 = *((char *)v64 + v45);
+    if ( *((char *)v64 + v45) && v57 <= (unsigned int)*pTargetZ )
+    {
+      *pTargetZ = v57;
+      *v43 = v61[v56];
+    }
+LABEL_72:
+    v82 += v87;
+    --v43;
+    --pTargetZ;
+    goto LABEL_73;
+  }
+  v18 = v75 + v15;
+  v19 = v75 + v17;
+  v88 = v18;
+  v85 = v19;
+  if ( result >= (signed int)v16 )
+  {
+    v50 = result - (int)v16 + 1;
+    while ( 1 )
+    {
+      v20 = &v78->pSpriteLines[v71 >> 16];
+      v80 = v71 >> 16;
+      if ( LOWORD(v20->dword_0) != -1 )
+        break;
+      v18 -= v69;
+      v85 = v19 - 640;
+      v88 = v18;
+LABEL_54:
+      result = v52;
+      v71 += v52;
+      --v50;
+      if ( !v50 )
+        return result;
+      v19 = v85;
+    }
+    v21 = (v58 * LOWORD(v20->dword_0) + 32768) >> 16;
+    v66 = v21 * v87;
+    v76 = v68;
+    v54 = HIWORD(v20->dword_0);
+    v22 = v9 - v60;
+    if ( v68 >= (v58 * v54 + 32768) >> 16 || v22 <= v21 )
+    {
+      v88 -= v69;
+      v85 -= 640;
+      goto LABEL_51;
+    }
+    if ( v68 > v21 )
+    {
+      v24 = (v87 >> 1) + v87 * (v68 - v21);
+    }
+    else
+    {
+      v76 = (v58 * LOWORD(v20->dword_0) + 32768) >> 16;
+      v23 = v21 - v68;
+      v88 += v23;
+      v24 = v87 >> 1;
+      v85 += v23;
+    }
+    LODWORD(v25) = (((v54 + 1) << 16) - v24 - v66) << 16;
+    HIDWORD(v25) = (((v54 + 1) << 16) - v24 - v66) >> 16;
+    v26 = v76 + ((signed int)(v25 / v48) >> 16) + 1;
+    if ( v22 > v26 )
+      v22 = v26;
+    v27 = &pTarget[v88];
+    v73 = &v27[v22 - v76 - 1];
+    v28 = &v78->pSpriteLines[v80];
+    v63 = v28->ptr_4;
+    if ( v57 )
+    {
+      pTargetZ = &v3->pTargetZ[v85];
+      v29 = v66 - (LOWORD(v28->dword_0) << 16) + v24;
+      if ( (v29 & 0xFFFF0000) >= 0 )
+        goto LABEL_36;
+      while ( 1 )
+      {
+        v29 += v87;
+        ++v27;
+        ++pTargetZ;
+LABEL_36:
+        if ( v27 >= v73 )
+          break;
+        v55 = *((char *)v63 + (v29 >> 16));
+        if ( *((char *)v63 + (v29 >> 16)) && v57 <= (unsigned int)*pTargetZ )
+        {
+          *pTargetZ = v57;
+          *v27 = v61[v55];
+        }
+      }
+      v30 = v29 >> 16;
+      if ( v30 > HIWORD(v78->pSpriteLines[v80].dword_0) - (signed int)LOWORD(v78->pSpriteLines[v80].dword_0)
+        || (v31 = *((char *)v63 + v30)) == 0
+        || v57 > (unsigned int)*pTargetZ )
+        goto LABEL_50;
+      *pTargetZ = v57;
+    }
+    else
+    {
+      v32 = v66 - (LOWORD(v28->dword_0) << 16) + v24;
+      if ( (v32 & 0xFFFF0000) < 0 )
+      {
+        v32 += v87;
+        ++v27;
+        ++pTargetZ;
+      }
+      while ( v27 < v73 )
+      {
+        if ( *((char *)v63 + (v32 >> 16)) )
+          *v27 = v61[*((char *)v63 + (v32 >> 16))];
+        v32 += v87;
+        ++v27;
+      }
+      v33 = v32 >> 16;
+      if ( v33 > HIWORD(v78->pSpriteLines[v80].dword_0) - (signed int)LOWORD(v78->pSpriteLines[v80].dword_0)
+        || (v31 = *((char *)v63 + v33)) == 0 )
+        goto LABEL_50;
+    }
+    *v27 = v61[v31];
+LABEL_50:
+    v88 += v68 - v76 - v69;
+    v85 = v85 + v68 - v76 - 640;
+LABEL_51:
+    v18 = v88;
+    goto LABEL_54;
+  }
+  return result;
+}
+
+//----- (004AD2D1) --------------------------------------------------------
+int LODSprite::_4AD2D1(struct RenderBillboardTransform_local0 *a2, int a3)
+{
+  int result; // eax@1
+  unsigned int v4; // esi@1
+  int v5; // edi@1
+  LODSprite_stru0 *v6; // edx@2
+  __int16 v7; // bx@2
+  int v8; // ecx@3
+  unsigned __int16 *v9; // esi@3
+  int v10; // ebx@3
+  void *v11; // edx@3
+  unsigned __int16 *v12; // ecx@3
+  int v13; // ebx@4
+  LODSprite *v14; // [sp+8h] [bp-10h]@1
+  unsigned __int16 *v15; // [sp+10h] [bp-8h]@1
+  unsigned __int16 *v16; // [sp+14h] [bp-4h]@1
+  int i; // [sp+20h] [bp+8h]@1
+
+  result = (int)a2;
+  v14 = this;
+  v4 = a2->uTargetPitch;
+  v16 = a2->pTarget;
+  v15 = a2->pPalette;
+  v5 = this->uHeight - 1;
+  for ( i = v4 * a2->field_C - (this->uWidth >> 1) + a2->field_8 + 1; v5 >= 0; --v5 )
+  {
+    v6 = &this->pSpriteLines[v5];
+    v7 = LOWORD(v6->dword_0);
+    if ( LOWORD(v6->dword_0) != -1 )
+    {
+      v8 = v7;
+      v9 = &v16[v7 + i];
+      v10 = HIWORD(v6->dword_0);
+      v11 = v6->ptr_4;
+      v12 = &v9[v10 - v8];
+      while ( v9 <= v12 )
+      {
+        v13 = *(char *)v11;
+        v11 = (char *)v11 + 1;
+        if ( v13 )
+          *v9 = v15[v13];
+        ++v9;
+      }
+      v4 = *(int *)(result + 48);
+      //this = v14;
+    }
+    i -= v4;
+  }
+  return result;
+}
+
+//----- (0046454B) --------------------------------------------------------
+void LODFile_IconsBitmaps::ReleaseAll2()
+{
+  LODFile_IconsBitmaps *v1; // esi@1
+  int v2; // edi@1
+  Texture *v3; // ebx@2
+  struct IDirect3DTexture2 **v4; // eax@3
+  struct IDirect3DTexture2 *v5; // eax@4
+  struct IDirectDrawSurface **v6; // eax@6
+  struct IDirectDrawSurface *v7; // eax@7
+  int v8; // eax@10
+
+  v1 = this;
+  v2 = this->uNumLoadedFiles - 1;
+  if ( v2 >= this->dword_11B84 )
+  {
+    v3 = &this->pTextures[v2];
+    do
+    {
+      v3->Release();
+      v4 = v1->pHardwareTextures;
+      if ( v4 )
+      {
+        v5 = v4[v2];
+        if ( v5 )
+        {
+          v5->Release();
+          v1->pHardwareTextures[v2] = 0;
+        }
+      }
+      v6 = v1->pHardwareSurfaces;
+      if ( v6 )
+      {
+        v7 = v6[v2];
+        if ( v7 )
+        {
+          v7->Release();
+          v1->pHardwareSurfaces[v2] = 0;
+        }
+      }
+      --v2;
+      --v3;
+    }
+    while ( v2 >= v1->dword_11B84 );
+  }
+  v8 = v1->dword_11B84;
+  v1->uTexturePacksCount = 0;
+  v1->uNumPrevLoadedFiles = 0;
+  v1->uNumLoadedFiles = v8;
+}
+
+//----- (004645DC) --------------------------------------------------------
+void LODFile_Sprites::DeleteSomeOtherSprites()
+{
+  int *v1; // esi@1
+  int *v2; // edi@1
+
+  v1 = (int *)&this->uNumLoadedSprites;
+  v2 = &this->field_ECA0;
+  DeleteSpritesRange(field_ECA0, uNumLoadedSprites);
+  *v1 = *v2;
+}
+
+
+//----- (00461431) --------------------------------------------------------
+void LOD::File::Close()
+{
+  LOD::File *v1; // esi@1
+  LOD::Directory **v2; // edi@2
+  FILE *v3; // ST00_4@2
+
+  v1 = this;
+  if ( this->isFileOpened )
+  {
+    this->pContainerName[0] = 0;
+    this->uCurrentIndexDir = 0;
+    v2 = &this->pSubIndices;
+    pAllocator->FreeChunk(this->pSubIndices);
+    pAllocator->FreeChunk(v1->pRoot);
+    v3 = v1->pFile;
+    *v2 = 0;
+    v1->pRoot = 0;
+    fclose(v3);
+    v1->isFileOpened = 0;
+    _6A0CA8_lod_unused = 0;
+  }
+}
+// 6A0CA8: using guessed type int 6A0CA8_lod_unused;
+
+//----- (00461492) --------------------------------------------------------
+int LODWriteableFile::_461492(LOD::FileHeader *pHeader, LOD::Directory *pDir, const char *Source)
+{
+  LODWriteableFile *v4; // esi@1
+  FILE *v6; // eax@5
+
+  v4 = this;
+  if ( this->isFileOpened )
+    return 1;
+  if ( !pDir->pFilename[0] )
+    return 2;
+  strcpy((char *)pHeader, "LOD");
+  pHeader->dword_0000A4 = 100;
+  pHeader->uNumIndices = 1;
+  pDir->pFilename[15] = 0;
+  pDir->uDataSize = 0;
+  pDir->uOfsetFromSubindicesStart = 288;
+  strcpy((char *)v4->pLODName, Source);
+  v6 = fopen((const char *)v4->pLODName, "wb+");
+  v4->pFile = v6;
+  if ( !v6 )
+    return 3;
+  fwrite(pHeader, 0x100u, 1u, v6);
+  fwrite(pDir, 0x20u, 1u, v4->pFile);
+  fclose(v4->pFile);
+  v4->pFile = 0;
+  return 0;
+}
+
+//----- (0046153F) --------------------------------------------------------
+void LOD::File::ResetSubIndices()
+{
+  LOD::Directory **pSubIndices_dup2; // esi@2
+  LOD::Directory *pSubIndices_dup; // ST00_4@2
+
+  if ( this->isFileOpened )
+  {
+    pSubIndices_dup2 = &this->pSubIndices;
+    this->pContainerName[0] = 0;
+    this->uCurrentIndexDir = 0;
+    pSubIndices_dup = this->pSubIndices;
+    this->uOffsetToSubIndex = 0;
+    this->uNumSubIndices = 0;
+    this->uLODDataSize = 0;
+    pAllocator->FreeChunk(pSubIndices_dup);
+    *pSubIndices_dup2 = 0;
+  }
+}
+
+
+
+
+
+
+
+//----- (00450C8B) --------------------------------------------------------
+void LODFile_Sprites::DeleteSomeSprites()
+{
+  int *v1; // esi@1
+  int *v2; // edi@1
+
+  v1 = (int *)&this->uNumLoadedSprites;
+  v2 = &this->field_ECA8;
+  DeleteSpritesRange(this->field_ECA8, this->uNumLoadedSprites);
+  *v1 = *v2;
+}
+
+//----- (00450CA9) --------------------------------------------------------
+void LODFile_Sprites::DeleteSpritesRange(int uStartIndex, int uStopIndex)
+{
+  LODFile_Sprites *v3; // edi@1
+  int v4; // esi@3
+  LODSprite *v5; // ebx@3
+  LODSprite *v6; // esi@7
+  int v7; // edi@7
+  int a2a; // [sp+10h] [bp+8h]@3
+
+  v3 = this;
+  if ( this->pHardwareSprites )
+  {
+    if ( uStartIndex < uStopIndex )
+    {
+      v4 = uStartIndex;
+      v5 = &this->pSpriteHeaders[uStartIndex];
+      a2a = uStopIndex - uStartIndex;
+      do
+      {
+        v5->Release();
+        pHardwareSprites[v4].Release();
+        ++v4;
+        ++v5;
+        --a2a;
+      }
+      while ( a2a );
+    }
+  }
+  else
+  {
+    if ( uStartIndex < uStopIndex )
+    {
+      v6 = &this->pSpriteHeaders[uStartIndex];
+      v7 = uStopIndex - uStartIndex;
+      do
+      {
+        v6->Release();
+        ++v6;
+        --v7;
+      }
+      while ( v7 );
+    }
+  }
+}
+
+//----- (00450D1D) --------------------------------------------------------
+void LODSprite::Release()
+{
+  LODSprite *v1; // esi@1
+
+  v1 = this;
+  if ( !(HIBYTE(this->word_1A) & 4) )
+  {
+    pAllocator->FreeChunk(this->pDecompressedBytes);
+    pAllocator->FreeChunk(v1->pSpriteLines);
+  }
+  v1->word_1A = 0;
+  v1->pDecompressedBytes = 0;
+  v1->pSpriteLines = 0;
+  v1->pName[0] = 0;
+  v1->word_16 = 0;
+  v1->uPaletteId = 0;
+  v1->uTexturePitch = 0;
+  v1->uHeight = 0;
+  v1->uWidth = 0;
+  v1->uSpriteSize = 0;
+}
+
+//----- (00450D68) --------------------------------------------------------
+void Sprite::Release()
+{
+  Sprite *v1; // esi@1
+  IDirectDrawSurface *v2; // eax@3
+  IDirect3DTexture2 *v3; // eax@5
+
+  v1 = this;
+  if ( this->pName )
+    pAllocator->FreeChunk((void *)this->pName);
+  v2 = v1->pTextureSurface;
+  if ( v2 )
+    v2->Release();
+  v3 = v1->pTexture;
+  if ( v3 )
+    v3->Release();
+  v1->pName = 0;
+  v1->pTextureSurface = 0;
+  v1->pTexture = 0;
+}
+
+
+
+
+//----- (0040FA2E) --------------------------------------------------------
+bool LODFile_IconsBitmaps::LoadBitmaps(const char *pFilename)
+{
+  ReleaseAll();
+  if (LoadHeader(pFilename, 1))
+    return false;
+  else
+    return LoadSubIndices("bitmaps") == 0;
+}
+
+
+//----- (0040FAEE) --------------------------------------------------------
+bool LODFile_IconsBitmaps::LoadIconsOrEvents(const char *pLODFilename)
+{
+  ReleaseAll();
+
+  if (LoadHeader(pLODFilename, 1))
+    return false;
+  else
+    return LoadSubIndices("icons") == 0;
+}
+
+
+//----- (0040FA60) --------------------------------------------------------
+void LODFile_IconsBitmaps::ReleaseAll()
+{
+  LODFile_IconsBitmaps *v1; // esi@1
+  unsigned int v2; // edi@1
+  Texture *v3; // ebp@2
+  struct IDirect3DTexture2 **v4; // eax@3
+  struct IDirect3DTexture2 *v5; // eax@4
+  struct IDirectDrawSurface **v6; // eax@6
+  struct IDirectDrawSurface *v7; // eax@7
+
+  v1 = this;
+  v2 = this->uNumLoadedFiles - 1;
+  if ( (v2 & 0x80000000u) == 0 )
+  {
+    v3 = &this->pTextures[v2];
+    do
+    {
+      v3->Release();
+      v4 = v1->pHardwareTextures;
+      if ( v4 )
+      {
+        v5 = v4[v2];
+        if ( v5 )
+        {
+          v5->Release();
+          v1->pHardwareTextures[v2] = 0;
+        }
+      }
+      v6 = v1->pHardwareSurfaces;
+      if ( v6 )
+      {
+        v7 = v6[v2];
+        if ( v7 )
+        {
+          v7->Release();
+          v1->pHardwareSurfaces[v2] = 0;
+        }
+      }
+      --v2;
+      --v3;
+    }
+    while ( (v2 & 0x80000000u) == 0 );
+  }
+  v1->uTexturePacksCount = 0;
+  v1->uNumPrevLoadedFiles = 0;
+  v1->dword_11B84 = 0;
+  v1->dword_11B80 = 0;
+  v1->uNumLoadedFiles = 0;
+}
+
+//----- (0040F9F0) --------------------------------------------------------
+unsigned int LODFile_IconsBitmaps::FindTextureByName(const char *pName)
+{
+  LODFile_IconsBitmaps *v2; // esi@1
+  unsigned int v3; // edi@1
+  Texture *v4; // ebx@2
+  unsigned int result; // eax@5
+
+  v2 = this;
+  v3 = 0;
+  if ( (signed int)this->uNumLoadedFiles <= 0 )
+  {
+LABEL_5:
+    result = -1;
+  }
+  else
+  {
+    v4 = this->pTextures;
+    while ( _strcmpi(v4->pName, pName) )
+    {
+      ++v3;
+      ++v4;
+      if ( (signed int)v3 >= (signed int)v2->uNumLoadedFiles )
+        goto LABEL_5;
+    }
+    result = v3;
+  }
+  return result;
+}
+
+//----- (0040F9C5) --------------------------------------------------------
+int LODFile_IconsBitmaps::_40F9C5()
+{
+  signed int result; // eax@1
+  Texture *pTex; // edx@1
+
+  result = this->uNumLoadedFiles;
+  for ( pTex = &this->pTextures[result]; !pTex->pName[0]; --pTex )
+    --result;
+  if ( result < (signed int)this->uNumLoadedFiles )
+  {
+    ++result;
+    this->uNumLoadedFiles = result;
+  }
+  return result;
+}
+
+
+
+//----- (0046249B) --------------------------------------------------------
+LODFile_Sprites::~LODFile_Sprites()
+{
+  LODFile_Sprites *v1; // esi@1
+  signed int v2; // ebx@1
+  LODSprite *v3; // edi@3
+  char *v4; // edi@6
+  int thisa; // [sp+4h] [bp-10h]@3
+  LODSprite *thisb; // [sp+4h] [bp-10h]@7
+
+  v1 = this;
+  v2 = 0;
+  if ( this->pHardwareSprites )
+  {
+    if ( (signed int)this->uNumLoadedSprites > 0 )
+    {
+      thisa = 0;
+      v3 = this->pSpriteHeaders;
+      do
+      {
+        v3->Release();
+        v1->pHardwareSprites[thisa].Release();
+        ++thisa;
+        ++v2;
+        ++v3;
+      }
+      while ( v2 < (signed int)v1->uNumLoadedSprites );
+    }
+  }
+  else
+  {
+    v4 = (char *)&this->uNumLoadedSprites;
+    if ( (signed int)this->uNumLoadedSprites > 0 )
+    {
+      thisb = this->pSpriteHeaders;
+      do
+      {
+        thisb->Release();
+        ++thisb;
+        ++v2;
+      }
+      while ( v2 < *(int *)v4 );
+    }
+  }
+  //_eh_vector_destructor_iterator_(v1->pSpriteHeaders, 40, 1500, LODSprite::dtor);
+  //LOD::File::vdtor((LOD::File *)v1);
+}
+// 4CC2B4: using guessed type int __stdcall _eh vector destructor iterator_(int, int, int, int);
+
+
+//----- (00462463) --------------------------------------------------------
+LODSprite::~LODSprite()
+{
+  LODSprite *v1; // esi@1
+
+  v1 = this;
+  if ( !(HIBYTE(this->word_1A) & 4) )
+  {
+    pAllocator->FreeChunk(this->pDecompressedBytes);
+    pAllocator->FreeChunk(v1->pSpriteLines);
+  }
+  v1->pDecompressedBytes = 0;
+  v1->pSpriteLines = 0;
+}
+
+//----- (004623E5) --------------------------------------------------------
+LODFile_Sprites::LODFile_Sprites():
+  LOD::File()
+{
+  /*_eh_vector_constructor_iterator_(
+    v1->pSpriteHeaders,
+    40,
+    1500,
+    (void (__thiscall *)(void *))LODSprite::LODSprite,
+    (void (__thiscall *)(void *))LODSprite::dtor);*/
+  field_ECA4 = 0;
+  field_ECA0 = 0;
+  pHardwareSprites = 0;
+  field_ECAC = 0;
+  field_ECB4 = 0;
+  uNumLoadedSprites = 0;
+}
+
+//----- (00462303) --------------------------------------------------------
+LODFile_IconsBitmaps::~LODFile_IconsBitmaps()
+{
+  LODFile_IconsBitmaps *v1; // esi@1
+  unsigned int v2; // edi@1
+  struct IDirect3DTexture2 **v3; // eax@3
+  struct IDirect3DTexture2 *v4; // eax@4
+  struct IDirectDrawSurface **v5; // eax@6
+  struct IDirectDrawSurface *v6; // eax@7
+  Texture *thisa; // [sp+4h] [bp-10h]@2
+
+  v1 = this;
+  v2 = this->uNumLoadedFiles - 1;
+  if ( (v2 & 0x80000000u) == 0 )
+  {
+    thisa = &this->pTextures[v2];
+    do
+    {
+      thisa->Release();
+      v3 = v1->pHardwareTextures;
+      if ( v3 )
+      {
+        v4 = v3[v2];
+        if ( v4 )
+        {
+          v4->Release();
+          v1->pHardwareTextures[v2] = 0;
+        }
+      }
+      v5 = v1->pHardwareSurfaces;
+      if ( v5 )
+      {
+        v6 = v5[v2];
+        if ( v6 )
+        {
+          v6->Release();
+          v1->pHardwareSurfaces[v2] = 0;
+        }
+      }
+      --thisa;
+      --v2;
+    }
+    while ( (v2 & 0x80000000u) == 0 );
+  }
+  if ( v1->pHardwareSurfaces )
+    free(v1->pHardwareSurfaces);
+  if ( v1->pHardwareTextures )
+    free(v1->pHardwareTextures);
+  if ( v1->ptr_011BB4 )
+    free(v1->ptr_011BB4);
+  //LOD::File::vdtor((LOD::File *)v1);
+}
+
+//----- (00462272) --------------------------------------------------------
+LODFile_IconsBitmaps::LODFile_IconsBitmaps():
+  LOD::File()
+{
+  LODFile_IconsBitmaps *v1; // esi@1
+  Texture *v2; // ebx@1
+  signed int v3; // [sp+4h] [bp-10h]@1
+
+  v1 = this;
+  /*v2 = v1->pTextures;
+  v3 = 1000;
+  do
+  {
+    Texture::Texture(v2);
+    ++v2;
+    --v3;
+  }
+  while ( v3 );*/
+  v1->uTexturePacksCount = 0;
+  v1->uNumPrevLoadedFiles = 0;
+  v1->dword_11B84 = 0;
+  v1->dword_11B80 = 0;
+  v1->uNumLoadedFiles = 0;
+  v1->dword_011BA4 = 0;
+  v1->dword_011BA8 = 0;
+  v1->pHardwareSurfaces = 0;
+  v1->pHardwareTextures = 0;
+  v1->ptr_011BB4 = 0;
+}
+
+
+//----- (004621A7) --------------------------------------------------------
+bool LODWriteableFile::_4621A7()
+{
+  CloseWriteFile();
+  return LoadFile(pLODName, 0);
+}
+
+
+//----- (00461FD4) --------------------------------------------------------
+int LODWriteableFile::Save()
+{
+  LODWriteableFile *v1; // esi@1
+  int v2; // edi@1
+  unsigned int v3; // edx@1
+  LOD::Directory *v4; // eax@2
+  unsigned int v5; // ecx@2
+  int v6; // eax@2
+  signed int v7; // ebx@5
+  int v8; // ecx@5
+  LOD::Directory **v9; // edi@6
+  int v10; // edx@6
+  LOD::Directory *v11; // eax@6
+  FILE *v12; // eax@9
+  FILE *v13; // ebx@9
+  signed int result; // eax@10
+  unsigned int v15; // eax@11
+  FILE *v16; // ST00_4@11
+  size_t v17; // edi@12
+  char OldFilename[256]; // [sp+Ch] [bp-228h]@9
+  char NewFilename[256]; // [sp+10Ch] [bp-128h]@15
+  //LOD::Directory v0; // [sp+20Ch] [bp-28h]@11
+  unsigned int v21; // [sp+22Ch] [bp-8h]@5
+  int v22; // [sp+230h] [bp-4h]@1
+
+  v1 = this;
+  v2 = 0;
+  v3 = this->uNumSubIndices;
+  v22 = 0;
+  if ( (signed int)v3 > 0 )
+  {
+    v4 = this->pSubIndices;
+    v5 = v3;
+    v6 = (int)&v4->uDataSize;
+    do
+    {
+      v2 += *(int *)v6;
+      v6 += 32;
+      --v5;
+    }
+    while ( v5 );
+    v22 = v2;
+  }
+  v7 = 0;
+  v21 = 32 * v3 + v2;
+  v8 = 32 * v3;
+  if ( (signed int)v3 > 0 )
+  {
+    v9 = &v1->pSubIndices;
+    v10 = 0;
+    v11 = v1->pSubIndices;
+    do
+    {
+      v11[v10].uOfsetFromSubindicesStart = v8;
+      v11 = *v9;
+      v8 += (*v9)[v10].uDataSize;
+      ++v7;
+      ++v10;
+    }
+    while ( v7 < (signed int)v1->uNumSubIndices );
+    v2 = v22;
+  }
+  strcpy(OldFilename, "lod.tmp");
+  v12 = fopen(OldFilename, "wb+");
+  v13 = v12;
+  if ( v12 )
+  {
+    fwrite(&v1->header, 0x100u, 1u, v12);
+
+    LOD::Directory v0; // [sp+20Ch] [bp-28h]@11
+    //LOD::Directory::LOD::Directory(&v0);
+
+    strcpy((char *)&v0, "chapter");
+    v15 = v1->uOffsetToSubIndex;
+    v0.dword_000018 = 0;
+    v0.uOfsetFromSubindicesStart = v15;
+    v0.word_00001E = 0;
+    v0.uDataSize = v21;
+    v0.uNumSubIndices = LOWORD(v1->uNumSubIndices);
+    fwrite(&v0, 0x20u, 1u, v13);
+    fwrite(v1->pSubIndices, 0x20u, v1->uNumSubIndices, v13);
+    v16 = v1->pOutputFileHandle;
+    v22 = v2;
+    fseek(v16, 0, 0);
+    if ( v2 > 0 )
+    {
+      do
+      {
+        v17 = v1->uIOBufferSize;
+        if ( v22 <= (signed int)v17 )
+          v17 = v22;
+        fread(v1->pIOBuffer, 1u, v17, v1->pOutputFileHandle);
+        fwrite(v1->pIOBuffer, 1u, v17, v13);
+        v22 -= v17;
+      }
+      while ( v22 > 0 );
+    }
+    strcpy(NewFilename, (const char *)v1->pLODName);
+    fclose(v13);
+    fclose(v1->pOutputFileHandle);
+    v1->CloseWriteFile();
+    remove("lodapp.tmp");
+    remove(NewFilename);
+    rename(OldFilename, NewFilename);
+    v1->CloseWriteFile();
+    v1->LoadFile(v1->pLODName, 0);
+    result = 0;
+  }
+  else
+  {
+    result = 5;
+  }
+  return result;
+}
+
+
+//----- (00461F71) --------------------------------------------------------
+bool LOD::File::AppendDirectory(LOD::Directory *pDir, const void *pData)
+{
+  unsigned int v3; // edi@1
+  bool result; // eax@2
+  FILE *v5; // ST0C_4@3
+
+  v3 = this->uNumSubIndices;
+  if ( (signed int)v3 < 299 )
+  {
+    memcpy(&this->pSubIndices[v3], pDir, sizeof(this->pSubIndices[v3]));
+    v5 = this->pOutputFileHandle;
+    ++this->uNumSubIndices;
+    fwrite(pData, 1u, pDir->uDataSize, v5);
+    result = 1;
+  }
+  else
+  {
+    MessageBoxA(0, "Unable to append item!", "LOD::File", 0x30u);
+    result = 0;
+  }
+  return result;
+}
+
+
+//----- (00461F1E) --------------------------------------------------------
+int LODWriteableFile::CreateTempFile()
+{
+  LODWriteableFile *v1; // esi@1
+  int result; // eax@2
+  FILE *pFile; // eax@5
+  int v4; // eax@5
+
+  v1 = this;
+  if ( this->isFileOpened )
+  {
+    if ( this->pIOBuffer && this->uIOBufferSize )
+    {
+      this->uCurrentIndexDir = 0;
+      this->uNumSubIndices = 0;
+      pFile = fopen("lodapp.tmp", "wb+");
+      v1->pOutputFileHandle = pFile;
+      v4 = -(pFile != 0);
+      LOBYTE(v4) = v4 & 0xF9;
+      result = v4 + 7;
+    }
+    else
+    {
+      result = 5;
+    }
+  }
+  else
+  {
+    result = 1;
+  }
+  return result;
+}
+
+
+
+//----- (00461EE9) --------------------------------------------------------
+void LODWriteableFile::CloseWriteFile()
+{
+  FILE **v1; // esi@1
+
+  v1 = (FILE **)this;
+  if ( this->isFileOpened )
+  {
+    this->pContainerName[0] = 0;
+    this->uCurrentIndexDir = 0;
+    this->isFileOpened = 0;
+    _6A0CA8_lod_unused = 0;
+    fflush(this->pFile);
+    fclose(*v1);
+  }
+}
+// 6A0CA8: using guessed type int 6A0CA8_lod_unused;
+
+//----- (00461B48) --------------------------------------------------------
+unsigned int LODWriteableFile::Write(const LOD::Directory *pDir, const void *pDirData, int a4)
+{
+  LODWriteableFile *v4; // ebx@1
+  int v5; // esi@1
+  unsigned __int8 v7; // zf@7
+  unsigned __int8 v8; // sf@7
+  const LOD::Directory *v9; // edi@9
+  int v10; // eax@9
+  unsigned __int8 v11; // of@15
+  unsigned __int16 v12; // dx@17
+  LOD::Directory *v13; // eax@17
+  unsigned __int16 v14; // cx@17
+  int v15; // edi@27
+  unsigned int v16; // eax@27
+  int v17; // eax@29
+  int v18; // edx@31
+  int v19; // eax@31
+  void *v20; // edi@32
+  LOD::Directory *v21; // edi@34
+  signed int v22; // esi@34
+  int v23; // eax@34
+  LOD::Directory *v24; // ecx@35
+  int v25; // edx@35
+  __int32 v26; // eax@37
+  int i; // esi@39
+  __int32 v28; // esi@46
+  char pFilename[256]; // [sp+Ch] [bp-230h]@22
+  char NewFilename[256]; // [sp+10Ch] [bp-130h]@51
+  //LOD::Directory Str; // [sp+20Ch] [bp-30h]@27
+  size_t v33; // [sp+22Ch] [bp-10h]@27
+  int v34; // [sp+230h] [bp-Ch]@7
+  __int32 v35; // [sp+234h] [bp-8h]@8
+  int v36; // [sp+238h] [bp-4h]@7
+  size_t Count; // [sp+244h] [bp+8h]@40
+  __int32 Countc; // [sp+244h] [bp+8h]@46
+  size_t Countb; // [sp+244h] [bp+8h]@47
+  FILE *pFile; // [sp+24Ch] [bp+10h]@22
+
+  v4 = this;
+  v5 = 0;
+  if ( !this->isFileOpened )
+    return 1;
+  if ( !this->pSubIndices )
+    return 2;
+  if ( !this->pIOBuffer || !this->uIOBufferSize )
+    return 3;
+  v7 = this->uNumSubIndices == 0;
+  v8 = (this->uNumSubIndices & 0x80000000u) != 0;
+  v36 = 0;
+  v34 = 0;
+  if ( v8 | v7 )
+  {
+    v9 = pDir;
+    goto LABEL_22;
+  }
+  v35 = 0;
+  while ( 1 )
+  {
+    v9 = pDir;
+    v10 = _strcmpi((const char *)v4->pSubIndices + v35, (const char *)pDir);
+    if ( v10 )
+    {
+      if ( v10 > 0 )
+        goto LABEL_22;
+      goto LABEL_15;
+    }
+    if ( !a4 )
+      goto LABEL_20;
+    if ( a4 == 1 )
+      break;
+    if ( a4 == 2 )
+      return 4;
+LABEL_15:
+    v35 += 32;
+    ++v5;
+    v11 = __OFSUB__(v5, v4->uNumSubIndices);
+    v8 = ((v5 - v4->uNumSubIndices) & 0x80000000u) != 0;
+    v34 = v5;
+    if ( !(v8 ^ v11) )
+      goto LABEL_22;
+  }
+  v12 = pDir->uNumSubIndices;
+  v13 = &v4->pSubIndices[v5];
+  v14 = v13->uNumSubIndices;
+  if ( v14 >= v12 && (v14 != v12 || (unsigned __int16)v13->word_00001E >= pDir->word_00001E) )
+    return 4;
+LABEL_20:
+  v36 = 1;
+LABEL_22:
+  strcpy(pFilename, "lod.tmp");
+  pFile = fopen(pFilename, "wb+");
+  if ( !pFile )
+    return 5;
+  if ( v36 )
+    v35 = v4->pSubIndices[v5].uDataSize;
+  else
+    v35 = 0;
+  v33 = v9->uDataSize;
+  v15 = v33 - v35;
+
+  LOD::Directory Str; // [sp+20Ch] [bp-30h]@27
+  //LOD::Directory::LOD::Directory(&Str);
+
+  strcpy((char *)&Str, "chapter");
+  v16 = v4->uLODDataSize;
+  Str.uNumSubIndices = LOWORD(v4->uNumSubIndices);
+  Str.dword_000018 = 0;
+  Str.word_00001E = 0;
+  if ( !v36 )
+  {
+    ++Str.uNumSubIndices;
+    v15 += 32;
+  }
+  v7 = v36 == 0;
+  Str.uDataSize = v15 + v16;
+  Str.uOfsetFromSubindicesStart = 288;
+  v17 = (signed __int16)Str.uNumSubIndices;
+  v4->uNumSubIndices = (signed __int16)Str.uNumSubIndices;
+  if ( v7 && v17 > v5 )
+  {
+    v18 = v17;
+    v19 = v17 - v5;
+    do
+    {
+      v20 = &v4->pSubIndices[v18];
+      --v18;
+      --v19;
+      memcpy(v20, (char *)v20 - 32, 0x20u);
+    }
+    while ( v19 );
+    v5 = v34;
+  }
+  v21 = v4->pSubIndices;
+  v34 = 32 * v5;
+  memcpy(&v21[v5], pDir, sizeof(v21[v5]));
+  v22 = 0;
+  v23 = 32 * v4->uNumSubIndices;
+  if ( (signed int)v4->uNumSubIndices > 0 )
+  {
+    v24 = v4->pSubIndices;
+    v25 = 0;
+    do
+    {
+      v24[v25].uOfsetFromSubindicesStart = v23;
+      v24 = v4->pSubIndices;
+      v23 += v24[v25].uDataSize;
+      ++v22;
+      ++v25;
+    }
+    while ( v22 < (signed int)v4->uNumSubIndices );
+  }
+  fwrite(&v4->header, 0x100u, 1u, pFile);
+  fwrite(&Str, 0x20u, 1u, pFile);
+  fseek(v4->pFile, Str.uOfsetFromSubindicesStart, 0);
+  fwrite(v4->pSubIndices, 0x20u, v4->uNumSubIndices, pFile);
+  v26 = 32 * v4->uNumSubIndices;
+  if ( !v36 )
+    v26 -= 32;
+  fseek(v4->pFile, v26, 1);
+  for ( i = *(unsigned int *)((char *)&v4->pSubIndices->uOfsetFromSubindicesStart + v34)
+          - v4->pSubIndices->uOfsetFromSubindicesStart; i > 0; i -= Count )
+  {
+    Count = v4->uIOBufferSize;
+    if ( i <= (signed int)v4->uIOBufferSize )
+      Count = i;
+    fread(v4->pIOBuffer, 1u, Count, v4->pFile);
+    fwrite(v4->pIOBuffer, 1u, Count, pFile);
+  }
+  fwrite(pDirData, 1u, v33, pFile);
+  if ( v36 )
+    fseek(v4->pFile, v35, 1);
+  Countc = ftell(v4->pFile);
+  fseek(v4->pFile, 0, 2);
+  v28 = ftell(v4->pFile) - Countc;
+  fseek(v4->pFile, Countc, 0);
+  while ( v28 > 0 )
+  {
+    Countb = v4->uIOBufferSize;
+    if ( v28 <= (signed int)v4->uIOBufferSize )
+      Countb = v28;
+    fread(v4->pIOBuffer, 1u, Countb, v4->pFile);
+    fwrite(v4->pIOBuffer, 1u, Countb, pFile);
+    v28 -= Countb;
+  }
+  strcpy(NewFilename, (const char *)v4->pLODName);
+  fclose(pFile);
+  v4->CloseWriteFile();
+  remove(NewFilename);
+  rename(pFilename, NewFilename);
+  v4->CloseWriteFile();
+  v4->LoadFile(v4->pLODName, 0);
+  return 0;
+}
+
+
+//----- (00461A43) --------------------------------------------------------
+bool LODWriteableFile::LoadFile(const char *pFilename, bool bWriting)
+{
+  LODWriteableFile *v3; // esi@1
+  FILE *pFile_dup; // eax@4
+  unsigned int v5; // ecx@5
+  __int32 v6; // eax@5
+  FILE *v7; // ST00_4@5
+  size_t v8; // edi@5
+  const char *v10; // [sp-4h] [bp-30h]@2
+
+  v3 = this;
+  if ( bWriting & 1 )
+    v10 = "rb";
+  else
+    v10 = "rb+";
+  pFile_dup = fopen(pFilename, v10);
+  v3->pFile = pFile_dup;
+  if ( !pFile_dup )
+    return 0;
+  strcpy((char *)v3->pLODName, pFilename);
+  fread(&v3->header, 0x100u, 1u, v3->pFile);
+  
+  LOD::Directory dir; // [sp+Ch] [bp-20h]@5
+  //LOD::Directory::LOD::Directory(&dir);
+
+  fread(&dir, 0x20u, 1u, v3->pFile);
+  fseek(v3->pFile, 0, 0);
+  v3->isFileOpened = 1;
+  strcpy((char *)v3->pContainerName, "chapter");
+  v5 = (signed __int16)dir.uNumSubIndices;
+  v6 = dir.uOfsetFromSubindicesStart;
+  v3->uCurrentIndexDir = 0;
+  v3->uOffsetToSubIndex = v6;
+  v7 = v3->pFile;
+  v3->uNumSubIndices = v5;
+  v3->uLODDataSize = dir.uDataSize;
+  fseek(v7, v6, 0);
+  v8 = v3->uNumSubIndices;
+  if ( (signed int)v8 > 300 )
+  {
+    MessageBoxA(0, "LODchapterPages exceed 300", "LOD::File", MB_ICONEXCLAMATION);
+    fclose(v3->pFile);
+    return 0;
+  }
+  fread(v3->pSubIndices, 0x20u, v8, v3->pFile);
+  return 1;
+}
+
+
+//----- (00461A11) --------------------------------------------------------
+void LOD::File::FreeSubIndexAndIO()
+{
+  void *v1; // edi@1
+  LOD::Directory **v2; // esi@1
+
+  v1 = this;
+  v2 = &this->pSubIndices;
+  pAllocator->FreeChunk(this->pSubIndices);
+  v1 = (char *)v1 + 264;
+  pAllocator->FreeChunk(pIOBuffer);// delete [] pIOBuffer;
+  pIOBuffer = nullptr;
+  pSubIndices = nullptr;
+}
+
+
+//----- (00461954) --------------------------------------------------------
+void LOD::File::AllocSubIndicesAndIO(unsigned int uNumSubIndices, unsigned int uBufferSize)
+{
+  LOD::File *v3; // esi@1
+  LOD::Directory *pSubIndices_dup; // eax@3
+  char v5; // zf@3
+
+  v3 = this;
+  if ( this->pSubIndices )
+  {
+    MessageBoxA(0, "Attempt to reset a LOD subindex!", "MM6", MB_ICONEXCLAMATION);
+    pAllocator->FreeChunk(v3->pSubIndices);
+    v3->pSubIndices = 0;
+  }
+  pSubIndices_dup = (LOD::Directory *)pAllocator->AllocNamedChunk(
+                                      v3->pSubIndices,
+                                      32 * uNumSubIndices,
+                                      "LODsub");
+  v5 = v3->pIOBuffer == 0;
+  v3->pSubIndices = pSubIndices_dup;
+  if ( !v5 )
+  {
+    MessageBoxA(0, "Attempt to reset a LOD IObuffer!", "MM6", MB_ICONEXCLAMATION);
+    pAllocator->FreeChunk(v3->pIOBuffer);
+    v3->pIOBuffer = 0;
+    v3->uIOBufferSize = 0;
+  }
+  if ( uBufferSize )
+  {
+    v3->pIOBuffer = (unsigned __int8 *)pAllocator->AllocNamedChunk(v3->pIOBuffer, uBufferSize, "LODio");
+    v3->uIOBufferSize = uBufferSize;
+  }
+}
+
+
+
+//----- (0046188A) --------------------------------------------------------
+int LOD::File::LoadSubIndices(const char *pContainer)
+{
+  LOD::File *v2; // esi@1
+  unsigned int uDir; // edi@1
+  int uDir_dup; // ebx@2
+  int result; // eax@5
+  LOD::Directory *v6; // eax@7
+  LOD::Directory *v7; // eax@7
+  __int32 v8; // edx@7
+  FILE *v9; // ST00_4@7
+  LOD::Directory *pSubIndices_dup; // eax@7
+
+  v2 = this;
+  ResetSubIndices();
+  uDir = 0;
+  if ( (signed int)v2->header.uNumIndices <= 0 )
+  {
+LABEL_5:
+    result = 3;
+  }
+  else
+  {
+    uDir_dup = 0;
+    while ( _strcmpi(pContainer, (const char *)&v2->pRoot[uDir_dup]) )
+    {
+      ++uDir;
+      ++uDir_dup;
+      if ( (signed int)uDir >= (signed int)v2->header.uNumIndices )
+        goto LABEL_5;
+    }
+    strcpy((char *)v2->pContainerName, pContainer);
+    v6 = v2->pRoot;
+    v2->uCurrentIndexDir = uDir;
+    v7 = &v6[uDir];
+    v8 = v7->uOfsetFromSubindicesStart;
+    v2->uOffsetToSubIndex = v8;
+    v9 = v2->pFile;
+    v2->uNumSubIndices = v7->uNumSubIndices;
+    fseek(v9, v8, 0);
+    pSubIndices_dup = (LOD::Directory *)pAllocator->AllocNamedChunk(
+                                        v2->pSubIndices,
+                                        32 * (v2->uNumSubIndices + 5),
+                                        "LOD Index");
+    v2->pSubIndices = pSubIndices_dup;
+    if ( pSubIndices_dup )
+      fread(pSubIndices_dup, 0x20u, v2->uNumSubIndices, v2->pFile);
+    result = 0;
+  }
+  return result;
+}
+
+//----- (004617D5) --------------------------------------------------------
+bool LOD::File::LoadHeader(const char *pFilename, bool bWriting)
+{
+  LOD::File *this_dup; // esi@1
+  FILE *pFile_dup; // eax@6
+  void *pRoot_dup; // eax@7
+  const char *v6; // [sp-4h] [bp-Ch]@4
+  FILE *v7; // [sp-4h] [bp-Ch]@7
+
+  this_dup = this;
+  if ( this->isFileOpened )
+    Close();
+  if ( bWriting & 1 )
+    v6 = "rb";
+  else
+    v6 = "rb+";
+  pFile_dup = fopen(pFilename, v6);
+  this_dup->pFile = pFile_dup;
+  if ( pFile_dup )
+  {
+    strcpy(this_dup->pLODName, pFilename);
+    fread(&this_dup->header, 0x100u, 1u, this_dup->pFile);
+    pRoot_dup = pAllocator->AllocNamedChunk(this_dup->pRoot, 0xA0u, "LOD CArray");
+    this_dup->pRoot = (LOD::Directory *)pRoot_dup;
+    v7 = this_dup->pFile;
+    if ( pRoot_dup )
+    {
+      fread(pRoot_dup, 0x20u, this_dup->header.uNumIndices, v7);
+      fseek(this_dup->pFile, 0, 0);
+      this_dup->isFileOpened = 1;
+      return false;
+    }
+    else
+    {
+      fclose(v7);
+      return true;
+    }
+  }
+  return true;
+}
+
+
+//----- (004617B6) --------------------------------------------------------
+void LOD::FileHeader::Reset()
+{
+  this->pSignature[0] = 0;
+  this->array_000004[0] = 0;
+  this->array_000054[0] = 0;
+  this->dword_0000A4 = 0;
+  this->dword_0000A8 = 0;
+  this->uNumIndices = 0;
+}
+
+//----- (00461790) --------------------------------------------------------
+LOD::File::~File()
+{
+  LOD::File *v1; // esi@1
+
+  v1 = this;
+  if ( this->isFileOpened )
+  {
+    fclose(this->pFile);
+    pAllocator->FreeChunk(v1->pSubIndices);
+  }
+}
+
+
+//----- (0046175B) --------------------------------------------------------
+LOD::File::File():
+  pRoot(nullptr)
+{
+  LOD::File *v1; // esi@1
+
+  v1 = this;
+  v1->pFile = 0;
+  v1->pSubIndices = 0;
+  v1->pIOBuffer = 0;
+  v1->isFileOpened = 0;
+  v1->uIOBufferSize = 0;
+  Close();
+}
+
+
+//----- (00461743) --------------------------------------------------------
+LOD::Directory *LOD::Directory::Reset()
+{
+  LOD::Directory *result; // eax@1
+
+  result = this;
+  this->pFilename[0] = 0;
+  this->uOfsetFromSubindicesStart = 0;
+  this->uDataSize = 0;
+  this->dword_000018 = 0;
+  this->uNumSubIndices = 0;
+  this->word_00001E = 0;
+  return result;
+}
+
+
+//----- (0046172B) --------------------------------------------------------
+LOD::Directory::Directory()
+{
+  this->pFilename[0] = 0;
+  this->uOfsetFromSubindicesStart = 0;
+  this->uDataSize = 0;
+  this->uNumSubIndices = 0;
+  this->dword_000018 = 0;
+  this->word_00001E = 0;
+}
+
+//----- (0046165E) --------------------------------------------------------
+int LOD::File::CalcIndexFast(int startIndex, int maxIndex, const char *pContainerName)
+{
+  int v4; // esi@1
+  int v5; // ebx@2
+  int result; // eax@2
+  int v7; // edi@10
+  int v8; // esi@11
+  int v9; // esi@17
+  LOD::File *v10; // [sp+Ch] [bp-4h]@1
+
+  v4 = startIndex;
+  v10 = this;
+  while ( 1 )                                   // binary search in LOD indices
+  {
+    while ( 1 )
+    {
+      v5 = maxIndex - v4;
+      result = _strcmpi((const char *)pContainerName, (const char *)(&v10->pSubIndices[(maxIndex - v4) / 2] + v4));
+      if ( !result )
+        _6A0CA4_lod_binary_search = (maxIndex - v4) / 2 + v4;
+      if ( v4 == maxIndex )
+        goto LABEL_14;
+      if ( result < 0 )
+        break;
+      if ( v5 <= 4 )
+      {
+        v7 = v4;
+        if ( v4 < maxIndex )
+        {
+          v9 = v4;
+          do
+          {
+            result = _strcmpi((const char *)pContainerName, (const char *)&v10->pSubIndices[v9]);
+            if ( !result )
+              goto LABEL_21;
+            ++v7;
+            ++v9;
+          }
+          while ( v7 < maxIndex );
+        }
+LABEL_14:
+        _6A0CA4_lod_binary_search = -1;
+        return result;
+      }
+      v4 += (maxIndex - v4) / 2;
+    }
+    if ( v5 <= 4 )
+      break;
+    maxIndex = (maxIndex - v4) / 2 + v4;
+  }
+  v7 = v4;
+  if ( v4 >= maxIndex )
+    goto LABEL_14;
+  v8 = v4;
+  while ( 1 )
+  {
+    result = _strcmpi((const char *)pContainerName, (const char *)&v10->pSubIndices[v8]);
+    if ( !result )
+      break;
+    ++v7;
+    ++v8;
+    if ( v7 >= maxIndex )
+      goto LABEL_14;
+  }
+LABEL_21:
+  _6A0CA4_lod_binary_search = v7;
+  return result;
+}
+// 6A0CA4: using guessed type int _6A0CA4_lod_binary_search;
+
+
+//----- (0046161C) --------------------------------------------------------
+bool LOD::File::DoesContainerExist(const char *pContainer)
+{
+  LOD::File *this_dup; // esi@1
+  int i; // ebx@1
+  signed int i_dup; // edi@1
+  bool result; // eax@4
+
+  this_dup = this;
+  i = 0;
+  i_dup = 0;
+  if ( (signed int)this->uNumSubIndices <= 0 )
+  {
+LABEL_4:
+    result = 0;
+  }
+  else
+  {
+    while ( _strcmpi((const char *)pContainer, (const char *)&this_dup->pSubIndices[i]) )
+    {
+      ++i_dup;
+      ++i;
+      if ( i_dup >= (signed int)this_dup->uNumSubIndices )
+        goto LABEL_4;
+    }
+    result = 1;
+  }
+  return result;
+}
+
+
+//----- (00461397) --------------------------------------------------------
+int LODFile_Sprites::_461397()
+{
+  int result; // eax@1
+  int *pfield_ECA0; // edi@1
+  int v3; // esi@1
+  int v4; // ecx@3
+
+  result = this->uNumLoadedSprites;
+  pfield_ECA0 = &this->field_ECA0;
+  v3 = this->field_ECA0;
+  this->field_ECA8 = result;
+  if ( result < v3 )
+    this->field_ECA8 = v3;
+  v4 = this->field_ECA4;
+  if ( v3 < v4 )
+    *pfield_ECA0 = v4;
+  return result;
+}
+
+//----- (00461580) --------------------------------------------------------
+FILE *LOD::File::FindContainer(const char *pContainerName, bool bLinearSearch)
+{
+  LOD::File *this_dup; // esi@1
+  unsigned int v4; // eax@4
+  signed int v5; // edi@5
+  int bLinearSearcha; // [sp+18h] [bp+Ch]@6
+
+  this_dup = this;
+  if ( !this->isFileOpened )
+    return 0;
+  if ( bLinearSearch )
+  {
+    v5 = 0;
+    if ( (signed int)this->uNumSubIndices > 0 )
+    {
+      bLinearSearcha = 0;
+      while ( _strcmpi((const char *)pContainerName, (const char *)&this_dup->pSubIndices[bLinearSearcha]) )
+      {
+        ++bLinearSearcha;
+        ++v5;
+        if ( v5 >= (signed int)this_dup->uNumSubIndices )
+          return 0;
+      }
+      v4 = this_dup->pSubIndices[v5].uOfsetFromSubindicesStart;
+      goto LABEL_12;
+    }
+    return 0;
+  }
+  CalcIndexFast(0, this->uNumSubIndices, pContainerName);
+  if ( _6A0CA4_lod_binary_search < 0 )
+    return 0;
+  v4 = this_dup->pSubIndices[_6A0CA4_lod_binary_search].uOfsetFromSubindicesStart;
+LABEL_12:
+  fseek(this_dup->pFile, this_dup->uOffsetToSubIndex + v4, 0);
+  return this_dup->pFile;
+}
+// 6A0CA4: using guessed type int _6A0CA4_lod_binary_search;
+
+//----- (0041097D) --------------------------------------------------------
+void LODFile_IconsBitmaps::SetupPalettes(unsigned int uTargetRBits, unsigned int uTargetGBits, unsigned int uTargetBBits)
+{
+  int v4; // edx@1
+  LODFile_IconsBitmaps *v5; // esi@1
+  int v6; // ecx@1
+  unsigned __int8 v7; // zf@4
+  unsigned __int8 v8; // sf@4
+  unsigned __int16 **v9; // edi@5
+  FILE *v10; // eax@7
+  FILE *v11; // ebx@7
+  signed int v12; // ebx@8
+  int v13; // eax@9
+  int v14; // edx@9
+  int v16; // [sp+4Ch] [bp-8h]@4
+  FILE *File; // [sp+50h] [bp-4h]@7
+
+  v4 = uTargetGBits;
+  v5 = this;
+  v6 = uTargetBBits;
+  if ( v5->uTextureRedBits != uTargetRBits
+    || v5->uTextureGreenBits != uTargetGBits
+    || v5->uTextureBlueBits != uTargetBBits )
+  {
+    v16 = 0;
+    v7 = v5->uNumLoadedFiles == 0;
+    v8 = (v5->uNumLoadedFiles & 0x80000000u) != 0;
+    v5->uTextureRedBits = uTargetRBits;
+    v5->uTextureGreenBits = v4;
+    v5->uTextureBlueBits = v6;
+    if ( !(v8 | v7) )
+    {
+      v9 = &v5->pTextures[0].pPalette16;
+      do
+      {
+        Texture DstBuf; // [sp+4h] [bp-50h]@6
+        //Texture::Texture(&DstBuf);
+
+        if ( *v9 )
+        {
+          v10 = FindContainer((const char *)v9 - 64, 0);
+          v11 = v10;
+          File = v10;
+          if ( v10 )
+          {
+            fread(&DstBuf, 1u, 0x30u, v10);
+            fseek(v11, DstBuf.uTextureSize, 1);
+            v12 = 0;
+            do
+            {
+              fread((char *)&uTargetRBits + 3, 1u, 1u, File);
+              fread((char *)&uTargetBBits + 3, 1u, 1u, File);
+              v13 = fread((char *)&uTargetGBits + 3, 1u, 1u, File);
+              LOWORD(v13) = (unsigned __int8)(BYTE3(uTargetRBits) >> (8 - LOBYTE(v5->uTextureRedBits)));
+              (*v9)[v12] = v13 << (LOBYTE(v5->uTextureGreenBits) + LOBYTE(v5->uTextureBlueBits));
+              LOWORD(v14) = (unsigned __int8)(BYTE3(uTargetBBits) >> (8 - LOBYTE(v5->uTextureGreenBits)));
+              (*v9)[v12] |= v14 << v5->uTextureBlueBits;
+              (*v9)[v12] |= BYTE3(uTargetGBits) >> (8 - LOBYTE(v5->uTextureBlueBits));
+              ++v12;
+            }
+            while ( v12 < 256 );
+          }
+        }
+        ++v16;
+        v9 += 18;
+      }
+      while ( v16 < (signed int)v5->uNumLoadedFiles );
+    }
+  }
+}
+
+
+
+//----- (0041088B) --------------------------------------------------------
+void *LOD::File::LoadRaw(const char *pContainer, int a3)
+{
+  LOD::File *v3; // esi@1
+  FILE *v4; // eax@1
+  FILE *v5; // esi@1
+  void *v6; // eax@5
+  void *v7; // ebx@7
+  void *v8; // edi@7
+  void *v9; // eax@9
+  Texture DstBuf; // [sp+Ch] [bp-4Ch]@1
+  FILE *File; // [sp+54h] [bp-4h]@1
+  unsigned int Argsa; // [sp+60h] [bp+8h]@3
+
+  v3 = this;
+  v4 = FindContainer(pContainer, 0);
+  v5 = v4;
+  File = v4;
+  if ( !v4 )
+    Abortf("Unable to load %s", pContainer);
+  fread(&DstBuf, 1u, 0x30u, v4);
+  Argsa = DstBuf.uTextureSize;
+  if ( DstBuf.uDecompressedSize )
+  {
+    if ( a3 )
+      v6 = malloc(DstBuf.uDecompressedSize);
+    else
+      v6 = pAllocator->AllocNamedChunk(0, DstBuf.uDecompressedSize, DstBuf.pName);
+    v7 = v6;
+    v8 = pAllocator->AllocNamedChunk(0, DstBuf.uTextureSize, DstBuf.pName);
+    fread(v8, 1u, Argsa, File);
+    zlib::MemUnzip(v7, &DstBuf.uDecompressedSize, v8, DstBuf.uTextureSize);
+    DstBuf.uTextureSize = DstBuf.uDecompressedSize;
+    pAllocator->FreeChunk(v8);
+  }
+  else
+  {
+    if ( a3 )
+      v9 = malloc(DstBuf.uTextureSize);
+    else
+      v9 = pAllocator->AllocNamedChunk(0, DstBuf.uTextureSize, DstBuf.pName);
+    v7 = v9;
+    fread(v9, 1u, Argsa, v5);
+  }
+  return v7;
+}
+
+
+
+//----- (00410522) --------------------------------------------------------
+int LODFile_IconsBitmaps::_410522(Texture *pDst, const char *pContainer, unsigned int uTextureType)
+{
+  LODFile_IconsBitmaps *v4; // edi@1
+  Texture *v5; // esi@5
+  unsigned int v6; // eax@5
+  void *v7; // eax@6
+  unsigned int v8; // ST28_4@6
+  void *v9; // ST2C_4@6
+  unsigned __int8 *v10; // eax@7
+  FILE *v11; // ST28_4@7
+  void *v12; // eax@9
+  FILE *v13; // ST28_4@9
+  signed int v14; // eax@12
+  int v15; // ecx@12
+  int v16; // ecx@12
+  int v17; // eax@12
+  signed int v18; // ebx@14
+  int v19; // eax@15
+  int v20; // edx@15
+  signed int v21; // ecx@18
+  signed int v22; // ecx@23
+  char Args[100]; // [sp+4h] [bp-68h]@3
+  FILE *File; // [sp+68h] [bp-4h]@1
+
+  v4 = this;
+  File = FindContainer(pContainer, 0);
+  if ( !File )
+  {
+    File = FindContainer("pending", 0);
+    if ( !File )
+    {
+      sprintfex(Args, "Can't find %s!", pContainer);
+      Abortf(Args);
+    }
+  }
+  v5 = pDst;
+  fread(pDst, 1u, 0x30u, File);
+  strcpy(v5->pName, pContainer);
+  pDst = (Texture *)v5->uTextureSize;
+  v6 = v5->uDecompressedSize;
+  v5->pLevelOfDetail0 = 0;
+  if ( v6 )
+  {
+    v7 = operator new(v6);
+    v8 = v5->uTextureSize;
+    v5->pLevelOfDetail0 = (unsigned __int8 *)v7;
+    pContainer = (const char *)operator new(v8);
+    fread((void *)pContainer, 1u, (size_t)pDst, File);
+    zlib::MemUnzip(v5->pLevelOfDetail0, &v5->uDecompressedSize, pContainer, v5->uTextureSize);
+    v9 = (void *)pContainer;
+    v5->uTextureSize = v5->uDecompressedSize;
+    free(v9);
+  }
+  else
+  {
+    v10 = (unsigned __int8 *)operator new(0);
+    v11 = File;
+    v5->pLevelOfDetail0 = v10;
+    fread(v10, 1u, (size_t)pDst, v11);
+  }
+  v5->pPalette24 = 0;
+  if ( uTextureType == 1 )
+  {
+    v12 = operator new(0x300u);
+    v13 = File;
+    v5->pPalette24 = (unsigned __int8 *)v12;
+    fread(v12, 1u, 0x300u, v13);
+LABEL_10:
+    v5->pPalette16 = 0;
+    goto LABEL_11;
+  }
+  if ( uTextureType != 2 )
+    goto LABEL_10;
+  v18 = 0;
+  v5->pPalette16 = 0;
+  v5->pPalette16 = (unsigned __int16 *)operator new(0x400u);
+  do
+  {
+    fread((char *)&pContainer + 3, 1u, 1u, File);
+    fread((char *)&uTextureType + 3, 1u, 1u, File);
+    v19 = fread((char *)&pDst + 3, 1u, 1u, File);
+    LOWORD(v19) = (unsigned __int8)(BYTE3(pContainer) >> (8 - LOBYTE(v4->uTextureRedBits)));
+    v5->pPalette16[v18] = v19 << (LOBYTE(v4->uTextureBlueBits) + LOBYTE(v4->uTextureGreenBits));
+    LOWORD(v20) = (unsigned __int8)(BYTE3(uTextureType) >> (8 - LOBYTE(v4->uTextureGreenBits)));
+    v5->pPalette16[v18] += v20 << v4->uTextureBlueBits;
+    v5->pPalette16[v18] += (unsigned __int8)(BYTE3(pDst) >> (8 - LOBYTE(v4->uTextureBlueBits)));
+    ++v18;
+  }
+  while ( v18 < 256 );
+LABEL_11:
+  if ( v5->pBits & 2 )
+  {
+    v14 = v5->uSizeOfMaxLevelOfDetail;
+    v15 = (int)&v5->pLevelOfDetail0[v14];
+    v5->pLevelOfDetail1 = (unsigned __int8 *)v15;
+    v16 = (v14 >> 2) + v15;
+    v5->pLevelOfDetail2 = (unsigned __int8 *)v16;
+    v17 = v16 + (v14 >> 4);
+  }
+  else
+  {
+    v17 = 0;
+    v5->pLevelOfDetail2 = 0;
+    v5->pLevelOfDetail1 = 0;
+  }
+  v5->pLevelOfDetail3 = (unsigned __int8 *)v17;
+  v21 = 1;
+  while ( 1 << v21 != v5->uTextureWidth )
+  {
+    ++v21;
+    if ( v21 >= 15 )
+      goto LABEL_23;
+  }
+  v5->uWidthLn2 = v21;
+LABEL_23:
+  v22 = 1;
+  while ( 1 << v22 != v5->uTextureHeight )
+  {
+    ++v22;
+    if ( v22 >= 15 )
+      goto LABEL_28;
+  }
+  v5->uHeightLn2 = v22;
+LABEL_28:
+  switch ( v5->uWidthLn2 )
+  {
+    case 2:
+      v5->uWidthMinus1 = 3;
+      break;
+    case 3:
+      v5->uWidthMinus1 = 7;
+      break;
+    case 4:
+      v5->uWidthMinus1 = 15;
+      break;
+    case 5:
+      v5->uWidthMinus1 = 31;
+      break;
+    case 6:
+      v5->uWidthMinus1 = 63;
+      break;
+    case 7:
+      v5->uWidthMinus1 = 127;
+      break;
+    case 8:
+      v5->uWidthMinus1 = 255;
+      break;
+    case 9:
+      v5->uWidthMinus1 = 511;
+      break;
+    case 10:
+      v5->uWidthMinus1 = 1023;
+      break;
+    case 11:
+      v5->uWidthMinus1 = 2047;
+      break;
+    case 12:
+      v5->uWidthMinus1 = 4095;
+      break;
+    default:
+      break;
+  }
+  switch ( v5->uHeightLn2 )
+  {
+    case 2:
+      v5->uHeightMinus1 = 3;
+      break;
+    case 3:
+      v5->uHeightMinus1 = 7;
+      break;
+    case 4:
+      v5->uHeightMinus1 = 15;
+      break;
+    case 5:
+      v5->uHeightMinus1 = 31;
+      break;
+    case 6:
+      v5->uHeightMinus1 = 63;
+      break;
+    case 7:
+      v5->uHeightMinus1 = 127;
+      break;
+    case 8:
+      v5->uHeightMinus1 = 255;
+      break;
+    case 9:
+      v5->uHeightMinus1 = 511;
+      break;
+    case 10:
+      v5->uHeightMinus1 = 1023;
+      break;
+    case 11:
+      v5->uHeightMinus1 = 2047;
+      break;
+    case 12:
+      v5->uHeightMinus1 = 4095;
+      break;
+    default:
+      return 1;
+  }
+  return 1;
+}
+
+
+//----- (00410423) --------------------------------------------------------
+void LODFile_IconsBitmaps::_410423_move_textures_to_device()
+{
+  LODFile_IconsBitmaps *v1; // esi@1
+  unsigned int v2; // edi@1
+  char *v3; // ebx@2
+  size_t v4; // eax@9
+  char *v5; // ST1C_4@9
+  void *v6; // eax@12
+  signed int v7; // esi@13
+
+  v1 = this;
+  v2 = this->uNumLoadedFiles - 1;
+  if ( (v2 & 0x80000000u) == 0 )
+  {
+    v3 = &this->pTextures[v2].pName[2];
+    do
+    {
+      if ( v1->ptr_011BB4[v2] )
+      {
+        if ( *(v3 - 2) != 'w' || *(v3 - 1) != 't' || *v3 != 'r' || v3[1] != 'd' || v3[2] != 'r' )
+        {
+          pRenderer->LoadTexture(
+            v3 - 2,
+            *((short *)v3 + 17),
+            &v1->pHardwareSurfaces[v2],
+            &v1->pHardwareTextures[v2]);
+        }
+        else
+        {
+          v4 = strlen(v3 - 2);
+          v5 = (char *)operator new(v4 + 2);
+          *v5 = 'h';
+          strcpy(v5 + 1, v3 - 2);
+          pRenderer->LoadTexture(
+            v5,
+            *((short *)v3 + 17),
+            &v1->pHardwareSurfaces[v2],
+            &v1->pHardwareTextures[v2]);
+          free(v5);
+        }
+      }
+      --v2;
+      v3 -= 72;
+    }
+    while ( (v2 & 0x80000000u) == 0 );
+  }
+  v6 = v1->ptr_011BB4;
+  if ( v6 )
+  {
+    v7 = v1->uNumLoadedFiles;
+    if ( v7 > 1 )
+      memset(v6, 0, v7 - 1);
+  }
+}
+
+
+//----- (004103BB) --------------------------------------------------------
+void LODFile_IconsBitmaps::ReleaseHardwareTextures()
+{
+  LODFile_IconsBitmaps *v1; // esi@1
+  unsigned int v2; // edi@1
+  struct IDirect3DTexture2 **v3; // eax@2
+  struct IDirect3DTexture2 *v4; // eax@3
+  struct IDirectDrawSurface **v5; // eax@5
+  struct IDirectDrawSurface *v6; // eax@6
+
+  v1 = this;
+  v2 = this->uNumLoadedFiles;
+  while ( 1 )
+  {
+    --v2;
+    if ( (v2 & 0x80000000u) != 0 )
+      break;
+    v3 = v1->pHardwareTextures;
+    if ( v3 )
+    {
+      v4 = v3[v2];
+      if ( v4 )
+      {
+        v4->Release();
+        v1->pHardwareTextures[v2] = 0;
+        v1->ptr_011BB4[v2] = 1;
+      }
+    }
+    v5 = v1->pHardwareSurfaces;
+    if ( v5 )
+    {
+      v6 = v5[v2];
+      if ( v6 )
+      {
+        v6->Release();
+        v1->pHardwareSurfaces[v2] = 0;
+        v1->ptr_011BB4[v2] = 1;
+      }
+    }
+  }
+}
+
+
+//----- (0041033D) --------------------------------------------------------
+void LODFile_IconsBitmaps::ReleaseLostHardwareTextures()
+{
+  LODFile_IconsBitmaps *v1; // edi@1
+  unsigned int i; // ebx@1
+  struct IDirectDrawSurface **pHardwareSurfaces; // eax@2
+  int v4; // esi@3
+  struct IDirectDrawSurface *pSurface; // eax@3
+  struct IDirect3DTexture2 **v6; // eax@5
+  struct IDirect3DTexture2 *v7; // eax@6
+
+  v1 = this;
+  for ( i = this->uNumLoadedFiles - 1; (i & 0x80000000u) == 0; --i )
+  {
+    pHardwareSurfaces = v1->pHardwareSurfaces;
+    if ( pHardwareSurfaces )
+    {
+      v4 = i;
+      pSurface = pHardwareSurfaces[i];
+      if ( pSurface )
+      {
+        if ( pSurface->IsLost() == DDERR_SURFACELOST )
+        {
+          v6 = v1->pHardwareTextures;
+          if ( v6 )
+          {
+            v7 = v6[v4];
+            if ( v7 )
+            {
+              v7->Release();
+              v1->pHardwareTextures[v4] = 0;
+            }
+          }
+          v1->pHardwareSurfaces[v4]->Release();
+          v1->pHardwareSurfaces[v4] = 0;
+          v1->ptr_011BB4[i] = 1;
+        }
+      }
+    }
+  }
+}
+
+//----- (004101B1) --------------------------------------------------------
+int LODFile_IconsBitmaps::ReloadTexture(Texture *pDst, const char *pContainer, int mode)
+{
+  LODFile_IconsBitmaps *v4; // edi@1
+  FILE *v5; // eax@1
+  Texture *v6; // esi@2
+  unsigned int v7; // ebx@6
+  unsigned int v8; // ecx@6
+  signed int result; // eax@7
+  size_t *v10; // ebx@8
+  signed int v11; // ebx@12
+  int v12; // eax@13
+  int v13; // edx@13
+  FILE *File; // [sp+Ch] [bp-8h]@1
+  unsigned __int8 v15; // [sp+11h] [bp-3h]@13
+  unsigned __int8 v16; // [sp+12h] [bp-2h]@13
+  unsigned __int8 DstBuf; // [sp+13h] [bp-1h]@13
+  void *DstBufa; // [sp+1Ch] [bp+8h]@10
+  void *Sourcea; // [sp+20h] [bp+Ch]@10
+  unsigned int Counta; // [sp+24h] [bp+10h]@6
+
+  v4 = this;
+  v5 = FindContainer(pContainer, 0);
+  File = v5;
+  if ( v5
+    && (v6 = pDst, pDst->pLevelOfDetail0)
+    && mode == 2
+    && pDst->pPalette16
+    && !pDst->pPalette24
+    && (v7 = pDst->uTextureSize,
+        fread(pDst, 1u, 0x30u, v5),
+        strcpy(pDst->pName, pContainer),
+        v8 = pDst->uTextureSize,
+        Counta = pDst->uTextureSize,
+        (signed int)v8 <= (signed int)v7) )
+  {
+    v10 = &pDst->uDecompressedSize;
+    if ( !pDst->uDecompressedSize || v4->dword_011BA4 )
+    {
+      fread(pDst->pLevelOfDetail0, 1u, v8, File);
+    }
+    else
+    {
+      Sourcea = malloc(pDst->uDecompressedSize);
+      DstBufa = malloc(pDst->uTextureSize);
+      fread(DstBufa, 1u, Counta, File);
+      zlib::MemUnzip(Sourcea, &v6->uDecompressedSize, DstBufa, v6->uTextureSize);
+      v6->uTextureSize = *v10;
+      free(DstBufa);
+      memcpy(v6->pLevelOfDetail0, Sourcea, *v10);
+      free(Sourcea);
+    }
+    v11 = 0;
+    do
+    {
+      fread(&DstBuf, 1u, 1u, File);
+      fread(&v16, 1u, 1u, File);
+      v12 = fread(&v15, 1u, 1u, File);
+      LOWORD(v12) = (unsigned __int8)(DstBuf >> (8 - LOBYTE(v4->uTextureRedBits)));
+      v6->pPalette16[v11] = v12 << (LOBYTE(v4->uTextureBlueBits) + LOBYTE(v4->uTextureGreenBits));
+      LOWORD(v13) = (unsigned __int8)(v16 >> (8 - LOBYTE(v4->uTextureGreenBits)));
+      v6->pPalette16[v11] += v13 << v4->uTextureBlueBits;
+      v6->pPalette16[v11] += (unsigned __int8)(v15 >> (8 - LOBYTE(v4->uTextureBlueBits)));
+      ++v11;
+    }
+    while ( v11 < 256 );
+    result = 1;
+  }
+  else
+  {
+    result = -1;
+  }
+  return result;
+}
+
+
+//----- (0040FC08) --------------------------------------------------------
+int LODFile_IconsBitmaps::LoadTextureFromLOD(Texture *pOutTex, const char *pContainer, enum TEXTURE_TYPE eTextureType)
+{
+  const char *v4; // ebx@1
+  LODFile_IconsBitmaps *v5; // edi@1
+  FILE *v6; // eax@1
+  Texture *v8; // esi@3
+  char *v9; // eax@8
+  void *v10; // ST24_4@8
+  size_t v11; // eax@14
+  enum TEXTURE_TYPE v12; // eax@14
+  signed int v13; // esi@14
+  unsigned int v14; // eax@21
+  unsigned int v15; // ecx@25
+  unsigned int *v16; // ebx@25
+  void *v17; // eax@27
+  unsigned int v18; // ST28_4@27
+  void *v19; // ST3C_4@27
+  Allocator *v20; // ebx@29
+  void *v21; // eax@29
+  size_t v22; // ST2C_4@29
+  const void *v23; // ecx@29
+  unsigned __int16 v24; // ax@29
+  unsigned __int16 v25; // cx@29
+  __int16 v26; // dx@29
+  unsigned int v27; // ecx@29
+  Texture *v28; // eax@29
+  unsigned int v29; // ST28_4@30
+  void *v30; // eax@30
+  unsigned int v31; // ST2C_4@30
+  void *v32; // eax@32
+  void *v33; // eax@34
+  signed int v34; // eax@37
+  unsigned __int8 *v35; // ecx@37
+  unsigned __int8 *v36; // ecx@37
+  unsigned __int8 *v37; // eax@37
+  signed int v38; // ebx@39
+  int v39; // eax@40
+  int v40; // edx@40
+  signed int v41; // ecx@43
+  signed int v42; // ecx@48
+  FILE *File; // [sp+14h] [bp-4h]@1
+
+  v4 = pContainer;
+  v5 = this;
+  v6 = FindContainer(pContainer, 0);
+  File = v6;
+  if ( !v6 )
+    return -1;
+  v8 = pOutTex;
+  fread(pOutTex, 1u, 0x30u, v6);
+  strcpy(v8->pName, v4);
+  if ( pRenderer->pRenderD3D && v8->pBits & 2 && v5->dword_011BA8 )
+  {
+    if ( !v5->pHardwareSurfaces || !v5->pHardwareTextures )
+    {
+      v5->pHardwareSurfaces = (struct IDirectDrawSurface **)operator new(0xFA0u);
+      v5->pHardwareTextures = (struct IDirect3DTexture2 **)operator new(0xFA0u);
+      v9 = (char *)operator new(0x3E8u);
+      v10 = v5->pHardwareSurfaces;
+      v5->ptr_011BB4 = v9;
+      memset(v10, 0, 0xFA0u);
+      memset(v5->pHardwareTextures, 0, 0xFA0u);
+      memset(v5->ptr_011BB4, 0, 0x3E8u);
+    }
+    if ( *v4 != 'w' || v4[1] != 't' || v4[2] != 'r' || v4[3] != 'd' || v4[4] != 'r' )
+    {
+      if ( *v4 != 'W' || v4[1] != 't' || v4[2] != 'r' || v4[3] != 'T' || v4[4] != 'y' || v4[5] != 'l' )
+      {
+        v14 = v5->uNumLoadedFiles;
+      }
+      else
+      {
+        pRenderer->field_1036AC_bitmapid = v5->uNumLoadedFiles;
+        v14 = v5->uNumLoadedFiles;
+      }
+      v13 = pRenderer->LoadTexture(
+              v4,
+              LOWORD(v8->palette),
+              &v5->pHardwareSurfaces[v14],
+              &v5->pHardwareTextures[v14]);
+    }
+    else
+    {
+      v11 = strlen(v4);
+      v12 = (enum TEXTURE_TYPE)(int)operator new(v11 + 2);
+      eTextureType = v12;
+      *(char *)v12 = 104;
+      strcpy((char *)(v12 + 1), v4);
+      v13 = pRenderer->LoadTexture(
+              (const char *)eTextureType,
+              LOWORD(v8->palette),
+              &v5->pHardwareSurfaces[v5->uNumLoadedFiles],
+              &v5->pHardwareTextures[v5->uNumLoadedFiles]);
+      free((void *)eTextureType);
+    }
+    return v13;
+  }
+  v15 = v8->uTextureSize;
+  v16 = &v8->uDecompressedSize;
+  pOutTex = (Texture *)v8->uTextureSize;
+  if ( !v8->uDecompressedSize || v5->dword_011BA4 )
+  {
+    v20 = pAllocator;
+    v32 = pAllocator->AllocNamedChunk(v8->pLevelOfDetail0, v15, v8->pName);
+    v8->pLevelOfDetail0 = (unsigned __int8 *)v32;
+    fread(v32, 1u, (size_t)pOutTex, File);
+  }
+  else
+  {
+    v17 = malloc(v8->uDecompressedSize);
+    v18 = v8->uTextureSize;
+    pContainer = (const char *)v17;
+    v19 = malloc(v18);
+    fread(v19, 1u, (size_t)pOutTex, File);
+    zlib::MemUnzip((void *)pContainer, &v8->uDecompressedSize, v19, v8->uTextureSize);
+    v8->uTextureSize = *v16;
+    free(v19);
+    if ( bUseLoResSprites && v8->pBits & 2 )
+    {
+      v20 = pAllocator;
+      pOutTex = (Texture *)(((signed int)v8->uSizeOfMaxLevelOfDetail >> 2)
+                          + ((signed int)v8->uSizeOfMaxLevelOfDetail >> 4)
+                          + ((signed int)v8->uSizeOfMaxLevelOfDetail >> 6));
+      v21 = pAllocator->AllocNamedChunk(v8->pLevelOfDetail0, (unsigned int)pOutTex, v8->pName);
+      v22 = (size_t)pOutTex;
+      v23 = &pContainer[v8->uTextureWidth * v8->uTextureHeight];
+      v8->pLevelOfDetail0 = (unsigned __int8 *)v21;
+      memcpy(v21, v23, v22);
+      v8->uTextureWidth = (signed __int16)v8->uTextureWidth >> 1;
+      v24 = v8->uTextureWidth;
+      v8->uTextureHeight = (signed __int16)v8->uTextureHeight >> 1;
+      v25 = v8->uTextureHeight;
+      --v8->uWidthLn2;
+      --v8->uHeightLn2;
+      v8->uWidthMinus1 = v24 - 1;
+      v26 = v25 - 1;
+      v27 = (signed __int16)v24 * (signed __int16)v25;
+      v28 = pOutTex;
+      v8->uHeightMinus1 = v26;
+      v8->uSizeOfMaxLevelOfDetail = v27;
+      v8->uTextureSize = (unsigned int)v28;
+    }
+    else
+    {
+      v29 = *v16;
+      v20 = pAllocator;
+      v30 = pAllocator->AllocNamedChunk(v8->pLevelOfDetail0, v29, v8->pName);
+      v31 = v8->uDecompressedSize;
+      v8->pLevelOfDetail0 = (unsigned __int8 *)v30;
+      memcpy(v30, pContainer, v31);
+    }
+    free((void *)pContainer);
+  }
+  pAllocator->FreeChunk(v8->pPalette16);
+  pAllocator->FreeChunk(v8->pPalette24);
+  if ( eTextureType == TEXTURE_24BIT_PALETTE )
+  {
+    v33 = pAllocator->AllocNamedChunk(v8->pPalette24, 0x300u, v8->pName);
+    v8->pPalette24 = (unsigned __int8 *)v33;
+    fread(v33, 1u, 0x300u, File);
+  }
+  else
+  {
+    v8->pPalette24 = 0;
+    if ( eTextureType == TEXTURE_16BIT_PALETTE )
+    {
+      v8->pPalette16 = (unsigned __int16 *)pAllocator->AllocNamedChunk(v8->pPalette16, 0x200u, v8->pName);
+      v38 = 0;
+      do
+      {
+        fread((char *)&eTextureType + 3, 1u, 1u, File);
+        fread((char *)&pContainer + 3, 1u, 1u, File);
+        v39 = fread((char *)&pOutTex + 3, 1u, 1u, File);
+        LOWORD(v39) = (unsigned __int8)(BYTE3(eTextureType) >> (8 - LOBYTE(v5->uTextureRedBits)));
+        v8->pPalette16[v38] = v39 << (LOBYTE(v5->uTextureBlueBits) + LOBYTE(v5->uTextureGreenBits));
+        LOWORD(v40) = (unsigned __int8)(BYTE3(pContainer) >> (8 - LOBYTE(v5->uTextureGreenBits)));
+        v8->pPalette16[v38] += v40 << v5->uTextureBlueBits;
+        v8->pPalette16[v38] += (unsigned __int8)(BYTE3(pOutTex) >> (8 - LOBYTE(v5->uTextureBlueBits)));
+        ++v38;
+      }
+      while ( v38 < 256 );
+      goto LABEL_36;
+    }
+  }
+  v8->pPalette16 = 0;
+LABEL_36:
+  if ( v8->pBits & 2 )
+  {
+    v34 = v8->uSizeOfMaxLevelOfDetail;
+    v35 = &v8->pLevelOfDetail0[v34];
+    v8->pLevelOfDetail1 = v35;
+    v36 = &v35[v34 >> 2];
+    v8->pLevelOfDetail2 = v36;
+    v37 = &v36[v34 >> 4];
+  }
+  else
+  {
+    v37 = 0;
+    v8->pLevelOfDetail2 = 0;
+    v8->pLevelOfDetail1 = 0;
+  }
+  v8->pLevelOfDetail3 = v37;
+  v41 = 1;
+  while ( 1 << v41 != v8->uTextureWidth )
+  {
+    ++v41;
+    if ( v41 >= 15 )
+      goto LABEL_48;
+  }
+  v8->uWidthLn2 = v41;
+LABEL_48:
+  v42 = 1;
+  while ( 1 << v42 != v8->uTextureHeight )
+  {
+    ++v42;
+    if ( v42 >= 15 )
+      goto LABEL_53;
+  }
+  v8->uHeightLn2 = v42;
+LABEL_53:
+  switch ( v8->uWidthLn2 )
+  {
+    case 2:
+      v8->uWidthMinus1 = 3;
+      break;
+    case 3:
+      v8->uWidthMinus1 = 7;
+      break;
+    case 4:
+      v8->uWidthMinus1 = 15;
+      break;
+    case 5:
+      v8->uWidthMinus1 = 31;
+      break;
+    case 6:
+      v8->uWidthMinus1 = 63;
+      break;
+    case 7:
+      v8->uWidthMinus1 = 127;
+      break;
+    case 8:
+      v8->uWidthMinus1 = 255;
+      break;
+    case 9:
+      v8->uWidthMinus1 = 511;
+      break;
+    case 10:
+      v8->uWidthMinus1 = 1023;
+      break;
+    case 11:
+      v8->uWidthMinus1 = 2047;
+      break;
+    case 12:
+      v8->uWidthMinus1 = 4095;
+      break;
+    default:
+      break;
+  }
+  switch ( v8->uHeightLn2 )
+  {
+    case 2:
+      v8->uHeightMinus1 = 3;
+      break;
+    case 3:
+      v8->uHeightMinus1 = 7;
+      break;
+    case 4:
+      v8->uHeightMinus1 = 15;
+      break;
+    case 5:
+      v8->uHeightMinus1 = 31;
+      break;
+    case 6:
+      v8->uHeightMinus1 = 63;
+      break;
+    case 7:
+      v8->uHeightMinus1 = 127;
+      break;
+    case 8:
+      v8->uHeightMinus1 = 255;
+      break;
+    case 9:
+      v8->uHeightMinus1 = 511;
+      break;
+    case 10:
+      v8->uHeightMinus1 = 1023;
+      break;
+    case 11:
+      v8->uHeightMinus1 = 2047;
+      break;
+    case 12:
+      v8->uHeightMinus1 = 4095;
+      break;
+    default:
+      return 1;
+  }
+  return 1;
+}
+
+
+//----- (0040FB20) --------------------------------------------------------
+unsigned int LODFile_IconsBitmaps::LoadTexture(const char *pContainer, enum TEXTURE_TYPE uTextureType)
+{
+  LODFile_IconsBitmaps *v3; // esi@1
+  unsigned int v4; // edi@1
+  Texture *v5; // ebx@2
+  unsigned int v6; // ebx@8
+  const char *Sourcea; // [sp+14h] [bp+8h]@9
+
+  v3 = this;
+  v4 = 0;
+  areWeLoadingTexture = 1;
+  if ( (signed int)this->uNumLoadedFiles <= 0 )
+  {
+LABEL_5:
+    if ( (signed int)v3->uNumLoadedFiles >= 1000 )
+      AbortWithError();
+    if ( v3->LoadTextureFromLOD(&v3->pTextures[v3->uNumLoadedFiles], pContainer, uTextureType) == -1 )
+    {
+      v6 = 0;
+      if ( (signed int)v3->uNumLoadedFiles > 0 )
+      {
+        Sourcea = (const char *)v3->pTextures;
+        while ( _strcmpi(Sourcea, "pending") )
+        {
+          Sourcea += 72;
+          ++v6;
+          if ( (signed int)v6 >= (signed int)v3->uNumLoadedFiles )
+            goto LABEL_15;
+        }
+        return v6;
+      }
+LABEL_15:
+      v3->LoadTextureFromLOD(&v3->pTextures[v3->uNumLoadedFiles], "pending", uTextureType);
+    }
+    areWeLoadingTexture = 0;
+    ++v3->uNumLoadedFiles;
+    return v3->uNumLoadedFiles - 1;
+  }
+  v5 = this->pTextures;
+  while ( _strcmpi(v5->pName, pContainer) )
+  {
+    ++v4;
+    ++v5;
+    if ( (signed int)v4 >= (signed int)v3->uNumLoadedFiles )
+      goto LABEL_5;
+  }
+  return v4;
+}
+// 506128: using guessed type int areWeLoadingTexture;
\ No newline at end of file