changeset 49:25fabc49627b

Слияние
author Ritor1
date Tue, 23 Oct 2012 17:34:20 +0600
parents 6a62c4005f0e (current diff) 8a8dd0164b12 (diff)
children 4211cceb3813 c28452924144 38025d9ab757
files GUIWindow.cpp mm7_1.cpp mm7_2.cpp mm7_3.cpp mm7_4.cpp mm7_5.cpp stru346.h
diffstat 37 files changed, 1400 insertions(+), 2761 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/Actor.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -2046,7 +2046,7 @@
     else
       v8->uCurrentActionLength = uActionLength;
     v8->uCurrentActionTime = v7;
-    v8->uAIState = v7;
+    v8->uAIState = Standing;
     v8->vVelocity.z = v7;
     v8->vVelocity.y = v7;
     v8->vVelocity.x = v7;
@@ -2083,7 +2083,7 @@
   else
     v6->uCurrentActionLength = uActionLength;
   v6->uCurrentActionTime = v5;
-  v6->uAIState = v5;
+  v6->uAIState = Standing;
   v6->vVelocity.z = v5;
   v6->vVelocity.y = v5;
   v6->vVelocity.x = v5;
@@ -2099,7 +2099,7 @@
   v1 = &pActors[uActorID];
   v1->uCurrentActionLength = rand() % 128 + 128;
   v1->uCurrentActionTime = 0;
-  v1->uAIState = 0;
+  v1->uAIState = Standing;
   v1->vVelocity.z = 0;
   v1->vVelocity.y = 0;
   v1->vVelocity.x = 0;
@@ -2187,7 +2187,7 @@
       v17 = v24;
       v3->uCurrentActionLength = 8 * v16;
       v3->uCurrentActionTime = v13;
-      v3->uAIState = 2;
+      v3->uAIState = AttackingMelee;
       Actor::PlaySound(v17, 0);
       LODWORD(v18) = pMonsterStats->pInfos[v3->pMonsterInfo.uID].uRecoveryTime;
       v25 = pMonsterStats->pInfos[v3->pMonsterInfo.uID].uRecoveryTime;
@@ -2584,7 +2584,7 @@
     v14 = v22;
     v3->uCurrentActionLength = 8 * v13;
     v3->uCurrentActionTime = v10;
-    v3->uAIState = 18;
+    v3->uAIState = AttackingRanged4;
     Actor::PlaySound(v14, 0);
     v15 = pMonsterStats->pInfos[v3->pMonsterInfo.uID].uRecoveryTime;
     pDira = pMonsterStats->pInfos[v3->pMonsterInfo.uID].uRecoveryTime;
@@ -2609,9 +2609,9 @@
     {
       v3->uCurrentActionLength = 64;
       v3->uCurrentActionTime = v10;
-      v3->uAIState = 9;
+      v3->uAIState = Fidgeting;
       result = v3->UpdateAnimation();
-      v3->uAIState = 18;
+      v3->uAIState = AttackingRanged4;
     }
     else
     {
@@ -2696,7 +2696,7 @@
     v14 = v22;
     v3->uCurrentActionLength = 8 * v13;
     v3->uCurrentActionTime = v10;
-    v3->uAIState = 13;
+    v3->uAIState = AttackingRanged3;
     Actor::PlaySound(v14, 0);
     v15 = pMonsterStats->pInfos[v3->pMonsterInfo.uID].uRecoveryTime;
     pDira = pMonsterStats->pInfos[v3->pMonsterInfo.uID].uRecoveryTime;
@@ -2721,9 +2721,9 @@
     {
       v3->uCurrentActionLength = 64;
       v3->uCurrentActionTime = v10;
-      v3->uAIState = 9;
+      v3->uAIState = Fidgeting;
       result = v3->UpdateAnimation();
-      v3->uAIState = 13;
+      v3->uAIState = AttackingRanged3;
     }
     else
     {
@@ -2807,7 +2807,7 @@
     v14 = v21;
     v3->uCurrentActionLength = 8 * v13;
     v3->uCurrentActionTime = v10;
-    v3->uAIState = 12;
+    v3->uAIState = AttackingRanged2;
     Actor::PlaySound(v14, 0);
     LODWORD(v15) = pMonsterStats->pInfos[v3->pMonsterInfo.uID].uRecoveryTime;
     pDira = pMonsterStats->pInfos[v3->pMonsterInfo.uID].uRecoveryTime;
@@ -2911,7 +2911,7 @@
     v15 = v21;
     v3->uCurrentActionLength = 8 * v14;
     v3->uCurrentActionTime = v11;
-    v3->uAIState = 3;
+    v3->uAIState = AttackingRanged1;
     Actor::PlaySound(v15, 0);
     v16 = pMonsterStats->pInfos[v3->pMonsterInfo.uID].uRecoveryTime;
     pDira = pMonsterStats->pInfos[v3->pMonsterInfo.uID].uRecoveryTime;
@@ -3010,7 +3010,7 @@
   else
     v5->uCurrentActionLength = 0;
   v5->uCurrentActionTime = 0;
-  v5->uAIState = 1;
+  v5->uAIState = Tethered;
   if ( rand() % 100 < 2 )
     Actor::PlaySound(uActorID, 3u);
   v5->UpdateAnimation();
@@ -3119,7 +3119,7 @@
     v7 = v6[v4->pSpriteIDs[4]].uAnimLength;
     v8 = v11;
     v4->uCurrentActionTime = 0;
-    v4->uAIState = 8;
+    v4->uAIState = Stunned;
     v4->uCurrentActionLength = 8 * v7;
     Actor::PlaySound(v8, 2u);
     result = v4->UpdateAnimation();
@@ -3220,7 +3220,7 @@
   v2 = pSpriteFrameTable->pSpriteSFrames;
   v3 = 60 * v1->pSpriteIDs[5];
   v1->uCurrentActionTime = 0;
-  v1->uAIState = 4;
+  v1->uAIState = Dying;
   v1->uCurrentActionAnimation = 5;
   LOWORD(v3) = *(__int16 *)((char *)&v2->uAnimLength + v3);
   v1->sCurrentHP = 0;
@@ -3444,7 +3444,7 @@
   else
     v7->uCurrentActionLength = 128;
   v7->uPitchAngle = LOWORD(v10->uPitchAngle);
-  v7->uAIState = 6;
+  v7->uAIState = Pursuing;
   return v7->UpdateAnimation();
 }
 
@@ -3503,7 +3503,7 @@
       v9 = LOWORD(a4->uPitchAngle);
       v5->uCurrentActionTime = 0;
       v5->uPitchAngle = v9;
-      v5->uAIState = 7;
+      v5->uAIState = Fleeing;
       result = v5->UpdateAnimation();
     }
   }
@@ -3588,7 +3588,7 @@
   v14 = LOWORD(v10->uPitchAngle);
   v7->uCurrentActionTime = 0;
   v7->uPitchAngle = v14;
-  v7->uAIState = 6;
+  v7->uAIState = Pursuing;
   return v7->UpdateAnimation();
 }
 
@@ -3679,7 +3679,7 @@
   v16 = LOWORD(v9->uPitchAngle);
   v6->uCurrentActionTime = 0;
   v6->uPitchAngle = v16;
-  v6->uAIState = 6;
+  v6->uAIState = Pursuing;
   if ( rand() % 100 < 2 )
     Actor::PlaySound(v4, 2u);
   return v6->UpdateAnimation();
@@ -3949,7 +3949,7 @@
 //----- (0045976D) --------------------------------------------------------
 unsigned int Actor::UpdateAnimation()
 {
-  enum AIState state; // edx@1
+  AIState state; // edx@1
   unsigned int result; // eax@1
 
   state = (AIState)this->uAIState;
@@ -4030,7 +4030,7 @@
   this->uTetherDistance = 256;
   this->uActorRadius = 32;
   this->uActorHeight = 128;
-  this->uAIState = 0;
+  this->uAIState = Standing;
   this->uCurrentActionAnimation = 0;
   this->uMovementSpeed = 200;
   this->uCarriedItemID = 0;
@@ -4212,7 +4212,7 @@
   v20 = v18->uGroup;
   v8->uCurrentActionTime = 0;
   v8->uGroup = v20;
-  v8->uAIState = 17;
+  v8->uAIState = Summoned;
   v8->uCurrentActionLength = 256;
   v8->UpdateAnimation();
   if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor
--- a/Actor.h	Tue Oct 23 17:33:33 2012 +0600
+++ b/Actor.h	Tue Oct 23 17:34:20 2012 +0600
@@ -76,7 +76,7 @@
 };
 
 /*  264 */
-enum AIState : __int32
+enum AIState : unsigned __int16
 {
   Standing = 0x0,
   Tethered = 0x1,
@@ -256,7 +256,7 @@
   struct Vec3_short_ vInitialPosition;
   struct Vec3_short_ vGuardingPosition;
   unsigned __int16 uTetherDistance;
-  unsigned __int16 uAIState;
+  AIState uAIState;
   unsigned __int16 uCurrentActionAnimation;
   unsigned __int16 uCarriedItemID;
   char field_B6;
--- a/Bink_Smacker.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/Bink_Smacker.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -22,6 +22,7 @@
 void (__stdcall *smackw32_SmackBufferClose)(HSMACKBUF) = 0;
 void (__stdcall *smackw32_SmackBlitClose)(HSMACKBLIT) = 0;
 int  (__stdcall *smackw32_SmackBlitClear)(HSMACKBLIT, unsigned short *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, int) = 0;
+int  (__stdcall *smackw32_SmackGoto)(_SMACK *, long) = 0;
 void SMACKW32_DLL_Initialize()
 {
  HMODULE pDll = LoadLibraryW(L"SmackW32.dll");
@@ -42,6 +43,7 @@
  smackw32_SmackBufferClose = (void (__stdcall *)(HSMACKBUF))GetProcAddress(pDll, "_SmackBufferClose@4");
  smackw32_SmackBlitClose = (void (__stdcall *)(HSMACKBLIT))GetProcAddress(pDll, "_SmackBlitClose@4");
  smackw32_SmackBlitClear = (int (__stdcall *)(HSMACKBLIT, unsigned short *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, int))GetProcAddress(pDll, "_SmackBlitClear@32");
+ smackw32_SmackGoto = (int  (__stdcall *)(_SMACK *, long))GetProcAddress(pDll, "_SmackGoto@8");
 }
 
 
@@ -129,6 +131,10 @@
  return (smackw32_SmackBlitClear)(a1, pFrameData, uTargetSurfacePitch, uOutX, uOutY, uOutZ, uOutW, a8);
 }
 
+int __stdcall SmackGoto(_SMACK *a1, long a2)
+{
+ return (smackw32_SmackGoto)(a1, a2);
+}
 
 
 int __stdcall SmackBufferOpen(HWND a1, long a2, long a3, long a4, long a5, long a6)
@@ -144,12 +150,6 @@
 }
 
 
-int __stdcall SmackGoto(_SMACK *a1, long a2)
-{
- __asm int 3
- return 0;
-}
-
 // sub_4D83D0: using guessed type int __stdcall SmackBufferNewPalette(_DWORD, _DWORD, _DWORD);
 int __stdcall SmackBufferNewPalette(long a1, long a2, long a3)
 {
--- a/DecalBuilder.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/DecalBuilder.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -3,9 +3,9 @@
 #include "Time.h"
 #include "stru314.h"
 #include "Outdoor.h"
+#include "Log.h"
 
 #include "mm7_data.h"
-//#include "MM7.h"
 
 
 
@@ -16,16 +16,14 @@
 
 
 //----- (0043B570) --------------------------------------------------------
-double DecalBuilder_stru0::_43B570()
+double DecalBuilder_stru0::_43B570_get_color_mult_by_time()
 {
-  DecalBuilder_stru0 *v1; // esi@1
   double result; // st7@3
-
-  v1 = this;
-  if ( this->field_1C_flags & 1 )
+  
+  if (field_1C_flags & 1)
   {
-    if ( (double)(signed __int64)(this->field_20_time - pEventTimer->Time() + 384) * 0.0026041667 >= 0.0 )
-      result = (double)(signed __int64)(v1->field_20_time - pEventTimer->Time() + 384) * 0.0026041667;
+    if ((field_20_time - pEventTimer->Time() + 384) / 384.0 >= 0.0)
+      result = (field_20_time - pEventTimer->Time() + 384) / 384.0;
     else
       result = 0.0;
   }
@@ -229,7 +227,7 @@
       *(float *)&v37 = v21->z;
       v36 = v21->y;
       v35 = v21->x;
-      v22 = sub_43F5C8(a2, a9, v35, v36, *(float *)&v37);
+      v22 = _43F5C8_get_point_light_level_with_respect_to_lights(a2, a9, v35, v36, *(float *)&v37);
       v23 = v21->b;
       v24 = v21->x;
       v42 = v22;
@@ -275,11 +273,9 @@
   }
   return 1;
 }
-// AE4F88: using guessed type int dword_AE4F88;
-// AE5B90: using guessed type char static_init_flag__AE4F90_bit1__AE4F60_bit2;
 
 //----- (0049B790) --------------------------------------------------------
-char DecalBuilder::_49B790_build_decal_geometry(int a2, char a3, int a4, int a5, int a6, int a7, RenderVertexSoft *a8, stru314 *a9, signed int a10, RenderVertexSoft *a11, char uClipFlags)
+char DecalBuilder::_49B790_build_decal_geometry(int a2, char a3, int a4, int a5, int a6, unsigned int uColorMultiplier, RenderVertexSoft *a8, stru314 *a9, signed int a10, RenderVertexSoft *a11, char uClipFlags)
 {
   DecalBuilder *v12; // esi@1
   Decal *v13; // edi@2
@@ -384,7 +380,7 @@
     *((float *)v25 - 11) = *((float *)v25 - 11) - v28 * v18->field_4.z;
   }
   while ( v26 );
-  v13->field_C10 = a7;
+  v13->uColorMultiplier = uColorMultiplier;
   v40 = (unsigned int *)&v13->uNumVertices;
   v39 = v13->pVertices;
   v13->uNumVertices = 4;
@@ -714,214 +710,109 @@
 }
 
 //----- (0049C095) --------------------------------------------------------
-void DecalBuilder::DrawDecal(Decal *pDecal, float a2)
+void DecalBuilder::DrawDecal(Decal *pDecal, float z_bias)
 {
-  Decal *v3; // edi@1
-  double v4; // st7@3
-  double v5; // st7@5
-  int v6; // eax@5
-  unsigned __int8 v7; // zf@5
-  unsigned __int8 v8; // sf@5
-  char *v9; // esi@6
-  int v10; // ebx@6
-  int v11; // eax@8
-  int v12; // edx@8
-  int v13; // eax@8
-  int v14; // ecx@8
-  double v15; // st7@9
-  int v16; // eax@12
-  double v17; // st7@12
-  int v18; // eax@12
-  unsigned __int8 v19; // of@12
-  HRESULT v20; // eax@17
   signed int v21; // [sp+Ch] [bp-864h]@15
-  const char *v22; // [sp+10h] [bp-860h]@15
-  int v23; // [sp+14h] [bp-85Ch]@15
-  unsigned int v24; // [sp+18h] [bp-858h]@14
-  RenderVertexD3D3 hr[64]; // [sp+20h] [bp-850h]@6
-  double v26; // [sp+820h] [bp-50h]@8
-  double v27; // [sp+828h] [bp-48h]@8
-  double v28; // [sp+830h] [bp-40h]@8
-  int v29; // [sp+838h] [bp-38h]@8
-  int v30; // [sp+83Ch] [bp-34h]@8
-  __int64 v31; // [sp+840h] [bp-30h]@8
-  __int64 v32; // [sp+848h] [bp-28h]@8
-  __int64 v33; // [sp+850h] [bp-20h]@8
-  int v34; // [sp+858h] [bp-18h]@8
-  unsigned __int64 v35; // [sp+85Ch] [bp-14h]@8
-  float v36; // [sp+864h] [bp-Ch]@6
-  int v37; // [sp+868h] [bp-8h]@5
-  float v38; // [sp+86Ch] [bp-4h]@8
-  float thisa; // [sp+878h] [bp+8h]@5
+  RenderVertexD3D3 pVerticesD3D[64]; // [sp+20h] [bp-850h]@6
+
+  if (pDecal->uNumVertices < 3)
+  {
+    Log::Warning(L"Decal has < 3 vertices");
+    return;
+  }
 
-  v3 = pDecal;
-  if ( pDecal->uNumVertices >= 3 )
+  float color_mult;
+  if ( pDecal->field_C1C & 1 )
+    color_mult = 1.0;
+  else
+    color_mult = pDecal->field_C18->_43B570_get_color_mult_by_time();
+
+  for (uint i = 0; i < pDecal->uNumVertices; ++i)
   {
-    if ( pDecal->field_C1C & 1 )
-      v4 = 1.0;
-    else
-      v4 = pDecal->field_C18->_43B570();
-    thisa = v4;
-    v5 = get_shading_dist_mist();
-    v6 = 0;
-    v7 = v3->uNumVertices == 0;
-    v8 = v3->uNumVertices < 0;
-    v37 = 0;
-    if ( !(v8 | v7) )
-    {
-      v9 = (char *)&hr[0].pos.y;
-      v10 = (int)&v3->pVertices[0].vWorldViewPosition;
-      v36 = 1.0 / v5;
-      while ( 1 )
-      {
-        v11 = pRenderer->GetActorTintColor(*(float *)v10, v3->field_C14, v6, v6, (RenderBillboard *)v6);
-        LOBYTE(v12) = v11;
-        v33 = ((unsigned int)v11 >> 16) & 0xFFi64;
-        LOBYTE(v38) = BYTE2(v3->field_C10);
-        v38 = (double)v33 * 0.0039215689 * thisa * (double)LOBYTE(v38);
-        v28 = v38 + 6.7553994e15;
-        v31 = (unsigned __int16)v11 >> 8;
-        LODWORD(v38) = BYTE1(v3->field_C10);
-        v38 = (double)v31 * 0.0039215689 * thisa * (double)SLODWORD(v38);
-        v26 = v38 + 6.7553994e15;
-        v35 = __PAIR__(LODWORD(v28), LODWORD(v26));
-        v13 = v3->field_C10;
-        v32 = v12 & 0xFFi64;
-        v29 = (unsigned __int8)v13;
-        v30 = 0;
-        v38 = (double)v32 * 0.0039215689 * thisa * (double)(unsigned __int8)v13;
-        v27 = v38 + 6.7553994e15;
-        v34 = LODWORD(v27);
-        v14 = LODWORD(v27) | ((LODWORD(v26) | (LODWORD(v28) << 8)) << 8);
-        if ( a2 == 0.0 )
-        {
-          v15 = 1.0 - 1.0 / (v36 * *(float *)v10 * 1000.0);
-        }
-        else
-        {
-          v15 = 1.0 - 1.0 / (v36 * *(float *)v10 * 1000.0) - a2;
-          if ( v15 < 0.000099999997 )
-            v15 = 0.000099999997;
-        }
-        *((float *)v9 + 1) = v15;
-        v16 = *(int *)(v10 + 12);
-        ++v37;
-        v17 = 1.0 / *(float *)v10;
-        *((int *)v9 - 1) = v16;
-        *(int *)v9 = *(int *)(v10 + 16);
-        *((int *)v9 + 5) = *(int *)(v10 + 24);
-        *((int *)v9 + 6) = *(int *)(v10 + 28);
-        v18 = v37;
-        *((int *)v9 + 3) = v14;
-        *((int *)v9 + 4) = 0;
-        v10 += 48;
-        v9 += 32;
-        v19 = __OFSUB__(v18, v3->uNumVertices);
-        v8 = v18 - v3->uNumVertices < 0;
-        *((float *)v9 - 6) = v17;
-        if ( !(v8 ^ v19) )
-          break;
-        v6 = 0;
-      }
-      v6 = 0;
-    }
-    v24 = v6;
-    if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-    {
-      v21 = 28;
-    }
-    else
-    {
-      v21 = 16;
-    }
-    ErrD3D(pRenderer->pRenderD3D->pDevice->DrawPrimitive(
-            D3DPT_TRIANGLEFAN,
-            452,
-            hr,
-            v3->uNumVertices,
+    uint uTint = pRenderer->GetActorTintColor(pDecal->pVertices[i].vWorldViewPosition.x, pDecal->field_C14, 0, 0, nullptr);
+
+    uint uTintR = (uTint >> 16) & 0xFF,
+         uTintG = (uTint >> 8) & 0xFF,
+         uTintB = uTint & 0xFF;
+
+    uint uDecalColorMultR = (pDecal->uColorMultiplier >> 16) & 0xFF,
+         uDecalColorMultG = (pDecal->uColorMultiplier >> 8) & 0xFF,
+         uDecalColorMultB = pDecal->uColorMultiplier & 0xFF;
+
+    uint uFinalR = floorf(uTintR / 255.0 * color_mult * uDecalColorMultR + 0.0f),
+         uFinalG = floorf(uTintG / 255.0 * color_mult * uDecalColorMultG + 0.0f),
+         uFinalB = floorf(uTintB / 255.0 * color_mult * uDecalColorMultB + 0.0f);
+
+
+    float v15;
+    if (fabs(z_bias) < 1e-5)
+      v15 = 1.0 - 1.0 / ((1.0f / get_shading_dist_mist()) * pDecal->pVertices[i].vWorldViewPosition.x * 1000.0);
+     else
+     {
+      v15 = 1.0 - 1.0 / ((1.0f / get_shading_dist_mist()) * pDecal->pVertices[i].vWorldViewPosition.x * 1000.0) - z_bias;
+      if (v15 < 0.000099999997)
+        v15 = 0.000099999997;
+     }
+
+    pVerticesD3D[i].pos.z = v15;
+
+    pVerticesD3D[i].pos.x = pDecal->pVertices[i].vWorldViewProjX;
+    pVerticesD3D[i].pos.y = pDecal->pVertices[i].vWorldViewProjY;
+    pVerticesD3D[i].texcoord.x = pDecal->pVertices[i].u;
+    pVerticesD3D[i].texcoord.y = pDecal->pVertices[i].v;
+    pVerticesD3D[i].diffuse = (uFinalR << 16) | (uFinalG << 8) | uFinalB;
+    pVerticesD3D[i].specular = 0;
+    pVerticesD3D[i].rhw = 1.0 / pDecal->pVertices[i].vWorldViewPosition.x;
+  }
+
+  if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+    v21 = D3DDP_DONOTLIGHT | D3DDP_DONOTCLIP | D3DDP_DONOTUPDATEEXTENTS;
+  else
+    v21 = D3DDP_DONOTLIGHT;
+
+  ErrD3D(pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,
+            D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
+            pVerticesD3D,
+            pDecal->uNumVertices,
             v21));
-  }
 }
 
 //----- (0049C2CD) --------------------------------------------------------
-void DecalBuilder::DrawDecals(float a2)
+void DecalBuilder::DrawDecals(float z_bias)
 {
-  DecalBuilder *v2; // esi@1
-  signed int v3; // edi@1
-  Decal *v4; // ebx@2
-
-  v2 = this;
-  v3 = 0;
-  if ( (signed int)this->std__vector_pDecals_size > 0 )
-  {
-    v4 = this->std__vector_pDecals;
-    do
-    {
-      DrawDecal(v4, a2);
-      ++v3;
-      ++v4;
-    }
-    while ( v3 < (signed int)v2->std__vector_pDecals_size );
-  }
+  for (uint i = 0; i < std__vector_pDecals_size; ++i)
+    DrawDecal(std__vector_pDecals + i, z_bias);
 }
 
 //----- (0049C304) --------------------------------------------------------
 void DecalBuilder::DrawBloodsplats()
 {
-  unsigned int v1; // ebx@0
-  int v2; // esi@0
-  char v3; // zf@1
-  HRESULT v4; // eax@4
-  HRESULT v5; // eax@4
-  HRESULT v6; // eax@4
-  HRESULT v7; // eax@4
-  HRESULT v8; // eax@4
-  HRESULT v9; // eax@4
-  HRESULT v10; // eax@4
-  char *v11; // eax@4
-  //IDirect3DDevice3Vtbl *v12; // ebx@6
-  int v13; // ST6C_4@6
-  HRESULT v14; // eax@6
-  HRESULT v15; // eax@6
-  HRESULT v16; // eax@6
-  HRESULT v17; // eax@6
-  HRESULT v18; // eax@6
-  HRESULT v19; // eax@6
-  char thisa; // [sp+80h] [bp-8h]@4
-  DecalBuilder *v21; // [sp+84h] [bp-4h]@1
+  if (!std__vector_pDecals_size)
+    return;
+
+  if (pRenderer->bUsingSpecular)
+    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 3));
 
-  v3 = this->std__vector_pDecals_size == 0;
-  v21 = this;
-  if ( !v3 )
-  {
-    if ( pRenderer->bUsingSpecular )
-      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 3));
-
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 1));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 0));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1u));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 2u));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 0));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 1));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 0));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 2u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 0));
 
-    v11 = (char *)std__string_AE5B94.c_str();
-    if ( !std__string_AE5B94.size() )
-      v11 = (char *)&dword_4D86F0;
-    //v12 = pRenderer->pRenderD3D->pDevice->lpVtbl;
-    v13 = (int)pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr(v11);
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetTexture(0, (IDirect3DTexture2 *)v13));
+  auto pTex = pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("hwsplat04");
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetTexture(0, pTex));
+ 
+  DrawDecals(0.00039999999);
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 2u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 0));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1u));
 
-    v21->DrawDecals(0.00039999999);
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 2u));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1u));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 0));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1u));
-
-    if ( pRenderer->bUsingSpecular )
-      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1u));
-  }
+  if (pRenderer->bUsingSpecular)
+    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1u));
 }
 
 //----- (0049C550) --------------------------------------------------------
--- a/DecalBuilder.h	Tue Oct 23 17:33:33 2012 +0600
+++ b/DecalBuilder.h	Tue Oct 23 17:34:20 2012 +0600
@@ -5,7 +5,7 @@
 #pragma pack(push, 1)
 struct DecalBuilder_stru0
 {
-  double _43B570();
+  double _43B570_get_color_mult_by_time();
 
   int field_0;
   int field_4;
@@ -47,7 +47,7 @@
   __int16 field_C0A;
   __int16 field_C0C;
   __int16 field_C0E;
-  int field_C10;
+  uint uColorMultiplier;
   int field_C14;
   DecalBuilder_stru0 *field_C18;
   int field_C1C;
@@ -92,12 +92,12 @@
   bool AddBloodsplat(float x, float y, float z, float r, float g, float b, float radius, int a8, int a9);
   void Reset(unsigned int bPreserveBloodsplats);
   char ApplyDecals(int a2, char a3, struct stru154 *a4, int a5, struct RenderVertexSoft *a6, int a7, char a8, int a9);
-  char _49B790_build_decal_geometry(int a2, char a3, int a4, int a5, int a6, int a7, struct RenderVertexSoft *a8, struct stru314 *a9, signed int a10, struct RenderVertexSoft *a11, char uClipFlags);
+  char _49B790_build_decal_geometry(int a2, char a3, int a4, int a5, int a6, unsigned int uColorMultiplier, struct RenderVertexSoft *a8, struct stru314 *a9, signed int a10, struct RenderVertexSoft *a11, char uClipFlags);
   char ApplyBloodsplatDecals_IndoorFace(unsigned int uFaceID);
   char ApplyDecals_OutdoorFace(ODMFace *pFace);
   bool _49BE8A(struct stru148 *a2, float a3, int a4, struct RenderVertexSoft *a5, unsigned int uStripType, char a7);
-  void DrawDecal(Decal *pDecal, float a2);
-  void DrawDecals(float a2);
+  void DrawDecal(Decal *pDecal, float z_bias);
+  void DrawDecals(float z_bias);
   void DrawBloodsplats();
   void DrawDecalDebugOutlines();
 
--- a/GUIWindow.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/GUIWindow.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -254,10 +254,10 @@
   }
   pRenderer->DrawTextureTransparent(v1->uFrameX + 24, v1->uFrameY + 24, v13);
   v16 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0x9Bu);
-  sprintfex(pTmpBuf, format_4E2DC8, v16);
+  sprintfex(pTmpBuf, "\xC" "00000\n", v16);
   sprintfex(pTmpBuf2, pGlobalTXT_LocalizationStrings[429], pPlayer->pName, pClassNames[pPlayer->uClass]);
   strcat(pTmpBuf, pTmpBuf2);
-  strcat(pTmpBuf, string_4E3294);
+  strcat(pTmpBuf, "\xC" "00000\n");
   v17 = pPlayer->GetMaxHealth();
   v18 = pPlayer->sHealth;
   v19 = pPlayer->GetMaxHealth();
--- a/Game.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/Game.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -48,8 +48,6 @@
 //----- (0044103C) --------------------------------------------------------
 void Game::Draw()
 {
-  Render *v0; // esi@3
-  int _null; // ebx@6
   float v2; // ST24_4@11
   //double v3; // ST28_8@11
   int v4; // edi@26
@@ -71,14 +69,13 @@
   pIndoorCamera->Initialize2();
   pIndoorCameraD3D->CreateWorldMatrixAndSomeStuff();
   pIndoorCameraD3D->_4374E8_ProllyBuildFrustrum();
-  //v0 = &pRenderer;
+
   if ( pVideoPlayer->AnyMovieLoaded() )
   {
-    _null = 0;
     if ( pRenderer->pRenderD3D )
       goto LABEL_22;
-    pRenderer->SetGameRenderStates();
-    pMouse->_469E3B();
+    pRenderer->BeginSceneD3D();
+    pMouse->DrawCursorToTarget();
   }
   else
   {
@@ -91,10 +88,10 @@
     pParty->vPrevPosition.z = pParty->vPosition.z;
     pParty->sPrevRotationX = pParty->sRotationX;
     pParty->sPrevEyelevel = pParty->sEyelevel;
-    pRenderer->SetGameRenderStates();
-    _null = 0;
+    pRenderer->BeginSceneD3D();
+
     if ( !pRenderer->pRenderD3D )
-      pMouse->_469E3B();
+      pMouse->DrawCursorToTarget();
     if ( !sub_4226C2() || viewparams->field_48 == 1 )
     {
       if ( pRenderer->pRenderD3D )
@@ -105,15 +102,15 @@
         pRenderer->field_1036A8_bitmapid = floorf(v2 + 0.5f);
       }
 
-      if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
+      if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
         pIndoor->Draw();
-      else if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-          pOutdoor->Draw();
+      else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+        pOutdoor->Draw();
 
-      if ( pRenderer->pRenderD3D )
+      if (pRenderer->pRenderD3D)
       {
         pDecalBuilder->DrawBloodsplats();
-        if ( pRenderer->pRenderD3D )
+        if (pRenderer->pRenderD3D)
           pGame->pLightmapBuilder->DrawLightmaps(2);
       }
     }
@@ -121,44 +118,43 @@
   pRenderer->DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene();
 LABEL_22:
   pRenderer->BeginScene();
-  if ( pRenderer->pRenderD3D != (RenderD3D *)_null )
-    pMouse->_469E3B();
-  if ( pOtherOverlayList->field_3EC != _null )
+  if (pRenderer->pRenderD3D)
+    pMouse->DrawCursorToTarget();
+  if (pOtherOverlayList->field_3EC)
     viewparams->bRedrawGameUI = 1;
   v4 = viewparams->bRedrawGameUI;
   GameUI_DrawStatusBar();
-  if ( viewparams->bRedrawGameUI == _null )
+  if (!viewparams->bRedrawGameUI)
   {
-    //nullsub_1();
     GameUI_DrawRightPanelItems();
   }
   else
   {
     GameUI_DrawRightPanelFrames();
     GameUI_DrawStatusBar_2();
-    viewparams->bRedrawGameUI = _null;
+    viewparams->bRedrawGameUI = false;
   }
-  if ( pVideoPlayer->pSmackerMovie == (_SMACK *)_null )
+  if (!pVideoPlayer->pSmackerMovie)
   {
     GameUI_DrawMinimap(0x1E8u, 0x10u, 0x271u, 0x85u, viewparams->uMinimapZoom, pParty->uFlags & 2);
-    if ( v4 != _null )
+    if (v4)
     {
-      if ( !sub_4226C2() && pRenderer->pRenderD3D != (RenderD3D *)_null )
+      if ( !sub_4226C2() && pRenderer->pRenderD3D)
         pRenderer->FillRect2(
-          _null,
+          0,
           pViewport->uViewportX,
           pViewport->uViewportY,
           pViewport->uViewportZ - pViewport->uViewportX,
           pViewport->uViewportW - pViewport->uViewportY + 1,
           LOWORD(pRenderer->uTargetGMask) | LOWORD(pRenderer->uTargetBMask));
-      viewparams->field_48 = _null;
+      viewparams->field_48 = 0;
     }
   }
   v5 = pOtherOverlayList->field_3EC;
-  pOtherOverlayList->field_3EC = _null;
+  pOtherOverlayList->field_3EC = 0;
   viewparams->bRedrawGameUI = v5;
   GameUI_DrawPartySpells();
-  if ( v4 != _null || pParty->pHirelings[0].evtc != _null || pParty->pHirelings[1].evtc != _null )
+  if (v4 || pParty->pHirelings[0].evtc || pParty->pHirelings[1].evtc )
     DrawHiredNPCs();
   GameUI_DrawPortraits(v4);
   GameUI_DrawLifeManaBars();
@@ -174,8 +170,8 @@
   GUI_UpdateWindows();
   pParty->_4909F4();
   ++stru_51076C.field_8;
-  dword_5B5924 = _null;
-  if ( v4 != _null )
+  dword_5B5924 = 0;
+  if (v4)
     pMouse->field_14 = 1;
   pMouse->_469EA4();
   pMouse->DrawCursor();
@@ -184,7 +180,6 @@
   pRenderer->Present();
   pParty->uFlags &= 0xFFFFFFFDu;
 }
-// 5B5924: using guessed type int dword_5B5924;
 
 
 //----- (0047A815) --------------------------------------------------------
@@ -293,7 +288,7 @@
       if ( pVideoPlayer->pSmackerMovie && !SmackWait(pVideoPlayer->pSmackerMovie) )
       {
         pRenderer->BeginScene();
-        pMouse->_469E3B();
+        pMouse->DrawCursorToTarget();
         pVideoPlayer->SmackUpdatePalette(pVideoPlayer->hWindow);
         pMouse->_469EA4();
         pRenderer->EndScene();
@@ -301,7 +296,7 @@
       if ( pVideoPlayer->pBinkMovie && !BinkWait(pVideoPlayer->pBinkMovie) )
       {
         pRenderer->BeginScene();
-        pMouse->_469E3B();
+        pMouse->DrawCursorToTarget();
         pVideoPlayer->BinkUpdatePalette(pVideoPlayer->hWindow);
         pMouse->_469EA4();
         pRenderer->EndScene();
@@ -495,33 +490,19 @@
 
 
 //----- (0044F192) --------------------------------------------------------
-void Game::PushStru165s()
+void Game::PrepareBloodsplats()
 {
-  Game *v1; // edi@1
-  int v2; // ebx@1
-  float *v3; // esi@2
-
-  auto a1 = this;
-  v1 = a1;
-  v2 = 0;
-  if ( a1->array_708_size > 0 )
+  for (uint i = 0; i < uNumBloodsplats; ++i)
   {
-    v3 = &a1->array_708[0].flt_10;
-    do
-    {
-      pBloodsplatContainer->AddBloodsplat(
-        *(v3 - 4),
-        *(v3 - 3),
-        *(v3 - 2),
-        v3[2],
-        (signed __int64)*(v3 - 1),
-        (signed __int64)*v3,
-        (signed __int64)v3[1]);
-      ++v2;
-      v3 += 7;
-    }
-    while ( v2 < v1->array_708_size );
-  }
+    pBloodsplatContainer->AddBloodsplat(
+        pBloodsplats[i].x,
+        pBloodsplats[i].y,
+        pBloodsplats[i].z,
+        pBloodsplats[i].radius,
+        pBloodsplats[i].r,
+        pBloodsplats[i].g,
+        pBloodsplats[i].b);
+   }
 }
 
 
@@ -562,7 +543,7 @@
 
   if ( !(uFlags & 0x40) )
   {
-    array_708_size = 0;
+    uNumBloodsplats = 0;
     field_E0C = 0;
   }
 }
@@ -593,7 +574,7 @@
 //----- (0044EEA7) --------------------------------------------------------
 bool Game::_44EEA7()
 {
-  Game *v1; // esi@1
+  //Game *v1; // esi@1
   double v2; // st7@2
   float depth; // ST00_4@9
   bool result; // eax@9
@@ -606,7 +587,7 @@
   stru157 *v11; // [sp+14h] [bp-14h]@2
   POINT a2; // [sp+20h] [bp-8h]@1
 
-  v1 = this;
+  //v1 = this;
   ++qword_5C6DF0;
   pParticleEngine->UpdateParticles();
   pMouseInstance->GetCursorPos(&a2);
@@ -621,7 +602,7 @@
   }
   else
   {
-    if ( v1->uFlags2 & 0x10 )
+    if ( uFlags2 & 0x10 )
     {
       v11 = &a5;
       v10 = &stru_F93E1C;
@@ -650,8 +631,8 @@
   depth = v2;
 
   PickMouse(depth, y, x, v9, v10, v11);
-  v1->pLightmapBuilder->std__vector_000004_size = 0;
-  v1->pLightmapBuilder->std__vector_183808_size = 0;
+  pLightmapBuilder->std__vector_000004_size = 0;
+  pLightmapBuilder->std__vector_183808_size = 0;
   pDecalBuilder->std__vector_pDecals_size = 0;
   pDecalBuilder->field_308008 = 0;
   result = _44F07B();
@@ -662,7 +643,7 @@
     if ( pRenderer->pRenderD3D && uCurrentlyLoadedLevelType == LEVEL_Outdoor)
     {
       v5 = GetLevelFogColor();
-      LODWORD(pRenderer->uFogColor) = v5 & 0xFFFFFF;
+      pRenderer->uFogColor = v5 & 0xFFFFFF;
     }
     if (uFlags & 0x0400)
       uFlags2 |= 0x01;
@@ -671,24 +652,20 @@
       uFlags2 |= 0x01;
       field_E10 = qword_5C6DF0;
     }
-    v6 = qword_5C6DF0 - v1->field_E10;
-    if ( qword_5C6DF0 - v1->field_E10 == 1 )
-      v1->uFlags2 |= v6;
-    if ( v1->uNumStationaryLights_in_pStationaryLightsStack != uNumStationaryLightsApplied )
+    v6 = qword_5C6DF0 - field_E10;
+    if ( qword_5C6DF0 - field_E10 == 1 )
+      uFlags2 |= v6;
+    if (uNumStationaryLights_in_pStationaryLightsStack != uNumStationaryLightsApplied )
     {
-      v1->uFlags2 |= 1u;
-      v1->uNumStationaryLights_in_pStationaryLightsStack = uNumStationaryLightsApplied;
+      uFlags2 |= 1u;
+      uNumStationaryLights_in_pStationaryLightsStack = uNumStationaryLightsApplied;
     }
     _44E904();
     LOBYTE(result) = 1;
   }
   return result;
 }
-// 519AB4: using guessed type int uNumStationaryLightsApplied;
-// 5C6DEC: using guessed type char static_sub_44EEA7_byte_5C6DEC__init_flag;
-// 5C6DF0: using guessed type __int64 qword_5C6DF0;
-// F93E1C: using guessed type stru157 stru_F93E1C;
-// F93E30: using guessed type stru157 stru_F93E30;
+
 
 //----- (0044EDE4) --------------------------------------------------------
 bool Game::_44EDE4(BLVFace *pFace, int *a3)
@@ -913,7 +890,7 @@
 Game::Game()
 {
   uNumStationaryLights = 0;
-  array_708_size = 0;
+  uNumBloodsplats = 0;
   field_E0C = 0;
   field_E10 = 0;
   uNumStationaryLights_in_pStationaryLightsStack = 0;
@@ -925,7 +902,7 @@
 
   pThreadWardInstance = new ThreadWard;
   pParticleEngine = new ParticleEngine;
-  pMouseInstance = new Mouse(pThreadWardInstance);
+  pMouse = pMouseInstance = new Mouse(pThreadWardInstance);
   pLightmapBuilder = new LightmapBuilder;
   pVisInstance = new Vis;
   pStru6Instance = new stru6;
@@ -985,7 +962,7 @@
 //----- (0044E904) --------------------------------------------------------
 void Game::_44E904()
 {
-  Game *v1; // esi@1
+  //Game *v1; // esi@1
   unsigned __int64 v2; // qax@1
   unsigned int v3; // ecx@1
   int v4; // edi@1
@@ -994,13 +971,13 @@
   double v7; // st7@15
   signed __int64 v8; // [sp+Ch] [bp-8h]@1
 
-  v1 = this;
+  //v1 = this;
   v2 = pEventTimer->Time();
-  v4 = (v2 - v1->uSomeGammaStartTime) >> 32;
-  v3 = v2 - LODWORD(v1->uSomeGammaStartTime);
-  v8 = v2 - v1->uSomeGammaStartTime;
+  v4 = (v2 - uSomeGammaStartTime) >> 32;
+  v3 = v2 - LODWORD(uSomeGammaStartTime);
+  v8 = v2 - uSomeGammaStartTime;
   if ( v4 < 0
-    || SHIDWORD(v2) < ((unsigned int)v2 < LODWORD(v1->uSomeGammaStartTime)) + HIDWORD(v1->uSomeGammaStartTime) | v4 == 0
+    || SHIDWORD(v2) < ((unsigned int)v2 < LODWORD(uSomeGammaStartTime)) + HIDWORD(uSomeGammaStartTime) | v4 == 0
     && v3 <= 0x80 )
   {
     if ( v4 > 0 || v4 >= 0 )
@@ -1010,25 +987,25 @@
   }
   else
   {
-    if ( v1->uSomeGammaDeltaTime )
+    if ( uSomeGammaDeltaTime )
     {
-      LODWORD(v1->uSomeGammaDeltaTime) = 0;
-      HIDWORD(v1->uSomeGammaDeltaTime) = 0;
+      LODWORD(uSomeGammaDeltaTime) = 0;
+      HIDWORD(uSomeGammaDeltaTime) = 0;
     }
     else
     {
-      LODWORD(v1->uSomeGammaDeltaTime) = v3;
-      HIDWORD(v1->uSomeGammaDeltaTime) = v4;
+      LODWORD(uSomeGammaDeltaTime) = v3;
+      HIDWORD(uSomeGammaDeltaTime) = v4;
     }
     v5 = __CFADD__(v3, -128);
     v3 -= 128;
     v4 = v5 + v4 - 1;
   }
-  v1->uSomeGammaStartTime = v2;
+  uSomeGammaStartTime = v2;
   v8 = __PAIR__(v4, v3);
 LABEL_12:
-  if ( v1->uSomeGammaDeltaTime )
-    v6 = (double)(signed __int64)(v1->uSomeGammaDeltaTime - __PAIR__(v4, v3));
+  if ( uSomeGammaDeltaTime )
+    v6 = (double)(signed __int64)(uSomeGammaDeltaTime - __PAIR__(v4, v3));
   else
     v6 = (double)v8;
   v7 = v6 * 0.0078125;
@@ -1042,9 +1019,9 @@
     v7 = 1.0;
   }
   if ( pRenderer->pRenderD3D )
-    v1->_E28_timed_gamma_strength = v7;
+    _E28_timed_gamma_strength = v7;
   else
-    v1->_E28_timed_gamma_strength = (1.0 - 0.5) * v7 + 0.5;
+    _E28_timed_gamma_strength = (1.0 - 0.5) * v7 + 0.5;
 }
 
 //----- (0044EA17) --------------------------------------------------------
--- a/Game.h	Tue Oct 23 17:33:33 2012 +0600
+++ b/Game.h	Tue Oct 23 17:34:20 2012 +0600
@@ -61,15 +61,16 @@
 
 /*  279 */
 #pragma pack(push, 1)
-struct Game_stru1
+//Game_stru1
+struct Game_Bloodsplat
 {
-  float flt_0;
-  float flt_4;
-  float flt_8;
-  float flt_C;
-  float flt_10;
-  float flt_14;
-  float flt_18;
+  float x;
+  float y;
+  float z;
+  float r;
+  float g;
+  float b;
+  float radius;
 };
 #pragma pack(pop)
 
@@ -100,7 +101,7 @@
   void ToggleFlags2(unsigned int uFlag);
   void _44F0FD();
   void PushStationaryLights(int a2);
-  void PushStru165s();
+  void PrepareBloodsplats();
   void Deinitialize();
   void Loop();
   void DrawParticles();
@@ -116,7 +117,7 @@
   Game__StationaryLight pStationaryLights[25];
   char field_2C0[1092];
   unsigned int uNumStationaryLights;
-  Game_stru1 array_708[20];
+  Game_Bloodsplat pBloodsplats[20];
   int field_938;
   int field_93C;
   int field_940;
@@ -136,7 +137,7 @@
   int field_978;
   Game_stru0 stru_97C;
   char field_98C[1148];
-  int array_708_size;
+  int uNumBloodsplats;
   int field_E0C;
   __int64 field_E10;
   int uNumStationaryLights_in_pStationaryLightsStack;
--- a/Indoor.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/Indoor.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -48,7 +48,7 @@
 stru337 stru_F81018;
 stru167_wrap array_5118E8;
 stru170_stru2 stru_F8A590;
-stru170 *pStru170; // idb
+stru170 *pStru170 = new stru170; // idb
 stru141 stru_721530;
 stru352 stru_F83B80[480];
 
@@ -123,13 +123,13 @@
     if ( v8->uNumDecorations > 0 )
     {
       do
-        PrepareDecorationsRenderList_BLV((signed __int16)v9[v12++], v7);
+        PrepareDecorationsRenderList_BLV(v9[v12++], v7);
       while ( v12 < v8->uNumDecorations );
     }
     v6 = i + 1;
   }
   MessWithBillboards_BLV();
-  pGame->PushStru165s();
+  pGame->PrepareBloodsplats();
 }
 
 
@@ -4167,8 +4167,8 @@
       v0->vVelocity.x = 0;
       if ( BYTE2(v17[v18].uAttributes) & 0x40 )
       {
-        if ( v0->uAIState == 5 )
-          v0->uAIState = 11;
+        if (v0->uAIState == Dead)
+          v0->uAIState = Removed;
       }
 LABEL_123:
       ++v63;
@@ -4259,9 +4259,9 @@
         v33 = _46ED1B_collide_against_floor(v30, v31, v32, &stru_721530.uSectorID, &v60);
         v34 = pIndoor->pFaces[v60].uAttributes;
         v35 = v34 & 0x400000;
-        if ( v35 && v0->uAIState == 5 )
+        if (v35 && v0->uAIState == Dead)
         {
-          v0->uAIState = 11;
+          v0->uAIState = Removed;
           goto LABEL_120;
         }
         if ( v59 != v22 || v62 != v22 || v35 == v22 )
--- a/Indoor_stuff.h	Tue Oct 23 17:33:33 2012 +0600
+++ b/Indoor_stuff.h	Tue Oct 23 17:34:20 2012 +0600
@@ -74,11 +74,14 @@
    // _eh_vector_constructor_iterator_(field_FA8, 2252, 150,
    //    (void (__thiscall *)(void *))stru170_stru0::stru170_stru0,
    //    (void (__thiscall *)(void *))stru170_stru0::dtor);
+    uNumFaceIDs = 0;
+    std__vector_000FA8 = 0;
+    field_53730 = 0;
   }
 
   void _4AFB86(int a2, unsigned int uFaceID);
   void _4B0EA8(signed int a2, unsigned int uFaceID);
-  int RenderWalls();
+  void RenderWalls();
 
   unsigned int uNumFaceIDs;
   __int16 pFaceIDs[150];
@@ -108,11 +111,11 @@
   char field_3;
   char field_4;
   char field_5;
-  __int16 field_6;
-  __int16 field_8;
-  __int16 field_A;
-  __int16 field_C;
-  __int16 field_E;
+  __int16 field_6_rnd_value;
+  __int16 field_8_rnd_value;
+  __int16 field_A_rnd_value;
+  __int16 field_C_time_left;
+  __int16 field_E_time_to_live;
   char field_10;
   char field_11;
   char field_12;
--- a/LOD.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/LOD.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -585,13 +585,13 @@
   v49 = v7;
   v69 = v3->uTargetPitch;
   pTarget = v3->pTarget;
-  v57 = v3->field_28;
+  v57 = v3->sZValue;
   v61 = v3->pPalette;
   v9 = (v6 * this->uWidth + 32768) >> 16;
-  v72 = v3->field_C;
+  v72 = v3->uScreenSpaceY;
   result = (v5 * v7 + 32768) >> 16;
   v10 = (int *)(v72 - result + 1);
-  v11 = v3->field_8 - (v9 >> 1) + 1;
+  v11 = v3->uScreenSpaceX - (v9 >> 1) + 1;
   v65 = v72 - result + 1;
   v59 = v11 + v9 - 1;
   if ( BYTE1(v3->uFlags) & 8 )
@@ -602,7 +602,7 @@
   }
   v12 = v72;
   pTargetZ = v10;
-  v75 = v3->field_8 - (v9 >> 1) + 1;
+  v75 = v3->uScreenSpaceX - (v9 >> 1) + 1;
   v79 = v11 + v9 - 1;
   if ( !(v3->uFlags & 8) )
   {
@@ -881,7 +881,7 @@
   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 )
+  for ( i = v4 * a2->uScreenSpaceY - (this->uWidth >> 1) + a2->uScreenSpaceX + 1; v5 >= 0; --v5 )
   {
     v6 = &this->pSpriteLines[v5];
     v7 = LOWORD(v6->dword_0);
--- a/LightmapBuilder.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/LightmapBuilder.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -2,6 +2,7 @@
 #include "Game.h"
 #include "stru314.h"
 #include "Outdoor.h"
+#include "Log.h"
 
 #include "mm7_data.h"
 
@@ -203,7 +204,7 @@
 }
 
 //----- (0045BE86) --------------------------------------------------------
-char LightmapBuilder::_45BE86_build_light_polygon(int arg0, float a4, int arg8, float a5, int uLightType, stru314 *a7, signed int a2, RenderVertexSoft *a9, char uClipFlag)
+char LightmapBuilder::_45BE86_build_light_polygon(int arg0, float a4, unsigned int uColorMask, float a5, int uLightType, stru314 *a7, signed int a2, RenderVertexSoft *a9, char uClipFlag)
 {
   LightmapBuilder *v10; // esi@1
   Lightmap *v11; // edi@3
@@ -279,13 +280,13 @@
   v10->flt_3C8C28 = v13;
   v14 = a7;
   v66 = 1.0 / a4;
-  v10->flt_3C8C2C = 1.0 - (a4 - v13) * v66;
+  v10->flt_3C8C2C_lightmaps_brightness = 1.0 - (a4 - v13) * v66;
   v11->field_C08 = (signed __int64)((double)*(signed int *)arg0 - a5 * v14->field_4.x);
   v11->field_C0A = (signed __int64)((double)*(signed int *)(arg0 + 4) - a5 * v14->field_4.y);
   v15 = a4;
   v11->field_C0C = (signed __int64)((double)*(signed int *)(arg0 + 8) - a5 * v14->field_4.z);
   pLightmapVertices = v11->pVertices;
-  v17 = v15 * v10->flt_3C8C2C;
+  v17 = v15 * v10->flt_3C8C2C_lightmaps_brightness;
   pLightmapVertices_ = (int)v11->pVertices;
   v10->flt_3C8C30 = v17;
   v10->flt_3C8C0C = v17 * v14->field_10.x;
@@ -337,7 +338,7 @@
     *((float *)v19 - 11) = *((float *)v19 - 11) - v24 * v14->field_4.z;
   }
   while ( v22 );
-  v11->field_C10 = arg8;
+  v11->uColorMask = uColorMask;
   v11->uNumVertices = 4;
   if ( pGame->uFlags2 & 4 )
   {
@@ -347,16 +348,16 @@
     LODWORD(a5) = v11->field_C0A;
     v27 = v11->field_C08;
     a5 = (double)SLODWORD(a5);
-    arg8 = v27;
+    uColorMask = v27;
     v28 = (double)v27;
     v61 = a5;
     v60 = v28;
     v62 = v26;
-    *(float *)&arg8 = (double)*(signed int *)(arg0 + 8);
+    *(float *)&uColorMask = (double)*(signed int *)(arg0 + 8);
     arg0b = (double)*(signed int *)(arg0 + 4);
     v29 = (double)*(signed int *)v25 - v28;
     v30 = arg0b - a5;
-    a5 = *(float *)&arg8 - v26;
+    a5 = *(float *)&uColorMask - v26;
     a1.x = v29;
     a1.z = a5;
     a1.y = v30;
@@ -369,10 +370,10 @@
     arg0c = floorf(v61 + 0.5f);
     //v64 = v60 + 6.7553994e15;
     //arg8 = LODWORD(v64);
-    arg8 = floorf(v60 + 0.5f);
+    uColorMask = floorf(v60 + 0.5f);
     auto v64 /*HIDWORD(v64)*/ = abs(*(int *)(v25 + 8) - (signed)LODWORD(a5));
     arg0a = abs(*(int *)(v25 + 4) - arg0c);
-    v31 = abs(*(int *)v25 - arg8);
+    v31 = abs(*(int *)v25 - (int)uColorMask);
     LODWORD(a5) = v31;
     v32 = arg0a;
     v33 = v64;//HIDWORD(v64);
@@ -422,11 +423,11 @@
     }
     v14 = a7;
     pLightmapVertices = (RenderVertexSoft *)pLightmapVertices_;
-    v11->flt_C14 = v40 - a4 * v40;
+    v11->fBrightness = v40 - a4 * v40;
   }
   else
   {
-    v11->flt_C14 = v10->flt_3C8C2C;
+    v11->fBrightness = v10->flt_3C8C2C_lightmaps_brightness;
   }
   v41 = v14->field_4.z;
   v42 = pGame->pStru9Instance;
@@ -1783,7 +1784,7 @@
   char v3; // zf@1
   IDirect3DDevice3 *v4; // eax@2
   HRESULT v5; // eax@2
-  char *v6; // eax@2
+  //char *v6; // eax@2
   struct IDirect3DTexture2 *v7; // edi@4
   HRESULT v8; // eax@8
   HRESULT v9; // eax@8
@@ -1800,13 +1801,13 @@
   HRESULT v20; // eax@21
   IDirect3DDevice3 *v21; // eax@21
   HRESULT v22; // eax@21
-  IDirect3DDevice3 *v23; // eax@23
+  //IDirect3DDevice3 *v23; // eax@23
   std::string v25; // [sp+44h] [bp-44h]@12
   signed int v26; // [sp+48h] [bp-40h]@21
   signed int v27; // [sp+4Ch] [bp-3Ch]@21
   Lightmap *v28; // [sp+50h] [bp-38h]@2
   int v29; // [sp+54h] [bp-34h]@2
-  float v30; // [sp+58h] [bp-30h]@2
+  //float v30; // [sp+58h] [bp-30h]@2
   int arg4; // [sp+68h] [bp-20h]@8
   float v32; // [sp+6Ch] [bp-1Ch]@8
   float v33; // [sp+70h] [bp-18h]@8
@@ -1820,13 +1821,13 @@
   LODWORD(v38) = (int)this;
   if ( !v3 )
   {
-    v30 = 0.0;
+    //v30 = 0.0;
     //v4 = pRenderer->pRenderD3D->pDevice;
     ErrD3D(v4->SetTextureStageState(0, D3DTSS_ADDRESS, 3u));
-    v6 = (char *)stru_69BD44.c_str();
-    if ( !stru_69BD44.c_str() )
-      v6 = (char *)&dword_4D86F0;
-    v7 = pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr(v6);
+    //v6 = (char *)stru_69BD44.c_str();
+    //if ( !stru_69BD44.c_str() )
+    //  v6 = (char *)&dword_4D86F0;
+    v7 = pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("effpar03");
     if ( pRenderer->bUsingSpecular )
       pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0);
     if ( !byte_4D864C || !(pGame->uFlags & 1) )
@@ -1892,253 +1893,134 @@
       //LODWORD(v30) = 1;
       //v29 = 28;
       //v28 = (Lightmap *)pRenderer->pRenderD3D->pDevice;
-      pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1);
-      v30 = pRenderer->uFogColor;
-      v23 = pRenderer->pRenderD3D->pDevice;
+      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1));
+      //v30 = pRenderer->uFogColor;
+      //v23 = pRenderer->pRenderD3D->pDevice;
       //v29 = 34;
       //v28 = (Lightmap *)v23;
-      v23->SetRenderState(D3DRENDERSTATE_FOGCOLOR, LODWORD(pRenderer->uFogColor));
+      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, pRenderer->uFogColor));
       //v28 = (Lightmap *)pRenderer->pRenderD3D->pDevice;
-      pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, false);
+      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, false));
     }
   }
   return 1;
 }
-// 4D864C: using guessed type char byte_4D864C;
-// 4D86F0: using guessed type int dword_4D86F0;
+
 
 //----- (0045DA56) --------------------------------------------------------
-bool LightmapBuilder::DrawLightmaps2(float a2)
+bool LightmapBuilder::DrawLightmaps2(float z_bias)
 {
-  LightmapBuilder *v2; // esi@1
-  bool result; // eax@1
-  signed int v4; // edi@2
-  std::string v5; // [sp-14h] [bp-3Ch]@5
-  const char *v6; // [sp-4h] [bp-2Ch]@5
-  int v7; // [sp+0h] [bp-28h]@5
   Vec3_float_ v; // [sp+Ch] [bp-1Ch]@2
-  std::string *v9; // [sp+18h] [bp-10h]@5
-  unsigned int v10; // [sp+1Ch] [bp-Ch]@5
-  Lightmap *a1; // [sp+20h] [bp-8h]@3
-  int a3; // [sp+27h] [bp-1h]@5
+  v.z = 1.0;
+  v.y = 1.0;
+  v.x = 1.0;
+  
+  for (uint i = 0; i < std__vector_183808_size; ++i)
+    if (!DrawLightmap(std__vector_183808 + i, &v, z_bias))
+      MessageBoxW(nullptr, L"Invalid lightmap detected!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:1288", 0);
 
-  v2 = this;
-  result = this->std__vector_183808_size;
-  if ( result )
-  {
-    v4 = 0;
-    v.z = 1.0;
-    v.y = 1.0;
-    v.x = 1.0;
-    if ( result > 0 )
-    {
-      a1 = this->std__vector_183808;
-      do
-      {
-        result = DrawLightmap(a1, &v, a2);
-        if ( !result )
-        {
-          MessageBoxW(nullptr, L"Invalid lightmap detected!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp:1288", 0);
-          v10 = 0x4D86ECu;
-        }
-        ++a1;
-        ++v4;
-      }
-      while ( v4 < (signed int)v2->std__vector_183808_size);
-    }
-  }
-  LOBYTE(result) = 1;
-  return result;
+  return true;
 }
 
 //----- (0045DAE8) --------------------------------------------------------
-bool LightmapBuilder::DrawLightmap(Lightmap *a1, Vec3_float_ *arg4, float thisa)
+bool LightmapBuilder::DrawLightmap(Lightmap *pLightmap, Vec3_float_ *pColorMult, float z_bias)
 {
-  Lightmap *v4; // edx@1
-  bool result; // eax@2
-  double v6; // st7@3
-  Vec3_float_ *v7; // ecx@3
-  LEVEL_TYPE v8; // edi@3
-  int v9; // esi@3
   double v10; // st7@4
-  unsigned int v11; // ebx@6
-  char *v12; // ecx@7
-  int v13; // edx@7
   double v14; // st7@7
   __int16 v15; // fps@8
-  unsigned __int8 v16; // c2@8
-  unsigned __int8 v17; // c3@8
   double v18; // st3@8
-  int v19; // eax@11
-  double v20; // st3@11
-  int v21; // eax@11
-  char v22; // zf@11
-  HRESULT v23; // eax@15
   signed int v24; // [sp-1Ch] [bp-670h]@13
   const char *v25; // [sp-18h] [bp-66Ch]@13
   int v26; // [sp-14h] [bp-668h]@13
-  HRESULT a2; // [sp+0h] [bp-654h]@15
-  char v28; // [sp+4h] [bp-650h]@7
-  double v29; // [sp+640h] [bp-14h]@3
-  __int64 v30; // [sp+648h] [bp-Ch]@3
-  float v31; // [sp+650h] [bp-4h]@3
-  signed int a1b; // [sp+65Ch] [bp+8h]@3
-  float a1c; // [sp+65Ch] [bp+8h]@3
-  float a1d; // [sp+65Ch] [bp+8h]@3
-  float a1e; // [sp+65Ch] [bp+8h]@3
-  unsigned int a1a; // [sp+65Ch] [bp+8h]@7
-  int arg4a; // [sp+660h] [bp+Ch]@3
+  RenderVertexD3D3 a2[32]; // [sp+0h] [bp-654h]@7
 
-  v4 = a1;
-  if ( (signed int)a1->uNumVertices >= 3 )
+
+  if (pLightmap->uNumVertices < 3)
   {
-    v6 = (double)BYTE1(a1->field_C10) * a1->flt_C14;
-    v30 = a1->field_C10 & 0xFFi64;
-    a1b = BYTE2(a1->field_C10);
-    v7 = arg4;
-    //v31 = v6;
-    *((float *)&v30 + 1) = (double)v30 * v4->flt_C14;
-    a1c = (double)a1b * v4->flt_C14 * arg4->x;
-    //v29 = a1c + 6.7553994e15;
-    //arg4a = LODWORD(v29);
-    arg4a = floorf(a1c + 0.5f);
+    Log::Warning(L"Lightmap uNumVertices < 3");
+    return false;
+  }
 
-    a1d = v6 * v7->y;
-    v29 = a1d + 6.7553994e15;
-    LODWORD(v31) = LODWORD(v29);
-
-    a1e = *((float *)&v30 + 1) * v7->z;
-
-    v29 = a1e + 6.7553994e15;
-    HIDWORD(v30) = LODWORD(v29);
+  uint uLightmapColorMaskR = (pLightmap->uColorMask >> 16) & 0xFF;
+  uint uLightmapColorR = floorf(uLightmapColorMaskR * pLightmap->fBrightness * pColorMult->x + 0.5f);
+  
+  uint uLightmapColorMaskG = (pLightmap->uColorMask >> 8) & 0xFF;
+  uint uLightmapColorG = floorf(uLightmapColorMaskG * pLightmap->fBrightness * pColorMult->y + 0.5f);
+ 
+  uint uLightmapColorMaskB = pLightmap->uColorMask & 0xFF;
+  uint uLightmapColorB = floorf(uLightmapColorMaskB * pLightmap->fBrightness * pColorMult->z + 0.5f);
+ 
+  uint uLightmapColor = uLightmapColorB | (uLightmapColorMaskG << 8) | (uLightmapColorMaskR << 16);
 
-    v8 = uCurrentlyLoadedLevelType;
-    v9 = LODWORD(v29) | ((LODWORD(v31) | (arg4a << 8)) << 8);
-    if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-      v10 = (double)pOutdoorCamera->shading_dist_mist;
-    else
-      v10 = 16192.0;
-    v11 = v4->uNumVertices;
-    if ( (signed int)v11 > 0 )
+  if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+    v10 = (double)pOutdoorCamera->shading_dist_mist;
+  else
+    v10 = 16192.0;
+  v14 = 1.0 / v10;
+
+  for (uint i = 0; i < pLightmap->uNumVertices; ++i)
+  {
+    v18 = 1.0 - 1.0 / (v14 * pLightmap->pVertices[i].vWorldViewPosition.x * 1000.0);
+    if (fabsf(z_bias) < 1e-5f)
     {
-      v12 = &v28;
-      v13 = (int)&v4->pVertices[0].vWorldViewPosition;
-      v14 = 1.0 / v10;
-      a1a = v11;
-      do
-      {
-        //UNDEF(v15);
-        v18 = 1.0 - 1.0 / (v14 * *(float *)v13 * 1000.0);
-        if ( !(v17 | v16) )
-        {
-          v18 = v18 - thisa;
-          if ( v18 < 0.000099999997 )
-            v18 = 0.000099999997;
-        }
-        *((float *)v12 + 1) = v18;
-        v19 = *(unsigned int *)(v13 + 12);
-        *((unsigned int *)v12 + 4) = 0;
-        v20 = 1.0 / *(float *)v13;
-        *((unsigned int *)v12 - 1) = v19;
-        *(unsigned int *)v12 = *(unsigned int *)(v13 + 16);
-        *((unsigned int *)v12 + 5) = *(unsigned int *)(v13 + 24);
-        v21 = *(unsigned int *)(v13 + 28);
-        *((unsigned int *)v12 + 3) = v9;
-        *((unsigned int *)v12 + 6) = v21;
-        v13 += 48;
-        v12 += 32;
-        v22 = a1a-- == 1;
-        *((float *)v12 - 6) = v20;
-      }
-      while ( !v22 );
+      v18 = v18 - z_bias;
+      if (v18 < 0.000099999997)
+        v18 = 0.000099999997;
     }
-    if ( v8 == 1 )
-    {
-      v26 = 1346;
-      v25 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp";
-      v24 = 28;
-    }
-    else
-    {
-      v26 = 1354;
-      v25 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Light.cpp";
-      v24 = 16;
-    }
-    v23 = pRenderer->pRenderD3D->pDevice->DrawPrimitive(
-            D3DPT_TRIANGLEFAN,
-            452,
-            &a2,
-            v11,
-            v24);
-    //CheckHRESULT((CheckHRESULT_stru0 *)&thisa, v23, v25, v26, 0);
-    LOBYTE(result) = 1;
+
+    a2[i].pos.x = pLightmap->pVertices[i].vWorldViewProjX;
+    a2[i].pos.z = v18;
+    a2[i].pos.y = pLightmap->pVertices[i].vWorldViewProjY;
+    a2[i].rhw = 1.0 / pLightmap->pVertices[i].vWorldViewPosition.x;
+    a2[i].diffuse = uLightmapColor;
+    a2[i].specular = 0;
+    a2[i].texcoord.x = pLightmap->pVertices[i].u;
+    a2[i].texcoord.y = pLightmap->pVertices[i].v;
   }
-  else
-  {
-    LOBYTE(result) = 0;
-  }
-  return result;
+
+  if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+    v24 = D3DDP_DONOTLIGHT | D3DDP_DONOTCLIP | D3DDP_DONOTUPDATEEXTENTS;
+   else
+    v24 = D3DDP_DONOTLIGHT;
+
+  ErrD3D(pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,
+            D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
+            a2,
+            pLightmap->uNumVertices,
+            v24));
+
+  return true;
 }
 
 //----- (0045DCA9) --------------------------------------------------------
 void LightmapBuilder::DoDrawLightmaps()
 {
-  const char *v1; // ebx@0
-  int v2; // ebp@0
-  int v3; // edi@0
-  int v4; // esi@0
-  HRESULT v5; // eax@4
-  HRESULT v6; // eax@4
-  HRESULT v7; // eax@4
-  char *v8; // eax@4
-  //IDirect3DDevice3Vtbl *v9; // ebp@6
-  struct IDirect3DTexture2 *v10; // ST90_4@6
-  //IDirect3DDevice3 *v11; // ST88_4@6
-  HRESULT v12; // eax@6
-  HRESULT v13; // eax@6
-  HRESULT v14; // eax@6
-  HRESULT v15; // eax@6
-  HRESULT v16; // eax@6
-  HRESULT v17; // eax@6
-  HRESULT v18; // eax@6
-  HRESULT v19; // eax@6
-  LightmapBuilder *v20; // [sp+98h] [bp-8h]@1
-  LightmapBuilder *v21; // [sp+9Ch] [bp-4h]@1
-  LightmapBuilder *thisa; // [sp+A4h] [bp+4h]@0
-  //CheckHRESULT_stru0 a8; // [sp+A8h] [bp+8h]@0
-  //CheckHRESULT_stru0 thisaa; // [sp+B4h] [bp+14h]@0
+  if (!std__vector_183808_size)
+    return;
+
+  if (pRenderer->bUsingSpecular)
+    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0));
+ 
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 0));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 1u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 0));
+
+  auto pTex = pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("effpar03");
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetTexture(0, pTex));
 
-  v21 = this;
-  v20 = this;
-  if ( this->std__vector_183808_size )
-  {
-    if ( pRenderer->bUsingSpecular )
-      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 2u));
 
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 0));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 1u));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 0));
+  DrawLightmaps2(0.00050000002);
 
-    v8 = (char *)stru_69BD44.c_str();
-    if ( !stru_69BD44.size() )
-      v8 = (char *)&dword_4D86F0;
-    //v9 = pRenderer->pRenderD3D->pDevice->lpVtbl;
-    v10 = pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr(v8);
-    //v11 = pRenderer->pRenderD3D->pDevice;
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetTexture(0, v10));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 2u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 0));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 1u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 2));
 
-    DrawLightmaps2(0.00050000002);
-
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1u));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 0));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 1u));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1u));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 2));
-    if ( pRenderer->bUsingSpecular )
-      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1u));
-  }
+  if (pRenderer->bUsingSpecular)
+    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1u));
 }
\ No newline at end of file
--- a/LightmapBuilder.h	Tue Oct 23 17:33:33 2012 +0600
+++ b/LightmapBuilder.h	Tue Oct 23 17:34:20 2012 +0600
@@ -17,8 +17,8 @@
   __int16 field_C0A;
   __int16 field_C0C;
   __int16 field_C0E;
-  int field_C10;
-  float flt_C14;
+  unsigned int uColorMask;
+  float fBrightness;
   int field_C18;
 };
 #pragma pack(pop)
@@ -28,12 +28,12 @@
 #pragma pack(push, 1)
 struct LightmapBuilder
 {
-   LightmapBuilder();
-   inline ~LightmapBuilder() //----- (0045BBAA)
-   {}
+  LightmapBuilder();
+  inline ~LightmapBuilder() //----- (0045BBAA)
+  {}
 
   void DoDrawLightmaps();
-  bool DrawLightmap(Lightmap *a1, Vec3_float_ *arg4, float thisa);
+  bool DrawLightmap(Lightmap *a1, Vec3_float_ *pColorMult, float z_bias);
   bool DrawLightmaps2(float a2);
   char _45D74F_MessWithLight(int a2, int *a3);
   void DrawLightmaps(int a2);
@@ -53,7 +53,7 @@
   bool ApplyLights_IndoorFace(unsigned int uFaceID);
   int _45C6D6(int a2, struct RenderVertexSoft *a3, Lightmap *pLightmap);
   int _45C4B9(int a2, struct RenderVertexSoft *a3, Lightmap *pLightmap);
-  char _45BE86_build_light_polygon(int arg0, float a4, int arg8, float a5, int uLightType, struct stru314 *a7, signed int a2, RenderVertexSoft *a9, char uClipFlag);
+  char _45BE86_build_light_polygon(int arg0, float a4, unsigned int uColorMask, float a5, int uLightType, struct stru314 *a7, signed int a2, RenderVertexSoft *a9, char uClipFlag);
   char ApplyLights(struct stru320 *a2, struct stru154 *a3, unsigned int uNumVertices, struct RenderVertexSoft *a5, float a6, char a7);
 
 
@@ -72,7 +72,7 @@
   float flt_3C8C20;
   float flt_3C8C24;
   float flt_3C8C28;
-  float flt_3C8C2C;
+  float flt_3C8C2C_lightmaps_brightness;
   float flt_3C8C30;
   RenderVertexSoft field_3C8C34[256];
   int uFlags;
--- a/Might and Magic Trilogy.vcxproj.filters	Tue Oct 23 17:33:33 2012 +0600
+++ b/Might and Magic Trilogy.vcxproj.filters	Tue Oct 23 17:34:20 2012 +0600
@@ -147,7 +147,6 @@
     <ClInclude Include="TurnEngine.h" />
     <ClInclude Include="stru220.h" />
     <ClInclude Include="stru279.h" />
-    <ClInclude Include="stru346.h" />
     <ClInclude Include="stru314.h" />
     <ClInclude Include="SaveLoad.h" />
     <ClInclude Include="stru287.h" />
@@ -200,7 +199,6 @@
     </ClInclude>
     <ClInclude Include="Log.h" />
     <ClInclude Include="FrameTableInc.h" />
-    <ClInclude Include="resource.h" />
   </ItemGroup>
   <ItemGroup>
     <Filter Include="lib">
@@ -317,7 +315,4 @@
     <ClCompile Include="mm7_6.cpp" />
     <ClCompile Include="GameUIs.cpp" />
   </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include="Might and Magic Trilogy.rc" />
-  </ItemGroup>
 </Project>
\ No newline at end of file
--- a/Mouse.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/Mouse.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -390,53 +390,15 @@
 }
 
 //----- (00469E3B) --------------------------------------------------------
-unsigned __int16 *Mouse::_469E3B()
+void Mouse::DrawCursorToTarget()
 {
-  unsigned __int16 *result; // eax@1
-  int v2; // esi@3
-  unsigned int v3; // edx@3
-  int v4; // edi@4
-  unsigned __int16 *v5; // ebx@5
-  unsigned __int16 *v6; // esi@6
-  unsigned int v7; // [sp+4h] [bp-Ch]@2
-  unsigned __int16 *v8; // [sp+8h] [bp-8h]@2
-  unsigned __int16 *v9; // [sp+Ch] [bp-4h]@2
+  if (!pCursorBitmap3_sysmembits_16bit)
+    return;
 
-  result = this->pCursorBitmap3_sysmembits_16bit;
-  if ( result )
-  {
-    v9 = this->pCursorBitmap3_sysmembits_16bit;
-    v7 = pRenderer->uTargetSurfacePitch;
-    v8 = pRenderer->pTargetSurface;
-    result = (unsigned __int16 *)this->field_44;
-    if ( (signed int)result < this->field_4C )
-    {
-      v2 = this->field_48;
-      v3 = pRenderer->uTargetSurfacePitch * (int)result;
-      do
-      {
-        v4 = this->field_40;
-        if ( v4 < v2 )
-        {
-          v5 = &v8[v3 + v4];
-          do
-          {
-            v6 = v9;
-            ++v9;
-            ++v4;
-            *v5 = *v6;
-            v2 = this->field_48;
-            ++v5;
-          }
-          while ( v4 < v2 );
-        }
-        v3 += v7;
-        result = (unsigned __int16 *)((char *)result + 1);
-      }
-      while ( (signed int)result < this->field_4C );
-    }
-  }
-  return result;
+  auto pSrc = pCursorBitmap3_sysmembits_16bit;
+  for (uint y = field_44; y < field_4C; ++y)
+    for (uint x = field_40; x < field_48; ++x)
+      pRenderer->pTargetSurface[y * pRenderer->uTargetSurfacePitch + x] = *pSrc++;
 }
 
 //----- (00469EA4) --------------------------------------------------------
@@ -780,8 +742,8 @@
   int v2; // eax@2
   int v3; // esi@4
   char result; // al@5
-  const char *v5; // eax@6
-  std::string v6; // [sp-18h] [bp-12Ch]@9
+  //const char *v5; // eax@6
+  //std::string v6; // [sp-18h] [bp-12Ch]@9
   const char *v7; // [sp-8h] [bp-11Ch]@9
   int v8; // [sp-4h] [bp-118h]@9
   DDSURFACEDESC2 Dst; // [sp+Ch] [bp-108h]@1
@@ -828,10 +790,7 @@
   }
   else
   {
-    v5 = std__string_720990.c_str();
-    if ( !std__string_720990.size() )
-      v5 = (const char *)&dword_4D86F0;
-    if ( !LoadCursor(v5) )
+    if ( !LoadCursor("micon1") )
     {
       MessageBoxW(nullptr, L"Could not load async mouse cursor image", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\MouseAsync.cpp:182", 0);
     }
--- a/Mouse.h	Tue Oct 23 17:33:33 2012 +0600
+++ b/Mouse.h	Tue Oct 23 17:34:20 2012 +0600
@@ -72,7 +72,7 @@
   void DrawCursor();
   void _469E1C();
   void _469E24();
-  unsigned __int16 *_469E3B();
+  void DrawCursorToTarget();
   void _469EA4();
   void Activate(int bActive);
   void SetMouseClick(int x, int y);
--- a/Outdoor.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/Outdoor.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -112,7 +112,7 @@
     pGame->pIndoorCameraD3D->_438240_draw_lits();
   }
   pGame->PushStationaryLights(-1);
-  pGame->PushStru165s();
+  pGame->PrepareBloodsplats();
   if ( v2 )
   {
     v4 = WorldPosToGridCellZ(pParty->vPosition.z);
@@ -3012,14 +3012,14 @@
             goto LABEL_53;
           }
         }
-        v28->field_26 = v27;
-        v28->field_20 = x;
-        v28->field_28 = v46;
-        v28->field_22 = y;
-        v28->field_24 = v61;
+        v28->uScreenSpaceX = v27;
+        v28->some_x = x;
+        v28->uScreenSpaceY = v46;
+        v28->some_y = y;
+        v28->some_z = v61;
         HIWORD(v34) = HIWORD(X);
         LOWORD(v34) = 0;
-        v28->field_2A = 0;
+        v28->uPaletteSubindex = 0;
         v28->sZValue = v34 + (8 * v59 | 3);
         v28->field_14 = v59;
         v35 = pMonsterList->pMonsters;
@@ -3028,7 +3028,7 @@
         v38 = *(int *)(v1 + 150) < 0;
         v28->field_1E = v62 | 0x200;
         v28->pSpriteFrame = v15;
-        v28->field_2C_prolly_tint = *((int *)&v35[v36] - 36);
+        v28->uTintColor = *((int *)&v35[v36] - 36);
         if ( !v38 && (!(v38 | v37) || *(int *)(v1 + 146)) )
           v28->field_1E = v62 | 0x200;
       }
--- a/OutdoorCamera.h	Tue Oct 23 17:33:33 2012 +0600
+++ b/OutdoorCamera.h	Tue Oct 23 17:34:20 2012 +0600
@@ -47,7 +47,7 @@
   unsigned int uNumEdges;
   unsigned int uNumSurfs;
   unsigned int uNumSpans;
-  int field_3C;
+  unsigned int uNumBillboards;
   float field_40;
   int field_44;
   int outdoor_grid_band_3;
--- a/ParticleEngine.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/ParticleEngine.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -7,7 +7,6 @@
 #include "IndoorCamera.h"
 #include "Math.h"
 #include "LOD.h"
-#include "stru346.h"
 
 #include "mm7_data.h"
 
@@ -44,7 +43,7 @@
     v3 = (Particle *)this;
     do
     {
-      if ( !v3->bFree )
+      if ( !v3->uType )
         break;
       ++v2;
       ++v3;
@@ -57,7 +56,7 @@
       if ( v2 > this->uEndParticle )
         this->uEndParticle = v2;
       v4 = &this->pParticles[v2];
-      v4->bFree = a2->bFree;
+      v4->uType = a2->bFree;
       v4->x = a2->x;
       v4->y = a2->y;
       v4->z = a2->z;
@@ -70,8 +69,8 @@
       v5 = a2->uDiffuse;
       v4->uParticleColor = v5;
       v4->uLightColor = v5;
-      v6 = (v4->bFree & 4) == 0;
-      v4->field_20 = a2->field_20;
+      v6 = (v4->uType & 4) == 0;
+      v4->timeToLive = a2->timeToLive;
       v4->uTextureID = a2->uTextureID;
       v4->flt_28 = a2->flt_28;
       if ( v6 )
@@ -91,128 +90,100 @@
 //----- (0048ABF3) --------------------------------------------------------
 void ParticleEngine::Draw()
 {
-  ParticleEngine *v1; // esi@1
+  uTimeElapsed += pEventTimer->uTimeElapsed;
+  pLines.uNumLines = 0;
 
-  v1 = this;
-  v1->uTimeElapsed += pEventTimer->uTimeElapsed;
-  this->pLines.uNumLines = 0;
-  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
+  if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
     DrawParticles_BLV();
   else
     DrawParticles_ODM();
-  if ( pRenderer->pRenderD3D )
+
+  if (pRenderer->pRenderD3D)
   {
-    if ( v1->pLines.uNumLines )
+    if (pLines.uNumLines)
     {
       pRenderer->pRenderD3D->pDevice->SetTexture(0, 0);
       pRenderer->pRenderD3D->pDevice->DrawPrimitive(
         D3DPT_LINELIST,
-        452,
-        v1->pLines.pLineVertices,
-        v1->pLines.uNumLines,
-        16);
+        D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
+        pLines.pLineVertices,
+        pLines.uNumLines,
+        D3DDP_DONOTLIGHT);
     }
   }
 }
 
 //----- (0048AC65) --------------------------------------------------------
-int ParticleEngine::UpdateParticles()
+void ParticleEngine::UpdateParticles()
 {
-  ParticleEngine *v1; // ebx@1
   unsigned int time; // edi@1
-  int v3; // eax@1
-  int v4; // esi@2
   int v5; // eax@3
   char v6; // sf@4
   float v7; // ST4C_4@11
   double v8; // st7@12
   int v9; // eax@12
   double v10; // st7@14
-  float v11; // ST4C_4@14
-  float v12; // ST3C_4@14
-  double v13; // ST20_8@14
-  float v14; // ST3C_4@14
-  double v15; // ST18_8@14
-  float v16; // ST3C_4@14
-  double v17; // ST10_8@14
-  signed int result; // eax@19
   signed int v19; // [sp+38h] [bp-14h]@1
   int v20; // [sp+3Ch] [bp-10h]@1
   unsigned int time_; // [sp+40h] [bp-Ch]@1
   int v22; // [sp+44h] [bp-8h]@12
-  int v23; // [sp+48h] [bp-4h]@1
 
   v20 = 0;
-  v1 = this;
   time = pMiscTimer->bPaused == 0 ? pEventTimer->uTimeElapsed : 0;
-  v3 = this->uStartParticle;
   v19 = 500;
   time_ = pMiscTimer->bPaused == 0 ? pEventTimer->uTimeElapsed : 0;
-  v23 = this->uStartParticle;
-  if ( v3 <= this->uEndParticle )
+
+  for (uint i = uStartParticle; i < uEndParticle; ++i)
   {
-    v4 = (int)((char *)&this->pParticles[v3].uParticleColor + 1);
-    do
-    {
-      v5 = *(int *)(v4 - 0x1D);
-      if ( v5 )
-      {
-        v6 = ((*(int *)(v4 + 3) - time) & 0x80000000u) != 0;
-        *(int *)(v4 + 3) -= time;
-        if ( v6 )
-        {
-          *(int *)(v4 - 0x1D) = 0;
-        }
+    auto p = pParticles + i;
+
+      v5 = p->uType;
+      if (!p->uType)
+        continue;
+
+        v6 = (p->timeToLive - time) < 0;
+        p->timeToLive -= time;
+        if (v6)
+          p->uType = 0;
         else
         {
           if ( BYTE1(v5) & 2 )
           {
-            *(int *)(v4 + 15) = *(int *)(v4 - 25);
-            *(int *)(v4 + 19) = *(int *)(v4 - 21);
-            *(int *)(v4 + 23) = *(int *)(v4 - 17);
+            p->_x = p->x;
+            p->_y = p->y;
+            p->_z = p->z;
           }
           if ( v5 & 1 )
-            *(float *)(v4 - 5) = *(float *)(v4 - 5) - (double)(signed int)time_ * 5.0;
+            p->flt_18 = p->flt_18 - (double)(signed int)time_ * 5.0;
           if ( v5 & 8 )
           {
             v7 = (double)(signed int)time_;
-            *(float *)(v4 - 25) = (double)(rand() % 5 - 2) * v7 * 0.0625 + *(float *)(v4 - 25);
-            *(float *)(v4 - 21) = (double)(rand() % 5 - 2) * v7 * 0.0625 + *(float *)(v4 - 21);
-            *(float *)(v4 - 17) = (double)(rand() % 5 + 4) * v7 * 0.0625 + *(float *)(v4 - 17);
+            *(float *)&p->x += (double)(rand() % 5 - 2) * v7 / 16.0f;
+            *(float *)&p->y += (double)(rand() % 5 - 2) * v7 / 16.0f;
+            *(float *)&p->z += (double)(rand() % 5 + 4) * v7 / 16.0f;
           }
-          v8 = (double)(signed int)time_ * 0.0078125;
-          v9 = (signed int)(time * *(int *)(v4 + 27)) / 16;
-          *(float *)(v4 - 25) = v8 * *(float *)(v4 - 13) + *(float *)(v4 - 25);
-          *(float *)(v4 - 21) = v8 * *(float *)(v4 - 9) + *(float *)(v4 - 21);
-          *(float *)(v4 - 17) = v8 * *(float *)(v4 - 5) + *(float *)(v4 - 17);
-          *(int *)(v4 + 31) += v9;
-          v22 = 2 * *(int *)(v4 + 3);
-          if ( 2 * *(int *)(v4 + 3) >= 255 )
+          v8 = (double)(signed int)time_ / 128.0f;
+          v9 = (signed int)(time * p->field_38) / 16;
+          *(float *)&p->x += v8 * p->flt_10;
+          *(float *)&p->y += v8 * p->flt_14;
+          *(float *)&p->z += v8 * p->flt_18;
+          p->_rotation += v9;
+          v22 = 2 * p->timeToLive;
+          if ( 2 * p->timeToLive >= 255 )
             v22 = 255;
           v10 = (double)v22 * 0.0039215689;
-          v11 = v10;
-          v12 = (double)*(char *)(v4 + 1) * v10;
-          v13 = v12 + 6.7553994e15;
-          v14 = (double)*(char *)v4 * v11;
-          v15 = v14 + 6.7553994e15;
-          v16 = (double)(*(int *)(v4 - 1) & 0xFF) * v11;
-          v17 = v16 + 6.7553994e15;
-          *(int *)(v4 + 71) = LODWORD(v17) | ((LODWORD(v15) | (LODWORD(v13) << 8)) << 8);
-          if ( v23 < v19 )
-            v19 = v23;
-          if ( v23 > v20 )
-            v20 = v23;
+          p->uLightColor = (uint)floorf(p->b + 0.5) |
+                           ((uint)floorf(p->g + 0.5) << 8) |
+                           ((uint)floorf(p->r + 0.5) << 16);
+          if ( i < v19 )
+            v19 = i;
+          if ( i > v20 )
+            v20 = i;
         }
-      }
-      ++v23;
-      v4 += 104;
-    }
-    while ( v23 <= v1->uEndParticle );
   }
-  v1->uEndParticle = v20;
-  result = v19;
-  v1->uStartParticle = v19;
-  return result;
+
+  uEndParticle = v20;
+  uStartParticle = v19;
 }
 
 //----- (0048AE74) --------------------------------------------------------
@@ -275,7 +246,7 @@
   int y; // [sp+4Ch] [bp-4h]@3
 
   pParticle = &this->pParticles[uParticleID];
-  if ( !pParticle->bFree )
+  if ( !pParticle->uType )
     return 0;
   uParticleID = LODWORD(pParticle->x);
   v56 = *(float *)&uParticleID + 6.7553994e15;
@@ -288,7 +259,7 @@
   {
     if ( pBLVRenderParams->sPartyRotX )
     {
-      if ( BYTE1(pParticle->bFree) & 2 )
+      if ( BYTE1(pParticle->uType) & 2 )
       {
         v11 = pParticle->_x + 6.7553994e15;
         uParticleID = (LODWORD(v11) - pBLVRenderParams->vPartyPos.x) << 16;
@@ -314,12 +285,12 @@
         LODWORD(v18) = pBLVRenderParams->uViewportCenterX
                      - ((signed int)((unsigned __int64)(v16 * (signed __int64)(a6 + v17)) >> 16) >> 16);
         v19 = pParticle->field_58;
-        pParticle->field_48 = v18;
+        pParticle->uScreenSpaceZ = v18;
         uParticleID = (unsigned __int64)(v19 * (signed __int64)(HIDWORD(v13) + HIDWORD(a5))) >> 16;
         v20 = pBLVRenderParams->uViewportCenterY
             - ((signed int)((unsigned __int64)(v19 * (signed __int64)(HIDWORD(v13) + HIDWORD(a5))) >> 16) >> 16);
-        pParticle->field_54 = v14;
-        pParticle->field_4C = v20;
+        pParticle->sZValue2 = v14;
+        pParticle->uScreenSpaceW = v20;
       }
       uParticleID = (x_int - pBLVRenderParams->vPartyPos.x) << 16;
       y = (LODWORD(y_int_) - pBLVRenderParams->vPartyPos.y) << 16;
@@ -340,7 +311,7 @@
     }
     else
     {
-      if ( BYTE1(pParticle->bFree) & 2 )
+      if ( BYTE1(pParticle->uType) & 2 )
       {
         v25 = pParticle->_x + 6.7553994e15;
         uParticleID = (LODWORD(v25) - pBLVRenderParams->vPartyPos.x) << 16;
@@ -363,11 +334,11 @@
         LODWORD(v33) = pBLVRenderParams->uViewportCenterX
                      - ((signed int)((unsigned __int64)(v31 * (signed __int64)(v28 + v32)) >> 16) >> 16);
         v34 = pParticle->field_58;
-        pParticle->field_48 = v33;
+        pParticle->uScreenSpaceZ = v33;
         v35 = pBLVRenderParams->uViewportCenterY
             - ((signed int)((unsigned __int64)(v34 * (signed __int64)v29) >> 16) >> 16);
-        pParticle->field_54 = v27;
-        pParticle->field_4C = v35;
+        pParticle->sZValue2 = v27;
+        pParticle->uScreenSpaceW = v35;
       }
       uParticleID = (x_int - pBLVRenderParams->vPartyPos.x) << 16;
       y = (LODWORD(y_int_) - pBLVRenderParams->vPartyPos.y) << 16;
@@ -433,7 +404,7 @@
   pParticle->field_58 = (unsigned __int64)(_48B561_mess_with_scaling_along_z(/*v9, */v8) * (signed __int64)pParticle->field_58) >> 16;
   v10 = uParticleID;
 LABEL_19:
-  pParticle->field_50 = v10;
+  pParticle->sZValue = v10;
   return 1;
 }
 
@@ -502,7 +473,7 @@
   v4 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY);
   v5 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY - stru_5C6E00->uIntegerHalfPi);
   v6 = &v2->pParticles[uID];
-  if ( v6->bFree )
+  if ( v6->uType )
   {
     v7 = v6->x + 6.7553994e15;
     v41 = LODWORD(v7);
@@ -510,7 +481,7 @@
     v42 = v6->z + 6.7553994e15;
     if ( v3 )
     {
-      if ( BYTE1(v6->bFree) & 2 )
+      if ( BYTE1(v6->uType) & 2 )
       {
         v8 = v6->_x + 6.7553994e15;
         uIDc = (LODWORD(v8) - pIndoorCamera->pos.x) << 16;
@@ -536,7 +507,7 @@
                           - ((signed int)((unsigned __int64)(v15
                                                            * (signed __int64)(signed int)(((unsigned __int64)(uIDd * (signed __int64)v3) >> 16)
                                                                                         - ((unsigned __int64)(v11 * (signed __int64)v44) >> 16))) >> 16) >> 16);
-        v6->field_50 = HIDWORD(v12);
+        v6->sZValue = HIDWORD(v12);
       }
       uIDe = (v41 - pIndoorCamera->pos.x) << 16;
       v47 = (LODWORD(v39) - pIndoorCamera->pos.y) << 16;
@@ -553,7 +524,7 @@
     }
     else
     {
-      if ( BYTE1(v6->bFree) & 2 )
+      if ( BYTE1(v6->uType) & 2 )
       {
         v18 = v6->_x + 6.7553994e15;
         uIDf = (LODWORD(v18) - pIndoorCamera->pos.x) << 16;
@@ -573,7 +544,7 @@
                                                                                         - ((unsigned __int64)(uIDf * (signed __int64)v5) >> 16))) >> 16) >> 16);
         v25 = pViewport->uScreenCenterY
             - ((signed int)((unsigned __int64)(v24 * (signed __int64)SLODWORD(v21)) >> 16) >> 16);
-        v6->field_50 = ((unsigned __int64)(v20 * (signed __int64)v5) >> 16)
+        v6->sZValue = ((unsigned __int64)(v20 * (signed __int64)v5) >> 16)
                      + ((unsigned __int64)(uIDf * (signed __int64)v4) >> 16);
         v6->uScreenSpaceY = v25;
       }
@@ -604,7 +575,7 @@
       v6->uScreenSpaceY = pViewport->uScreenCenterY - v33;
       v35 = v32;
       v6->field_58 = (unsigned __int64)(_48B561_mess_with_scaling_along_z(/*v34, */v35) * (signed __int64)v6->field_58) >> 16;
-      v6->field_50 = X_4;
+      v6->sZValue = X_4;
       v36 = v6->uScreenSpaceX;
       if ( v36 >= (signed int)pViewport->uViewportX )
       {
@@ -626,152 +597,110 @@
 //----- (0048BBA6) --------------------------------------------------------
 void ParticleEngine::DrawParticles_BLV()
 {
-  ParticleEngine *v1; // esi@1
-  int v2; // eax@1
-  unsigned __int8 v3; // zf@1
-  char v4; // sf@1
-  unsigned __int8 v5; // of@1
-  Render *v6; // ebx@2
-  char *v7; // edi@2
-  signed int v8; // ecx@7
-  int v9; // eax@10
-  signed int v10; // eax@12
   int v11; // eax@18
   int v12; // ecx@20
   int v13; // edx@20
   Particle *v14; // eax@28
   RenderBillboardTransform_local0 v15; // [sp+Ch] [bp-58h]@1
-  int v16; // [sp+5Ch] [bp-8h]@5
-  int v17; // [sp+60h] [bp-4h]@1
 
   v15.uParentBillboardID = -1;
-  v1 = this;
-  v2 = this->uStartParticle;
-  v5 = __OFSUB__(v2, this->uEndParticle);
-  v3 = v2 == this->uEndParticle;
-  v4 = v2 - this->uEndParticle < 0;
-  v17 = this->uStartParticle;
-  if ( (unsigned __int8)(v4 ^ v5) | v3 )
+
+  for (uint i = uStartParticle; i < uEndParticle; ++i)
   {
-    v6 = pRenderer;
-    v7 = (char *)&this->pParticles[v2].field_54 + 2;
-    do
+    auto p = pParticles + i;
+
+    if (!p->uType)
+      continue;
+
+    if (!ViewProject_TrueIfStillVisible(i))
+      continue;
+
+    if (p->uScreenSpaceX >= pBLVRenderParams->uViewportX &&
+        p->uScreenSpaceX < pBLVRenderParams->uViewportZ &&
+        p->uScreenSpaceY >= pBLVRenderParams->uViewportY &&
+        p->uScreenSpaceY < pBLVRenderParams->uViewportW)
     {
-      if ( *(int *)(v7 - 86) )
+      if (pRenderer->pRenderD3D)
       {
-        if ( v1->ViewProject_TrueIfStillVisible(v2) )
+        if (p->uType & 0x0100)
         {
-          v16 = *(int *)(v7 - 22);
-          if ( v16 >= (signed int)pBLVRenderParams->uViewportX )
+          v14 = &pParticles[i];
+          v15.field_10 = v14->field_58 / 4;
+          v15.field_14 = v14->field_58 / 4;
+          v15.uScreenSpaceX = v14->uScreenSpaceX;
+          v15.uScreenSpaceY = v14->uScreenSpaceY;
+          v15.sZValue = v14->sZValue;
+          pRenderer->MakeParticleBillboardAndPush_BLV(&v15, 0, v14->uLightColor, v14->_rotation);
+          return;
+        }
+        if (p->uType & 0x0200)
+        {
+          if (pLines.uNumLines < 100)
           {
-            if ( v16 < (signed int)pBLVRenderParams->uViewportZ )
-            {
-              v8 = *(int *)(v7 - 18);
-              if ( v8 >= (signed int)pBLVRenderParams->uViewportY )
-              {
-                if ( v8 < (signed int)pBLVRenderParams->uViewportW )
-                {
-                  if ( pRenderer->pRenderD3D )
-                  {
-                    v9 = *(int *)(v7 - 86);
-                    if ( BYTE1(v9) & 1 )
-                    {
-                      v14 = &v1->pParticles[v17];
-                      v15.field_10 = v14->field_58 >> 2;
-                      v15.field_14 = v14->field_58 >> 2;
-                      v15.field_8 = v14->uScreenSpaceX;
-                      v15.field_C = v14->uScreenSpaceY;
-                      v15.field_28 = v14->field_50;
-                      pRenderer->MakeParticleBillboardAndPush_BLV(&v15, 0, v14->uLightColor, v14->_rotation);
-                      return;
-                    }
-                    if ( BYTE1(v9) & 2 )
-                    {
-                      v10 = v1->pLines.uNumLines;
-                      if ( v10 < 100 )
-                      {
-                        v1->pLines.pLineVertices[2 * v10].pos.x = (double)v16;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].pos.y = (double)*(signed int *)(v7 - 18);
-                        v16 = *((short *)v7 - 2);
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].pos.z = 1.0
-                                                                                 - 1.0 / ((double)v16 * 0.061758894);
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].rhw = 1.0;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].diffuse = *(int *)(v7 + 14);
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].specular = 0;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].texcoord.x = 0.0;
-                        *((float *)&v1->pParticles[0].bFree + 16 * (v1->pLines.uNumLines + 813)) = 0.0;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].pos.x = (double)*(signed int *)(v7 - 14);
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].pos.y = (double)*(signed int *)(v7 - 10);
-                        v16 = *(short *)v7;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].pos.z = 1.0
-                                                                                     - 1.0 / ((double)v16 * 0.061758894);
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].rhw = 1.0;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].diffuse = *(int *)(v7 + 14);
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].specular = 0;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].texcoord.x = 0.0;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines++ + 1].texcoord.y = 0.0;
-                      }
-                    }
-                    if ( *(v7 - 85) & 4 )
-                    {
-                      v15.field_10 = *(int *)(v7 + 2);
-                      v15.field_14 = *(int *)(v7 + 2);
-                      v15.field_8 = *(int *)(v7 - 22);
-                      v15.field_C = *(int *)(v7 - 18);
-                      v15.field_28 = *(int *)(v7 - 6);
-                      pRenderer->MakeParticleBillboardAndPush_BLV(
-                        &v15,
-                        pBitmaps_LOD->pHardwareTextures[*(int *)(v7 - 50)],
-                        *(int *)(v7 + 14),
-                        *(int *)(v7 - 26));
-                    }
-                    if ( *(v7 - 85) & 8 )
-                    {
-                      v15.field_10 = *(int *)(v7 + 2);
-                      v15.field_14 = *(int *)(v7 + 2);
-                      v15.field_8 = *(int *)(v7 - 22);
-                      v15.field_C = *(int *)(v7 - 18);
-                      v15.field_28 = *(int *)(v7 - 6);
-                      pRenderer->MakeParticleBillboardAndPush_BLV(
-                        &v15,
-                        pSprites_LOD->pHardwareSprites[*(int *)(v7 - 50)].pTexture,
-                        *(int *)(v7 + 14),
-                        *(int *)(v7 - 26));
-                    }
-                  }
-                  else
-                  {
-                    v11 = 13 * *(int *)(v7 + 2) >> 16;
-                    if ( v11 > 30 )
-                      v11 = 30;
-                    v12 = v8 - v11;
-                    v13 = v16 - (v11 >> 1);
-                    if ( v13 + v11 < (signed int)pViewport->uViewportX
-                      || v13 >= (signed int)pViewport->uViewportZ
-                      || v12 + v11 < (signed int)pViewport->uViewportY
-                      || v12 >= (signed int)pViewport->uViewportW )
-                    {
-                      v6 = pRenderer;
-                    }
-                    else
-                    {
-                      v6 = pRenderer;
-                      pRenderer->_4A48E4(v13, v12, *(int *)(v7 - 6), *(int *)(v7 + 14), v11);
-                    }
-                  }
-                }
-              }
-            }
+            pLines.pLineVertices[2 * pLines.uNumLines].pos.x = p->uScreenSpaceX;
+            pLines.pLineVertices[2 * pLines.uNumLines].pos.y = p->uScreenSpaceY;
+            pLines.pLineVertices[2 * pLines.uNumLines].pos.z = 1.0 - 1.0 / ((short)p->sZValue * 0.061758894);
+            pLines.pLineVertices[2 * pLines.uNumLines].rhw = 1.0;
+            pLines.pLineVertices[2 * pLines.uNumLines].diffuse = p->uLightColor;
+            pLines.pLineVertices[2 * pLines.uNumLines].specular = 0;
+            pLines.pLineVertices[2 * pLines.uNumLines].texcoord.x = 0.0;
+            pLines.pLineVertices[2 * pLines.uNumLines].texcoord.y = 0.0;
+
+            pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.x = p->uScreenSpaceZ;
+            pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.y = p->uScreenSpaceW;
+            pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.z = 1.0 - 1.0 / ((short)p->sZValue2 * 0.061758894);
+            pLines.pLineVertices[2 * pLines.uNumLines + 1].rhw = 1.0;
+            pLines.pLineVertices[2 * pLines.uNumLines + 1].diffuse = p->uLightColor;
+            pLines.pLineVertices[2 * pLines.uNumLines + 1].specular = 0;
+            pLines.pLineVertices[2 * pLines.uNumLines + 1].texcoord.x = 0.0;
+            pLines.pLineVertices[2 * pLines.uNumLines++ + 1].texcoord.y = 0.0;
           }
         }
+        if (p->uType & 0x0400)
+        {
+          v15.field_10 = p->field_58;
+          v15.field_14 = p->field_58;
+          v15.uScreenSpaceX = p->uScreenSpaceX;
+          v15.uScreenSpaceY = p->uScreenSpaceY;
+          v15.sZValue = p->sZValue;
+          pRenderer->MakeParticleBillboardAndPush_BLV(&v15,
+                        pBitmaps_LOD->pHardwareTextures[p->uTextureID],
+                        v14->uLightColor,
+                        p->_rotation);
+        }
+        if (p->uType & 0x0800)
+        {
+          v15.field_10 = p->field_58;
+          v15.field_14 = p->field_58;
+          v15.uScreenSpaceX = p->uScreenSpaceX;
+          v15.uScreenSpaceY = p->uScreenSpaceY;
+          v15.sZValue = p->sZValue;
+          pRenderer->MakeParticleBillboardAndPush_BLV(&v15,
+                        pSprites_LOD->pHardwareSprites[p->uTextureID].pTexture,
+                        v14->uLightColor,
+                        p->_rotation);
+        }
       }
-      v7 += 104;
-      v2 = v17 + 1;
-      v5 = __OFSUB__(v17 + 1, v1->uEndParticle);
-      v3 = v17 + 1 == v1->uEndParticle;
-      v4 = v17++ + 1 - v1->uEndParticle < 0;
+      else
+      {
+                    v11 = 13 * p->field_58 >> 16;
+                     if ( v11 > 30 )
+                       v11 = 30;
+                    v12 = p->uScreenSpaceY - v11;
+                    v13 = p->uScreenSpaceX - (v11 >> 1);
+                     if ( v13 + v11 < (signed int)pViewport->uViewportX
+                       || v13 >= (signed int)pViewport->uViewportZ
+                       || v12 + v11 < (signed int)pViewport->uViewportY
+                       || v12 >= (signed int)pViewport->uViewportW )
+                     {
+                      ;
+                     }
+                     else
+                     {
+                      pRenderer->MakeParticleBillboardAndPush_BLV_Software(v13, v12, p->sZValue, p->uLightColor, v11);
+                     }
+      }
     }
-    while ( (unsigned __int8)(v4 ^ v5) | v3 );
   }
 }
 
@@ -783,7 +712,6 @@
   unsigned __int8 v3; // zf@1
   char v4; // sf@1
   unsigned __int8 v5; // of@1
-  Render *pRender; // ebx@2
   char *v7; // edi@2
   int v8; // eax@6
   signed int v9; // eax@8
@@ -791,7 +719,7 @@
   int v11; // ecx@16
   int v12; // edx@16
   Particle *v13; // eax@24
-  stru346 v14; // [sp+Ch] [bp-58h]@1
+  RenderBillboardTransform_local0 v14; // [sp+Ch] [bp-58h]@1
   int v15; // [sp+5Ch] [bp-8h]@9
   int v16; // [sp+60h] [bp-4h]@1
 
@@ -804,8 +732,7 @@
   v16 = this->uStartParticle;
   if ( (unsigned __int8)(v4 ^ v5) | v3 )
   {
-    pRender = pRenderer;
-    v7 = (char *)&this->pParticles[v2].field_50 + 2;
+    v7 = (char *)&this->pParticles[v2].sZValue + 2;
     do
     {
       if ( *(int *)(v7 - 82) && v1->_48B5B3(v2) )
@@ -818,11 +745,11 @@
             v13 = &v1->pParticles[v16];
             v14.field_10 = v13->field_58 >> 2;
             v14.field_14 = v13->field_58 >> 2;
-            v14.field_8 = v13->uScreenSpaceX;
-            v14.field_C = v13->uScreenSpaceY;
-            v14.field_28 = v13->field_50;
+            v14.uScreenSpaceX = v13->uScreenSpaceX;
+            v14.uScreenSpaceY = v13->uScreenSpaceY;
+            v14.sZValue = v13->sZValue;
             pRenderer->MakeParticleBillboardAndPush_ODM(
-              (RenderBillboardTransform_local0 *)&v14,
+              &v14,
               0,
               v13->uLightColor,
               v13->_rotation);
@@ -845,7 +772,7 @@
               v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].diffuse = *(int *)(v7 + 18);
               v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].specular = 0;
               v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].texcoord.x = 0.0;
-              *((float *)&v1->pParticles[0].bFree + 16 * (v1->pLines.uNumLines + 813)) = 0.0;
+              *((float *)&v1->pParticles[0].uType + 16 * (v1->pLines.uNumLines + 813)) = 0.0;
               v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].pos.x = (double)*(signed int *)(v7 - 10);
               v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].pos.y = (double)*(signed int *)(v7 - 6);
               v15 = *(short *)v7;
@@ -865,11 +792,11 @@
           {
             v14.field_10 = *(int *)(v7 + 6);
             v14.field_14 = *(int *)(v7 + 6);
-            v14.field_8 = *(int *)(v7 - 18);
-            v14.field_C = *(int *)(v7 - 14);
-            v14.field_28 = *(int *)(v7 - 2);
+            v14.uScreenSpaceX = *(int *)(v7 - 18);
+            v14.uScreenSpaceY = *(int *)(v7 - 14);
+            v14.sZValue = *(int *)(v7 - 2);
             pRenderer->MakeParticleBillboardAndPush_ODM(
-              (RenderBillboardTransform_local0 *)&v14,
+              &v14,
               pBitmaps_LOD->pHardwareTextures[*(int *)(v7 - 46)],
               *(int *)(v7 + 18),
               *(int *)(v7 - 22));
@@ -878,11 +805,11 @@
           {
             v14.field_10 = *(int *)(v7 + 6);
             v14.field_14 = *(int *)(v7 + 6);
-            v14.field_8 = *(int *)(v7 - 18);
-            v14.field_C = *(int *)(v7 - 14);
-            v14.field_28 = *(int *)(v7 - 2);
+            v14.uScreenSpaceX = *(int *)(v7 - 18);
+            v14.uScreenSpaceY = *(int *)(v7 - 14);
+            v14.sZValue = *(int *)(v7 - 2);
             pRenderer->MakeParticleBillboardAndPush_ODM(
-              (RenderBillboardTransform_local0 *)&v14,
+              &v14,
               pSprites_LOD->pHardwareSprites[*(int *)(v7 - 46)].pTexture,
               *(int *)(v7 + 18),
               *(int *)(v7 - 22));
@@ -900,12 +827,11 @@
             || *(int *)(v7 - 14) < (signed int)pViewport->uViewportY
             || v12 >= (signed int)pViewport->uViewportW )
           {
-            pRender = pRenderer;
+            ;
           }
           else
           {
-            pRender = pRenderer;
-            pRenderer->_4A48E4(v11, v12, *(int *)(v7 - 2), *(int *)(v7 + 18), v10);
+            pRenderer->MakeParticleBillboardAndPush_BLV_Software(v11, v12, *(int *)(v7 - 2), *(int *)(v7 + 18), v10);
           }
         }
       }
--- a/ParticleEngine.h	Tue Oct 23 17:33:33 2012 +0600
+++ b/ParticleEngine.h	Tue Oct 23 17:34:20 2012 +0600
@@ -15,7 +15,7 @@
   float flt_14;
   float flt_18;
   unsigned int uDiffuse;
-  int field_20;
+  int timeToLive;
   unsigned int uTextureID;
   float flt_28;
   int field_2C;
@@ -30,15 +30,26 @@
 #pragma pack(push, 1)
 struct Particle
 {
-  int bFree;
+  int uType; // 0x0000: empty
+             // 0x0100: color plane
+             // 0x0200: line
+             // 0x0400: bitmap plane
+             // 0x0800: sprite plane
   float x;
   float y;
   float z;
   float flt_10;
   float flt_14;
   float flt_18;
-  int uParticleColor;
-  int field_20;
+  union
+  {
+    struct
+    {
+      unsigned char r, g, b, a;
+    };
+    unsigned int uParticleColor;
+  };
+  int timeToLive;
   unsigned int uTextureID;
   float flt_28;
   float _x;
@@ -48,10 +59,10 @@
   int _rotation;
   int uScreenSpaceX;
   int uScreenSpaceY;
-  float field_48;
-  int field_4C;
-  int field_50;
-  int field_54;
+  int uScreenSpaceZ;  // line end x
+  int uScreenSpaceW;  // line end y
+  int sZValue;
+  int sZValue2;  // line end z
   int field_58;
   float flt_5C;
   float flt_60;
@@ -84,7 +95,7 @@
   void ResetParticles();
   void AddParticle(Particle_ *a2);
   void Draw();
-  int UpdateParticles();
+  void   UpdateParticles();
   bool ViewProject_TrueIfStillVisible(unsigned int uParticleID);
   bool _48B5B3(unsigned int uID);
   void DrawParticles_BLV();
--- a/Player.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/Player.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -7,7 +7,7 @@
 #include "Party.h"
 #include "GUIButton.h"
 #include "LOD.h"
-#include "Monsters.h"
+#include "Monsters.h" 
 #include "GUIWindow.h"
 #include "Viewport.h"
 #include "Actor.h"
@@ -4656,7 +4656,7 @@
   {
     if ( !HasItemEquipped((ITEM_EQUIP_TYPE)v3) )
       goto LABEL_11;
-    v5 = *(int *)v4 - 1;                     // BUG
+    v5 = pEquipment.uOffHand  - 1;            // BUG
                                                 // v5 = _this->cEquippedItems.uOffHand - 1;
     if ( a2 != 17 )
       break;
--- a/Player.h	Tue Oct 23 17:33:33 2012 +0600
+++ b/Player.h	Tue Oct 23 17:34:20 2012 +0600
@@ -193,6 +193,29 @@
 #pragma pack(push, 1)
 struct Player
 {
+  enum Condition: unsigned __int32
+  {
+    Condition_Cursed = 0,
+    Condition_Weak = 1,
+    Condition_Sleep = 2,
+    Condition_Fear = 3,
+    Condition_Drunk = 4,
+    Condition_Insane = 5,
+    Condition_Poison1 = 6,
+    Condition_Disease1 = 7,
+    Condition_Posion2 = 8,
+    Condition_Disease2 = 9,
+    Condition_Poison3 = 10,
+    Condition_Disease3 = 11,
+    Condition_Paralyzed = 12,
+    Condition_Unconcious = 13,
+    Condition_Dead = 14,
+    Condition_Pertified = 15,
+    Condition_Eradicated = 16,
+    Condition_Zombie = 17,
+    Condition_Good = 18
+  };
+
   Player();
 
   void SetVariable(enum VariableType var, signed int a3);
@@ -315,6 +338,9 @@
   bool Recover(signed int a2);
   bool CanCastSpell(unsigned int uRequiredMana);
 
+  inline bool Dead()       {return pConditions[Condition::Condition_Dead] != 0;}
+  inline bool Eradicated() {return pConditions[Condition::Condition_Eradicated] != 0;}
+
 
 
   __int64 pConditions[20];
--- a/Render.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/Render.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -63,6 +63,7 @@
 
 
 
+void SetBillboardBlendOptions(RenderBillboardD3D::OpacityType a1);
 
 
 /*  384 */
@@ -173,11 +174,7 @@
 //----- (00440CB8) --------------------------------------------------------
 void Render::DrawBillboardList_BLV()
 {
-  int v0; // ebx@1
-  char *v1; // esi@2
   __int16 v2; // ax@3
-  unsigned __int16 *v3; // eax@6
-  char v4; // zf@6
   int v5; // eax@11
   RenderBillboardTransform_local0 soft_billboard; // [sp+4h] [bp-50h]@1
 
@@ -189,46 +186,38 @@
   soft_billboard.uViewportY = pBLVRenderParams->uViewportY;
   soft_billboard.uViewportZ = pBLVRenderParams->uViewportZ - 1;
   soft_billboard.uViewportW = pBLVRenderParams->uViewportW;
-  v0 = 0;
-  pOutdoorCamera->field_3C = uNumBillboardsToDraw;
-  if ( (signed int)uNumBillboardsToDraw > 0 )
-  {
-    v1 = (char *)&pBillboardRenderList[0].field_28;
-    do
-    {
-      soft_billboard.field_8 = *((short *)v1 - 1);
-      soft_billboard.uParentBillboardID = v0;
-      soft_billboard.field_C = *(short *)v1;
-      soft_billboard.field_10 = *((int *)v1 - 10);
-      soft_billboard.field_14 = *((int *)v1 - 9);
-      soft_billboard.field_28 = *((int *)v1 - 6);
-      soft_billboard.uFlags = *((short *)v1 - 5);
-      soft_billboard.uTintColor = *((int *)v1 + 1);
-      v2 = *((short *)v1 - 8);
+
+  pOutdoorCamera->uNumBillboards = uNumBillboardsToDraw;
+
+  for (uint i = 0; i < uNumBillboardsToDraw; ++i)
+  {
+    auto p = pBillboardRenderList + i;
+
+      soft_billboard.uScreenSpaceX = p->uScreenSpaceX;
+      soft_billboard.uParentBillboardID = i;
+      soft_billboard.uScreenSpaceY = p->uScreenSpaceY;
+      soft_billboard.field_10 = p->field_0;
+      soft_billboard.field_14 = p->field_4;
+      soft_billboard.sZValue = p->sZValue;
+      soft_billboard.uFlags = p->field_1E;
+      soft_billboard.uTintColor = p->uTintColor;
+      v2 = p->uHwSpriteID;
       if ( v2 != -1 )
       {
         if ( pRenderer->pRenderD3D )
-        {
-          pRenderer->_4A43B1(&soft_billboard, &pSprites_LOD->pHardwareSprites[v2], *((short *)v1 + 1));
-        }
+          pRenderer->DrawBillboard_Indoor(&soft_billboard, &pSprites_LOD->pHardwareSprites[v2], p->uPaletteSubindex);
         else
         {
-          v3 = PaletteManager::Get_Dark_or_Red_LUT(*((short *)v1 - 7), *((short *)v1 + 1), 1);
-          v4 = (*(v1 - 9) & 1) == 0;
-          soft_billboard.pPalette = v3;
-          if ( !v4 )
-            soft_billboard.pPalette = pPaletteManager->field_261600[*((short *)v1 - 7)];
+          soft_billboard.pPalette = PaletteManager::Get_Dark_or_Red_LUT(p->uPalette, p->uPaletteSubindex, 1);
+          if (p->field_1E & 0x0100)
+            soft_billboard.pPalette = pPaletteManager->field_261600[p->uPalette];
           if ( !(soft_billboard.uFlags & 0x40) && soft_billboard.uFlags & 0x80 )
-            soft_billboard.pPalette2 = PaletteManager::Get_Dark_or_Red_LUT(*((short *)v1 - 7), 0, 1);
-          v5 = *((short *)v1 - 8);
+            soft_billboard.pPalette2 = PaletteManager::Get_Dark_or_Red_LUT(p->uPalette, 0, 1);
+          v5 = p->uHwSpriteID;
           if ( v5 >= 0 )
             pSprites_LOD->pSpriteHeaders[v5]._4ACC38(&soft_billboard, 1);
         }
       }
-      ++v0;
-      v1 += 52;
-    }
-    while ( v0 < (signed int)uNumBillboardsToDraw );
   }
 }
 
@@ -2904,17 +2893,17 @@
   billboard.uViewportZ = pViewport->uViewportZ - 1;
   billboard.uViewportW = pViewport->uViewportW;
   v0 = 0;
-  pOutdoorCamera->field_3C = uNumBillboardsToDraw;
+  pOutdoorCamera->uNumBillboards = uNumBillboardsToDraw;
   v16 = 0;
   if ( (signed int)uNumBillboardsToDraw > 0 )
   {
     v17 = 0;
-    v1 = (char *)&pBillboardRenderList[0].field_28;
+    v1 = (char *)&pBillboardRenderList[0].uScreenSpaceY;
     do
     {
-      billboard.field_8 = *((short *)v1 - 1);
+      billboard.uScreenSpaceX = *((short *)v1 - 1);
       v2 = *((short *)v1 - 5);
-      billboard.field_C = *(short *)v1;
+      billboard.uScreenSpaceY = *(short *)v1;
       v3 = *((int *)v1 - 10);
       billboard.uParentBillboardID = v0;
       v4 = *((int *)v1 + 1);
@@ -2924,14 +2913,14 @@
       v6 = *((short *)v1 - 8);
       billboard.field_14 = v5;
       v7 = *((int *)v1 - 6);
-      billboard.field_28 = *((int *)v1 - 6);
+      billboard.sZValue = *((int *)v1 - 6);
       billboard.uFlags = v2;
       if ( v6 != -1 )
       {
         v8 = *((short *)v1 + 1);
         if ( pRenderer->pRenderD3D )
         {
-          billboard.field_28 = v7;
+          billboard.sZValue = v7;
           billboard.uFlags = v2;
           pRenderer->TransformBillboard(
             &billboard,
@@ -3141,17 +3130,17 @@
                   v3->pSpriteFrame = v28;
                   v3->field_4 = v26;
                   v3->field_1E = v46;
-                  v3->field_20 = x;
-                  v3->field_22 = y;
-                  v3->field_24 = z;
-                  v3->field_26 = v35;
-                  v3->field_28 = v32;
+                  v3->some_x = x;
+                  v3->some_y = y;
+                  v3->some_z = z;
+                  v3->uScreenSpaceX = v35;
+                  v3->uScreenSpaceY = v32;
                   HIWORD(v26) = HIWORD(v42);
                   LOWORD(v26) = 0;
                   v27 = (*(v0 - 2) & 0x20) == 0;
                   v3->sZValue = v26 + (8 * v41 | 2);
-                  v3->field_2A = 0;
-                  v3->field_2C_prolly_tint = 0;
+                  v3->uPaletteSubindex = 0;
+                  v3->uTintColor = 0;
                   if ( !v27 )
                   {
                     if ( !pRenderer->pRenderD3D )
@@ -3573,22 +3562,22 @@
                     v27->field_0 = v26;
                     v27->field_4 = v26;
                     v29 = v38;
-                    v27->field_26 = v25;
+                    v27->uScreenSpaceX = v25;
                     HIBYTE(v29) |= 2u;
                     v27->uPalette = v28;
                     v27->field_1E = v29;
-                    v27->field_20 = x;
-                    v27->field_22 = y;
-                    v27->field_24 = v36;
-                    v27->field_28 = v40;
+                    v27->some_x = x;
+                    v27->some_y = y;
+                    v27->some_z = v36;
+                    v27->uScreenSpaceY = v40;
                     HIWORD(v30) = HIWORD(v39);
                     v31 = 8 * v35 | 5;
                     LOWORD(v30) = 0;
                     v27->uIndoorSectorID = 0;
                     v27->sZValue = v30 + v31;
-                    v27->field_2A = 0;
+                    v27->uPaletteSubindex = 0;
                     v27->pSpriteFrame = v9;
-                    v27->field_2C_prolly_tint = 0;
+                    v27->uTintColor = 0;
                   }
                 }
                 goto LABEL_38;
@@ -3627,7 +3616,7 @@
           local_0.flt_14 = 0.0;
           local_0.flt_18 = 0.0;
           local_0.flt_28 = 1.0;
-          local_0.field_20 = (rand() & 0x80) + 128;
+          local_0.timeToLive = (rand() & 0x80) + 128;
           local_0.uTextureID = pBitmaps_LOD->LoadTexture("effpar01");
           pGame->pParticleEngine->AddParticle(&local_0);
         }
@@ -4511,7 +4500,7 @@
               *(int *)v34 = 0;
               v34 += 32;
               --v33;
-              *((int *)v34 - 9) = LODWORD(pRenderer->uFogColor) | v35 & 0xFF000000;
+              *((int *)v34 - 9) = pRenderer->uFogColor | v35 & 0xFF000000;
             }
             while ( v33 );
           }
@@ -4624,6 +4613,8 @@
   LOBYTE(v1->field_103668) = 0;
   v1->field_1036B8 = 0;
   v1->_gpu_memory_used = 0;
+  uNumBillboardsToDraw = 0;
+  bFogEnabled = false;
 }
 
 bool Render::Initialize(bool bWindowed, uint uDefaultDevice,
@@ -7116,29 +7107,10 @@
 }
 
 //----- (004A1EB6) --------------------------------------------------------
-void Render::SetGameRenderStates()
-{
-  Render *v1; // esi@1
-  unsigned int v2; // eax@1
-  RenderD3D *v3; // ecx@2
-  unsigned int uFogColor; // edi@6
-  IDirect3DDevice3 *v5; // eax@8
-  //IDirect3DDevice3Vtbl *v6; // ecx@8
-  RenderD3D *v7; // eax@9
-  RenderD3D *v8; // eax@9
-  std::string v9; // [sp-14h] [bp-2Ch]@4
-  IDirect3DDevice3 *v10; // [sp-8h] [bp-20h]@9
-  signed int v11; // [sp-4h] [bp-1Ch]@4
-  int v12; // [sp+0h] [bp-18h]@4
-  std::string *v13; // [sp+10h] [bp-8h]@4
-  int a3; // [sp+17h] [bp-1h]@4
-
-  v1 = this;
-  v2 = this->uNumD3DSceneBegins;
-  this->uNumD3DSceneBegins = v2 + 1;
-  if ( !v2 )
-  {
-    v3 = this->pRenderD3D;
+void Render::BeginSceneD3D()
+{
+  if (!uNumD3DSceneBegins++)
+  {
     if (pRenderD3D)
     {
       pRenderD3D->ClearTarget(1u, 0, 1u, 1.0);
@@ -7152,42 +7124,27 @@
         uFogColor = GetLevelFogColor();
       else
         uFogColor = 0;
-      v5 = v1->pRenderD3D->pDevice;
-      //v6 = v5->lpVtbl;
+
       if ( uFogColor & 0xFF000000 )
       {
-        v12 = 1;
-        v11 = 28;
-        v10 = v5;
-        pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1u);
-        //v7 = v1->pRenderD3D;
-        v12 = uFogColor & 0xFFFFFF;
-        v11 = 34;
-        //v10 = v7->pDevice;
+        pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1);
         pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, uFogColor & 0xFFFFFF);
-        v8 = v1->pRenderD3D;
-        *(float *)&v12 = 0.0;
-        v11 = 35;
-        //v10 = v8->pDevice;
         pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0);
-        v1->bUsingSpecular = 1;
+        bUsingSpecular = true;
       }
       else
       {
-        *(float *)&v12 = 0.0;
-        v11 = 28;
-        v10 = v5;
         pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0);
-        v1->bUsingSpecular = 0;
+        bUsingSpecular = 0;
       }
     }
     else
     {
-      LockRenderSurface((void **)&v1->pTargetSurface, &v1->uTargetSurfacePitch);
-      if ( v1->pTargetSurface )
-        v1->field_18_locked_pitch = v1->uTargetSurfacePitch;
+      LockRenderSurface((void **)&pTargetSurface, &uTargetSurfacePitch);
+      if (pTargetSurface)
+        field_18_locked_pitch = uTargetSurfacePitch;
       else
-        --v1->uNumD3DSceneBegins;
+        --uNumD3DSceneBegins;
     }
   }
 }
@@ -7195,23 +7152,19 @@
 //----- (004A1FE1) --------------------------------------------------------
 void Render::DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene()
 {
-  char v1; // zf@1
-
-  v1 = this->uNumD3DSceneBegins-- == 1;
-  if ( v1 )
-  {
-    if ( this->pRenderD3D )
-    {
-      pGame->draw_debug_outlines();
-      DoRenderBillboards_D3D();
-      pGame->pStru6Instance->RenderSpecialEffects();
-      pRenderD3D->pDevice->EndScene();
-    }
-    else
-    {
-      pGame->pStru6Instance->RenderSpecialEffects();
-    }
-  }
+  --uNumD3DSceneBegins;
+  if (uNumD3DSceneBegins)
+    return;
+
+  if (pRenderD3D)
+  {
+    pGame->draw_debug_outlines();
+    DoRenderBillboards_D3D();
+    pGame->pStru6Instance->RenderSpecialEffects();
+    pRenderD3D->pDevice->EndScene();
+  }
+  else
+    pGame->pStru6Instance->RenderSpecialEffects();
 }
 
 
@@ -7479,7 +7432,7 @@
               *(int *)v38 = 0;
               v38 += 32;
               --v37;
-              *((int *)v38 - 9) = LODWORD(pRenderer->uFogColor) | v39 & 0xFF000000;
+              *((int *)v38 - 9) = pRenderer->uFogColor | v39 & 0xFF000000;
             }
             while ( v37 );
           }
@@ -7866,7 +7819,7 @@
 
 
 //----- (004A43B1) --------------------------------------------------------
-void Render::_4A43B1(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *a3, int a4)
+void Render::DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *a3, int uPaletteSubindex)
 {
   RenderBillboardTransform_local0 *v4; // ebx@2
   double v5; // st7@2
@@ -7903,23 +7856,23 @@
   if ( this->uNumD3DSceneBegins )
   {
     v4 = pSoftBillboard;
-    v5 = (double)HIWORD(pSoftBillboard->field_28);
+    v5 = (double)HIWORD(pSoftBillboard->sZValue);
     pSoftBillboarda = v5;
     v6 = v5;
     v7 = Billboard_ProbablyAddToListAndSortByZOrder(LODWORD(v6));
-    v8 = a4;
+    v8 = uPaletteSubindex;
     v9 = v7;
-    v28 = a4 & 0xFF000000;
-    if ( a4 & 0xFF000000 )
-      pBillboardRenderListD3D[v9].bOpaque = 3;
+    v28 = uPaletteSubindex & 0xFF000000;
+    if ( uPaletteSubindex & 0xFF000000 )
+      pBillboardRenderListD3D[v9].uOpacity = RenderBillboardD3D::Opaque_3;
     else
-      pBillboardRenderListD3D[v9].bOpaque = 0;
+      pBillboardRenderListD3D[v9].uOpacity = RenderBillboardD3D::Transparent;
     v10 = a3;
     pBillboardRenderListD3D[v9].field_90 = v4->field_44;
-    pBillboardRenderListD3D[v9].field_94 = v4->field_28;
+    pBillboardRenderListD3D[v9].sZValue = v4->sZValue;
     pBillboardRenderListD3D[v9].uParentBillboardID = v4->uParentBillboardID;
-    v25 = v4->field_8;
-    v24 = v4->field_C;
+    v25 = v4->uScreenSpaceX;
+    v24 = v4->uScreenSpaceY;
     a1 = (double)(v4->field_10 & 0xFFFF) * 0.000015260186 + (double)HIWORD(v4->field_10);
     v29 = (double)(v4->field_14 & 0xFFFF) * 0.000015260186 + (double)HIWORD(v4->field_14);
     v31 = (double)((v10->uBufferWidth >> 1) - v10->uAreaX);
@@ -7956,39 +7909,39 @@
       v17 = v17 * -1.0;
     pBillboardRenderListD3D[v9].pQuards[1].specular = 0;
     pBillboardRenderListD3D[v9].pQuards[1].diffuse = v12;
-    *(float *)(v9 * 156 + 15684320) = v13 - v17 * a1;
-    *(float *)(v9 * 156 + 15684324) = v32 - v18 * v29;
-    *(float *)(v9 * 156 + 15684328) = v15;
-    *(float *)(v9 * 156 + 15684332) = v16;
-    *(float *)(v9 * 156 + 15684344) = 0.0;
-    *(float *)(v9 * 156 + 15684348) = 1.0;
+    pBillboardRenderListD3D[v9].pQuards[1].pos.x = v13 - v17 * a1;
+    pBillboardRenderListD3D[v9].pQuards[1].pos.y = v32 - v18 * v29;
+    pBillboardRenderListD3D[v9].pQuards[1].pos.z = v15;
+    pBillboardRenderListD3D[v9].pQuards[1].rhw = v16;
+    pBillboardRenderListD3D[v9].pQuards[1].texcoord.x = 0.0;
+    pBillboardRenderListD3D[v9].pQuards[1].texcoord.y = 1.0;
     v19 = v10->uBufferHeight - v10->uAreaY - v10->uAreaHeight;
     v20 = (double)(v10->uAreaX + v10->uAreaWidth + (v10->uBufferWidth >> 1) - v10->uBufferWidth);
     if ( v4->uFlags & 4 )
       v20 = v20 * -1.0;
     pBillboardRenderListD3D[v9].pQuards[2].specular = 0;
     pBillboardRenderListD3D[v9].pQuards[2].diffuse = v12;
-    *(float *)(v9 * 156 + 15684352) = v20 * a1 + v13;
-    *(float *)(v9 * 156 + 15684356) = v32 - (double)v19 * v29;
-    *(float *)(v9 * 156 + 15684360) = v15;
-    *(float *)(v9 * 156 + 15684364) = v16;
-    *(float *)(v9 * 156 + 15684376) = 1.0;
-    *(float *)(v9 * 156 + 15684380) = 1.0;
+    pBillboardRenderListD3D[v9].pQuards[2].pos.x = v20 * a1 + v13;
+    pBillboardRenderListD3D[v9].pQuards[2].pos.y = v32 - (double)v19 * v29;
+    pBillboardRenderListD3D[v9].pQuards[2].pos.z = v15;
+    pBillboardRenderListD3D[v9].pQuards[2].rhw = v16;
+    pBillboardRenderListD3D[v9].pQuards[2].texcoord.x = 1.0;
+    pBillboardRenderListD3D[v9].pQuards[2].texcoord.y = 1.0;
     v21 = v10->uBufferHeight - v10->uAreaY;
     v22 = (double)(v10->uAreaX + v10->uAreaWidth + (v10->uBufferWidth >> 1) - v10->uBufferWidth);
     if ( v4->uFlags & 4 )
       v22 = v22 * -1.0;
     pBillboardRenderListD3D[v9].pQuards[3].specular = 0;
     pBillboardRenderListD3D[v9].pQuards[3].diffuse = v12;
-    *(float *)(v9 * 156 + 15684384) = v22 * a1 + v13;
-    *(float *)(v9 * 156 + 15684388) = v32 - (double)v21 * v29;
-    *(float *)(v9 * 156 + 15684392) = v15;
-    *(float *)(v9 * 156 + 15684396) = v16;
-    *(float *)(v9 * 156 + 15684408) = 1.0;
-    *(float *)(v9 * 156 + 15684412) = 0.0;
+    pBillboardRenderListD3D[v9].pQuards[3].pos.x = v22 * a1 + v13;
+    pBillboardRenderListD3D[v9].pQuards[3].pos.y = v32 - (double)v21 * v29;
+    pBillboardRenderListD3D[v9].pQuards[3].pos.z = v15;
+    pBillboardRenderListD3D[v9].pQuards[3].rhw = v16;
+    pBillboardRenderListD3D[v9].pQuards[3].texcoord.x = 1.0;
+    pBillboardRenderListD3D[v9].pQuards[3].texcoord.y = 0.0;
     v23 = v10->pTexture;
     pBillboardRenderListD3D[v9].uNumVertices = 4;
-    *(float *)(v9 * 156 + 15684416) = pSoftBillboarda;
+    pBillboardRenderListD3D[v9].flt_88 = pSoftBillboarda;
     pBillboardRenderListD3D[v9].pTexture = v23;
   }
 }
@@ -8043,18 +7996,18 @@
 
   if ( this->uNumD3DSceneBegins )
   {
-    if ( HIWORD(a2->field_28) )
-    {
-      v5 = (double)HIWORD(a2->field_28);
+    if ( HIWORD(a2->sZValue) )
+    {
+      v5 = (double)HIWORD(a2->sZValue);
       v6 = v5;
       v7 = v5;
       v8 = Billboard_ProbablyAddToListAndSortByZOrder(LODWORD(v7));
-      pBillboardRenderListD3D[v8].bOpaque = 1;
+      pBillboardRenderListD3D[v8].uOpacity = RenderBillboardD3D::Opaque_1;
       pBillboardRenderListD3D[v8].field_90 = a2->field_44;
-      pBillboardRenderListD3D[v8].field_94 = a2->field_28;
+      pBillboardRenderListD3D[v8].sZValue = a2->sZValue;
       pBillboardRenderListD3D[v8].uParentBillboardID = a2->uParentBillboardID;
-      v9 = a2->field_8;
-      v10 = a2->field_C;
+      v9 = a2->uScreenSpaceX;
+      v10 = a2->uScreenSpaceY;
       v11 = (double)(a2->field_10 & 0xFFFF) * 0.000015260186 + (double)HIWORD(a2->field_10);
       v12 = (double)v9;
       v13 = v12;
@@ -8077,7 +8030,7 @@
            + ((double)(unsigned __int16)v20 * 0.000015259022 + (double)(v20 >> 16)) * v16
            - 12.0)
           * v11
-          + (double)a2->field_C;
+          + (double)a2->uScreenSpaceY;
       pBillboardRenderListD3D[v8].pQuards[0].specular = 0;
       pBillboardRenderListD3D[v8].pQuards[0].diffuse = uDiffuse;
       pBillboardRenderListD3D[v8].pQuards[0].pos.y = v22;
@@ -8085,8 +8038,8 @@
       pBillboardRenderListD3D[v8].pQuards[0].rhw = 1.0 / v6;
       pBillboardRenderListD3D[v8].pQuards[0].texcoord.x = 0.0;
       pBillboardRenderListD3D[v8].pQuards[0].texcoord.y = 0.0;
-      v23 = (double)(a2->field_8 - 12) - v13;
-      v24 = (double)a2->field_C - v15;
+      v31 = (double)(a2->uScreenSpaceX + 12) - v13;
+      v32 = (double)a2->uScreenSpaceY - v15;
       v25 = stru_5C6E00->SinCos(angle);
       v26 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi);
       v27 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi);
@@ -8102,7 +8055,7 @@
            + ((double)(unsigned __int16)v27 * 0.000015259022 + (double)(v27 >> 16)) * v23
            - 12.0)
           * v11
-          + (double)a2->field_C;
+          + (double)a2->uScreenSpaceY;
       pBillboardRenderListD3D[v8].pQuards[1].pos.z = pRenderer->pBillboardRenderListD3D[v8].pQuards[0].pos.z;
       v30 = pBillboardRenderListD3D[v8].pQuards[0].rhw;
       pBillboardRenderListD3D[v8].pQuards[1].pos.y = v29;
@@ -8111,8 +8064,8 @@
       pBillboardRenderListD3D[v8].pQuards[1].diffuse = uDiffuse;
       pBillboardRenderListD3D[v8].pQuards[1].texcoord.x = 0.0;
       pBillboardRenderListD3D[v8].pQuards[1].texcoord.y = 1.0;
-      v31 = (double)(a2->field_8 + 12) - v13;
-      v32 = (double)a2->field_C - v15;
+      v23 = (double)(a2->uScreenSpaceX - 12) - v13;
+      v24 = (double)a2->uScreenSpaceY - v15;
       v33 = stru_5C6E00->SinCos(angle);
       v34 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi);
       v35 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi);
@@ -8129,7 +8082,7 @@
            + ((double)(unsigned __int16)v35 * 0.000015259022 + (double)(v35 >> 16)) * v31
            - 12.0)
           * v11
-          + (double)a2->field_C;
+          + (double)a2->uScreenSpaceY;
       pBillboardRenderListD3D[v8].pQuards[2].specular = 0;
       pBillboardRenderListD3D[v8].pQuards[2].pos.z = v37;
       pBillboardRenderListD3D[v8].pQuards[2].rhw = pBillboardRenderListD3D[v8].pQuards[0].rhw;
@@ -8137,8 +8090,8 @@
       pBillboardRenderListD3D[v8].pQuards[2].pos.y = v38;
       pBillboardRenderListD3D[v8].pQuards[2].texcoord.x = 1.0;
       pBillboardRenderListD3D[v8].pQuards[2].texcoord.y = 1.0;
-      v39 = (double)(a2->field_8 + 12) - v13;
-      v40 = (double)(a2->field_C - 25) - v15;
+      v39 = (double)(a2->uScreenSpaceX + 12) - v13;
+      v40 = (double)(a2->uScreenSpaceY - 25) - v15;
       v41 = stru_5C6E00->SinCos(angle);
       v42 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi);
       v43 = stru_5C6E00->SinCos(angle - stru_5C6E00->uIntegerHalfPi);
@@ -8154,7 +8107,7 @@
            + ((double)(unsigned __int16)v43 * 0.000015259022 + (double)(v43 >> 16)) * v39
            - 12.0)
           * v11
-          + (double)a2->field_C;
+          + (double)a2->uScreenSpaceY;
       v46 = pBillboardRenderListD3D[v8].pQuards[0].pos.z;
       pBillboardRenderListD3D[v8].pQuards[3].specular = 0;
       pBillboardRenderListD3D[v8].pQuards[3].pos.z = v46;
@@ -8219,16 +8172,16 @@
 
   if ( this->uNumD3DSceneBegins )
   {
-    v5 = (double)HIWORD(a2->field_28);
+    v5 = (double)HIWORD(a2->sZValue);
     v6 = v5;
     v7 = v5;
     v8 = Billboard_ProbablyAddToListAndSortByZOrder(LODWORD(v7));
-    pBillboardRenderListD3D[v8].bOpaque = 1;
+    pBillboardRenderListD3D[v8].uOpacity = RenderBillboardD3D::Opaque_1;
     pBillboardRenderListD3D[v8].field_90 = a2->field_44;
-    pBillboardRenderListD3D[v8].field_94 = a2->field_28;
+    pBillboardRenderListD3D[v8].sZValue = a2->sZValue;
     pBillboardRenderListD3D[v8].uParentBillboardID = a2->uParentBillboardID;
-    v9 = a2->field_8;
-    v10 = a2->field_C;
+    v9 = a2->uScreenSpaceX;
+    v10 = a2->uScreenSpaceY;
     v11 = (double)(a2->field_10 & 0xFFFF) * 0.000015260186 + (double)HIWORD(a2->field_10);
     v12 = (double)v9;
     v13 = v12;
@@ -8252,7 +8205,7 @@
          + ((double)(unsigned __int16)v21 * 0.000015259022 + (double)(v21 >> 16)) * v16
          - 12.0)
         * v11
-        + (double)a2->field_C;
+        + (double)a2->uScreenSpaceY;
     pBillboardRenderListD3D[v8].pQuards[0].specular = 0;
     pBillboardRenderListD3D[v8].pQuards[0].diffuse = uDiffuse;
     pBillboardRenderListD3D[v8].pQuards[0].pos.y = v23;
@@ -8262,8 +8215,8 @@
     pBillboardRenderListD3D[v8].pQuards[0].rhw = v25;
     pBillboardRenderListD3D[v8].pQuards[0].texcoord.x = 0.0;
     pBillboardRenderListD3D[v8].pQuards[0].texcoord.y = 0.0;
-    v26 = (double)(a2->field_8 - 12) - v13;
-    v27 = (double)a2->field_C - v15;
+    v26 = (double)(a2->uScreenSpaceX - 12) - v13;
+    v27 = (double)a2->uScreenSpaceY - v15;
     v28 = stru_5C6E00->SinCos(angle);
     v29 = stru_5C6E00->SinCos(v19);
     v30 = stru_5C6E00->SinCos(v19);
@@ -8279,7 +8232,7 @@
          + ((double)(unsigned __int16)v30 * 0.000015259022 + (double)(v30 >> 16)) * v26
          - 12.0)
         * v11
-        + (double)a2->field_C;
+        + (double)a2->uScreenSpaceY;
     pBillboardRenderListD3D[v8].pQuards[1].pos.z = v24;
     pBillboardRenderListD3D[v8].pQuards[1].pos.y = v32;
     pBillboardRenderListD3D[v8].pQuards[1].specular = 0;
@@ -8287,8 +8240,8 @@
     pBillboardRenderListD3D[v8].pQuards[1].diffuse = uDiffuse;
     pBillboardRenderListD3D[v8].pQuards[1].texcoord.x = 0.0;
     pBillboardRenderListD3D[v8].pQuards[1].texcoord.y = 1.0;
-    v33 = (double)(a2->field_8 + 12) - v13;
-    v34 = (double)a2->field_C - v15;
+    v33 = (double)(a2->uScreenSpaceX + 12) - v13;
+    v34 = (double)a2->uScreenSpaceY - v15;
     v35 = stru_5C6E00->SinCos(angle);
     v36 = stru_5C6E00->SinCos(v19);
     v37 = stru_5C6E00->SinCos(v19);
@@ -8304,7 +8257,7 @@
          + ((double)(unsigned __int16)v37 * 0.000015259022 + (double)(v37 >> 16)) * v33
          - 12.0)
         * v11
-        + (double)a2->field_C;
+        + (double)a2->uScreenSpaceY;
     pBillboardRenderListD3D[v8].pQuards[2].specular = 0;
     pBillboardRenderListD3D[v8].pQuards[2].pos.z = v24;
     pBillboardRenderListD3D[v8].pQuards[2].rhw = v25;
@@ -8312,8 +8265,8 @@
     pBillboardRenderListD3D[v8].pQuards[2].pos.y = v39;
     pBillboardRenderListD3D[v8].pQuards[2].texcoord.x = 1.0;
     pBillboardRenderListD3D[v8].pQuards[2].texcoord.y = 1.0;
-    v40 = (double)(a2->field_8 + 12) - v13;
-    v41 = (double)(a2->field_C - 25) - v15;
+    v40 = (double)(a2->uScreenSpaceX + 12) - v13;
+    v41 = (double)(a2->uScreenSpaceY - 25) - v15;
     v42 = stru_5C6E00->SinCos(angle);
     v43 = stru_5C6E00->SinCos(v19);
     v44 = stru_5C6E00->SinCos(v19);
@@ -8329,7 +8282,7 @@
          + ((double)(unsigned __int16)v44 * 0.000015259022 + (double)(v44 >> 16)) * v40
          - 12.0)
         * v11
-        + (double)a2->field_C;
+        + (double)a2->uScreenSpaceY;
     pBillboardRenderListD3D[v8].pQuards[3].specular = 0;
     pBillboardRenderListD3D[v8].pQuards[3].pos.z = v24;
     pBillboardRenderListD3D[v8].pQuards[3].rhw = v25;
@@ -8383,20 +8336,20 @@
   if ( a1->uNumD3DSceneBegins )
   {
     v5 = a2;
-    v6 = (double)HIWORD(a2->field_28);
+    v6 = (double)HIWORD(a2->sZValue);
     v31 = v6;
     v7 = v6;
     v8 = Billboard_ProbablyAddToListAndSortByZOrder(LODWORD(v7));
     if ( BYTE3(v5->uTintColor) )
-      pBillboardRenderListD3D[v8].bOpaque = 3;
+      pBillboardRenderListD3D[v8].uOpacity = RenderBillboardD3D::Opaque_3;
     else
-      pBillboardRenderListD3D[v8].bOpaque = 0;
+      pBillboardRenderListD3D[v8].uOpacity = RenderBillboardD3D::Transparent;
     v9 = pSprite;
     pBillboardRenderListD3D[v8].field_90 = v5->field_44;
-    pBillboardRenderListD3D[v8].field_94 = v5->field_28;
+    pBillboardRenderListD3D[v8].sZValue = v5->sZValue;
     pBillboardRenderListD3D[v8].uParentBillboardID = v5->uParentBillboardID;
-    v24 = v5->field_8;
-    v23 = v5->field_C;
+    v24 = v5->uScreenSpaceX;
+    v23 = v5->uScreenSpaceY;
     v30 = (double)(v5->field_10 & 0xFFFF) * 0.000015260186 + (double)HIWORD(v5->field_10);
     v29 = (double)(v5->field_14 & 0xFFFF) * 0.000015260186 + (double)HIWORD(v5->field_14);
     pSpritea = (double)((v9->uBufferWidth >> 1) - v9->uAreaX);
@@ -8481,7 +8434,7 @@
 
 
 //----- (004A48E4) --------------------------------------------------------
-int Render::_4A48E4(int a2, int a3, int a4, int a5, int a6)
+int Render::MakeParticleBillboardAndPush_BLV_Software(int screenSpaceX, int screenSpaceY, int z, int lightColor, int a6)
 {
   int v6; // ecx@1
   int v7; // ebx@1
@@ -8498,8 +8451,8 @@
   unsigned int v18; // [sp+28h] [bp+Ch]@1
   int v19; // [sp+34h] [bp+18h]@1
 
-  v6 = a2;
-  v7 = (a6 >> 1) + a3;
+  v6 = screenSpaceX;
+  v7 = (a6 >> 1) + screenSpaceY;
   v17 = 0;
   v15 = 0;
   v8 = (a6 >> 1) + v6;
@@ -8507,22 +8460,22 @@
   v9 = 2 * (a6 >> 1);
   v10 = (a6 >> 1) * ((a6 >> 1) - 1);
   x = v8 - (a6 >> 1);
-  v16 = (a6 >> 1) + a3 - v8;
+  v16 = (a6 >> 1) + screenSpaceY - v8;
   v19 = a6 >> 1;
   v13 = v9;
   v18 = v8;
   do
   {
-    sub_4A46E6(x, v16 + v18, a4, 2 * v19, a5);
+    sr_4A46E6_draw_particle_segment(x, v16 + v18, z, 2 * v19, lightColor);
     if ( v15 )
-      sub_4A46E6(x, v17 + v7, a4, 2 * v19, a5);
+      sr_4A46E6_draw_particle_segment(x, v17 + v7, z, 2 * v19, lightColor);
     v14 -= v15;
     if ( v14 <= v10 )
     {
       if ( v19 != v17 )
       {
-        sub_4A46E6(v18, v16 + x, a4, 2 * v17, a5);
-        sub_4A46E6(v18, v19 + v7, a4, 2 * v17, a5);
+        sr_4A46E6_draw_particle_segment(v18, v16 + x, z, 2 * v17, lightColor);
+        sr_4A46E6_draw_particle_segment(v18, v19 + v7, z, 2 * v17, lightColor);
       }
       --v19;
       v13 -= 2;
@@ -8713,7 +8666,7 @@
     v6 = 0;
     pBillboardRenderListD3D[v5].field_90 = 0;
     pBillboardRenderListD3D[v5].uParentBillboardID = -1;
-    pBillboardRenderListD3D[v5].bOpaque = 2;
+    pBillboardRenderListD3D[v5].uOpacity = RenderBillboardD3D::Opaque_2;
     if ( a1->field_10 > 0 )
     {
       v7 = (char *)&a1->field_14[62];
@@ -8755,22 +8708,12 @@
 //----- (004A4DE1) --------------------------------------------------------
 bool Render::LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture)
 {
-  //const char *v5; // ebx@1
-  //Render *v6; // edi@1
-  //HWLTexture *pHWLTexture; // esi@1
-  //signed int result; // eax@1
-  //IDirectDrawSurface **v9; // ebx@9
-  //IDirectDrawSurface4 *v10; // edi@11
-  //int v11; // ebx@11
   HRESULT v12; // eax@14
   unsigned __int16 *v13; // ecx@19
   unsigned __int16 *v14; // eax@19
   DWORD v15; // edx@20
   HRESULT v16; // eax@23
   stru350 Dst; // [sp+Ch] [bp-F8h]@12
-  //DDSURFACEDESC2 desc; // [sp+6Ch] [bp-98h]@13
-  //DDSCAPS2 v19; // [sp+E8h] [bp-1Ch]@13
-  //int v20; // [sp+100h] [bp-4h]@12
 
   auto pHWLTexture = pD3DBitmaps.LoadTexture(pName, bMipMaps);
   if ( pHWLTexture )
@@ -11269,4 +11212,101 @@
   fread(pSpriteOffsets, 4, uNumItems, pFile);
 
   return true;
-}
\ No newline at end of file
+}
+
+
+
+
+
+
+
+
+
+//----- (004A1C1E) --------------------------------------------------------
+void DoRenderBillboards_D3D()
+{
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 3u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 1u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 0));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1u));
+
+  for (uint i = pRenderer->uNumBillboardsToDraw - 1; i != (uint)-1; --i)
+  {
+    auto p = pRenderer->pBillboardRenderListD3D + i;
+
+    if (p->uOpacity != RenderBillboardD3D::InvalidOpacity)
+      SetBillboardBlendOptions(p->uOpacity);
+    
+    ErrD3D(pRenderer->pRenderD3D->pDevice->SetTexture(0, p->pTexture));
+    ErrD3D(pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,
+        D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
+        p->pQuards,
+        p->uNumVertices,
+        D3DDP_DONOTLIGHT | D3DDP_DONOTUPDATEEXTENTS));
+  }
+
+  if (pRenderer->bFogEnabled)
+  {
+    pRenderer->bFogEnabled = false;
+    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1));
+    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF));
+    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0));
+  }
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 2));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 0));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1u));
+  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 1u));
+}
+
+
+
+
+
+//----- (004A1DA8) --------------------------------------------------------
+void SetBillboardBlendOptions(RenderBillboardD3D::OpacityType a1)
+{
+  switch (a1)
+  {
+    case RenderBillboardD3D::Transparent:
+    {
+      if (pRenderer->bFogEnabled)
+      {
+        pRenderer->bFogEnabled = false;
+        ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1u));
+        ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF));
+        ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0));
+      }
+
+      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 5));
+      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 6u));
+      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 1));
+    }
+    break;
+
+    case RenderBillboardD3D::Opaque_1:
+    case RenderBillboardD3D::Opaque_2:
+    case RenderBillboardD3D::Opaque_3:
+    {
+      if (pRenderer->bUsingSpecular)
+      {
+        if (!pRenderer->bFogEnabled)
+        {
+          pRenderer->bFogEnabled = true;
+          ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0));
+        }
+      }
+
+      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2));
+      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 2u));
+      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 0));
+    }
+    break;
+
+    default:
+      Log::Warning(L"SetBillboardBlendOptions: invalid opacity type (%u)", a1);
+    break;
+  }
+}
+
--- a/Render.h	Tue Oct 23 17:33:33 2012 +0600
+++ b/Render.h	Tue Oct 23 17:34:20 2012 +0600
@@ -18,6 +18,10 @@
 #pragma pack(push, 1)
 struct RenderVertexSoft
 {
+  inline RenderVertexSoft():
+    flt_2C(0.0f)
+  {}
+
   Vec3_float_ vWorldPosition;
   Vec3_float_ vWorldViewPosition;
   float vWorldViewProjX;
@@ -58,13 +62,13 @@
   __int16 uPalette;
   __int16 uIndoorSectorID;
   __int16 field_1E;
-  __int16 field_20;
-  __int16 field_22;
-  __int16 field_24;
-  __int16 field_26;
-  __int16 field_28;
-  __int16 field_2A;
-  int field_2C_prolly_tint;
+  __int16 some_x;
+  __int16 some_y;
+  __int16 some_z;
+  __int16 uScreenSpaceX;
+  __int16 uScreenSpaceY;
+  unsigned __int16 uPaletteSubindex;
+  unsigned int uTintColor;
   SpriteFrame *pSpriteFrame;
 };
 #pragma pack(pop)
@@ -167,13 +171,22 @@
 #pragma pack(push, 1)
 struct RenderBillboardD3D
 {
+  enum OpacityType: unsigned __int32
+  {
+    Transparent = 0,
+    Opaque_1 = 1,
+    Opaque_2 = 2,
+    Opaque_3 = 3,
+    InvalidOpacity = 0xFFFFFFFF
+  };
+
   IDirect3DTexture2 *pTexture;
   unsigned int uNumVertices;
   RenderVertexD3D3 pQuards[4];
   float flt_88;
-  unsigned int bOpaque;
+  OpacityType uOpacity;
   int field_90;
-  int field_94;
+  int sZValue;
   unsigned int uParentBillboardID;
 };
 #pragma pack(pop)
@@ -291,7 +304,7 @@
   unsigned int Billboard_ProbablyAddToListAndSortByZOrder(unsigned int a1);
   unsigned int GetBillboardDrawListSize();
   unsigned int GetParentBillboardID(unsigned int uBillboardID);
-  void SetGameRenderStates();
+  void BeginSceneD3D();
   void DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene();
   unsigned int GetActorTintColor(float a2, int a3, int a4, int a5, RenderBillboard *a6);
   void DrawPolygon(unsigned int uNumVertices, stru148 *a3, ODMFace *a4, IDirect3DTexture2 *pTexture);
@@ -302,8 +315,8 @@
   void MakeParticleBillboardAndPush_BLV(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle);
   void MakeParticleBillboardAndPush_ODM(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle);
   void TransformBillboard(RenderBillboardTransform_local0 *a2, Sprite *pSprite, int a1a, RenderBillboard *pBillboard);
-  void _4A43B1(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *a3, int a4);
-  int _4A48E4(int a2, int a3, int a4, int a5, int a6);
+  void DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *a3, int uPaletteSubindex);
+  int MakeParticleBillboardAndPush_BLV_Software(int screenSpaceX, int screenSpaceY, int z, int lightColor, int a6);
   void DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9);
   void _4A4CC9(struct stru6_stru1_indoor_sw_billboard *a1, int a2);
   bool LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture);
@@ -409,7 +422,7 @@
   unsigned int uMinDeviceTextureDim;
   int field_10365C;
   unsigned int bUsingSpecular;
-  float uFogColor;
+  uint uFogColor;
   int field_103668;
   unsigned int pHDWaterBitmapIDs[7];
   char field_103688[32];
@@ -421,7 +434,7 @@
   int _gpu_memory_used;
   void (__cdecl *pBeforePresentFunction)();
   int field_1036C4;
-  int turnFogOn;
+  uint bFogEnabled;
   int field_1036CC;
   RenderBillboardD3D pBillboardRenderListD3D[1000];
   unsigned int uNumBillboardsToDraw;
@@ -444,14 +457,14 @@
 {
   unsigned __int16 *pTarget;
   int *pTargetZ;
-  int field_8;
-  int field_C;
+  int uScreenSpaceX;
+  int uScreenSpaceY;
   int field_10;
   int field_14;
   char field_18[8];
   unsigned __int16 *pPalette;
   unsigned __int16 *pPalette2;
-  int field_28;
+  int sZValue;
   unsigned int uFlags;
   unsigned int uTargetPitch;
   unsigned int uViewportX;
--- a/Texture.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/Texture.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -1141,8 +1141,10 @@
   unsigned __int8 v28; // [sp+9Bh] [bp-1h]@54
 
   v4 = this;
-  if ( pFile )
-  {
+  if (!pFile)
+    return 1;
+ 
+
     fread(&pcxh1, 1u, 1u, pFile);
     fread(&pcxh1.version, 1u, 1u, pFile);
     fread(&pcxh1.encoding, 1u, 1u, pFile);
@@ -1419,11 +1421,7 @@
     {
       result = 3;
     }
-  }
-  else
-  {
-    result = 1;
-  }
+
   return result;
 }
 
--- a/Vis.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/Vis.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -361,6 +361,7 @@
   v17 = 0;
   for ( a1.flt_2C = 0.0; v17 < (signed int)pStru170->uNumFaceIDs; ++v17 )
   {
+    __debugbreak();
     v6 = pStru170->pFaceIDs[2 * v5];
     if ( v6 >= 0 )
     {
@@ -1600,20 +1601,17 @@
 //----- (004C0646) --------------------------------------------------------
 bool Vis::PickMouse(float fDepth, float fMouseX, float fMouseY, stru157 *a5, stru157 *a6)
 {
-  Vis *v6; // esi@1
-  bool result; // eax@4
   RenderVertexSoft pMouseRay[2]; // [sp+1Ch] [bp-60h]@1
 
-  v6 = this;
-  this->stru1.uNumPointers = 0;
+  stru1.uNumPointers = 0;
   CastPickRay(pMouseRay, fMouseX, fMouseY, fDepth);
-  PickBillboards(fDepth, fMouseX, fMouseY, &v6->stru1, a5);
+  PickBillboards(fDepth, fMouseX, fMouseY, &stru1, a5);
   if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
-    PickIndoor(fDepth, pMouseRay, &v6->stru1, a6);
+    PickIndoor(fDepth, pMouseRay, &stru1, a6);
   else
-    PickOutdoor(fDepth, pMouseRay, &v6->stru1, a6, 0);
-  v6->stru1.create_object_pointers(0);
-  sort_object_pointers(v6->stru1.array_1804, 0, v6->stru1.uNumPointers - 1);
+    PickOutdoor(fDepth, pMouseRay, &stru1, a6, 0);
+  stru1.create_object_pointers(0);
+  sort_object_pointers(stru1.array_1804, 0, stru1.uNumPointers - 1);
   return true;
 }
 
--- a/mm7_1.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/mm7_1.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -626,7 +626,7 @@
     &stru_AA1058[3].pSounds[6972 * v1 + 40720],
     pClassNames[stru_AA1058[3].pSounds[6972 * v1 + 40737]]);
   strcat(pTmpBuf, Source);
-  strcat(pTmpBuf, byte_4E2FD4);
+  strcat(pTmpBuf, "\xC" "00000");
   pGUIWindow_CurrentMenu->DrawText(pFontArrus, 24, 18, 0, pTmpBuf, 0, 0, 0);
   result = dword_506528;
   a1.uFrameX = 12;
@@ -1352,9 +1352,9 @@
     v0 = uGameUIFontMain;
     v1 = uGameUIFontShadow;
     v2 = sub_44100D() != 0 ? 381 : 322;
-    sprintfex(pTmpBuf, "\r087%lu", pParty->uNumFoodRations);
+    sprintf(pTmpBuf, "\r087%lu", pParty->uNumFoodRations);
     pGUIWindow0->DrawText(pFontSmallnum, 0, v2, v0, pTmpBuf, 0, 0, v1);
-    sprintfex(pTmpBuf, "\r028%lu", pParty->uNumGold);
+    sprintf(pTmpBuf, "\r028%lu", pParty->uNumGold);
     pGUIWindow0->DrawText(pFontSmallnum, 0, v2, v0, pTmpBuf, 0, 0, v1);
   }
 }
@@ -3093,12 +3093,12 @@
   v106.uViewportY = v12;
   v106.uViewportW = v12 + 128;
   v106.uViewportZ = v106.uViewportX + 128;
-  v106.field_8 = (signed int)(v106.uViewportX + 128 + v106.uViewportX) / 2;
+  v106.uScreenSpaceX = (signed int)(v106.uViewportX + 128 + v106.uViewportX) / 2;
   v106.field_10 = 65536;
   v106.field_14 = 65536;
-  v106.field_C = v115 + v12 + *(short *)(v11 + 18);
+  v106.uScreenSpaceY = v115 + v12 + *(short *)(v11 + 18);
   v106.pPalette = PaletteManager::Get_Dark_or_Red_LUT(v10->uPaletteIndex, 0, 1);
-  v106.field_28 = 0;
+  v106.sZValue = 0;
   v106.uFlags = 0;
   pRenderer->Clip_v2(0, 0, 0x27Fu, 0x1DFu);
   pRenderer->FillRect(v106.uViewportX - 1, v106.uViewportY - 1, v106.uViewportX + 129, v106.uViewportY - 1, a5);
@@ -3113,7 +3113,7 @@
   if ( pRenderer->pRenderD3D )
   {
     v13 = &pSprites_LOD->pHardwareSprites[v10->pHwSpriteIDs[0]];
-    v106.field_C = v115 + v106.uViewportY + v13->uBufferHeight;
+    v106.uScreenSpaceY = v115 + v106.uViewportY + v13->uBufferHeight;
     v222 = (IDirectDrawSurface *)v13->pTextureSurface;
     memset(&Dst, 0, 0x64u);
     Dst.dwSize = 100;
@@ -3127,13 +3127,13 @@
     v15 = v13->uAreaX;
     v119 = (signed int)v120 / 2;
     i = 0;
-    a4 = (char *)(v106.field_8 + v15 - (signed int)v120 / 2);
+    a4 = (char *)(v106.uScreenSpaceX + v15 - (signed int)v120 / 2);
     v115 = v13->uAreaY;
     v16 = v13->uAreaWidth + (signed int)v120 / 2 + v15 - (int)v120;
-    v124 = v106.field_C + v115 - v14;
+    v124 = v106.uScreenSpaceY + v115 - v14;
     v17 = v13->uAreaHeight + v115 - v14;
-    v116 = v106.field_8 + v16;
-    v119 = v106.field_C + v17;
+    v116 = v106.uScreenSpaceX + v16;
+    v119 = v106.uScreenSpaceY + v17;
     if ( (signed int)a4 < (signed int)v106.uViewportX )
     {
       v18 = v106.uViewportX - (int)a4;
@@ -3633,7 +3633,9 @@
   v60 = v59->pMonsterInfo.uSpell2ID;
   if ( v60 )
   {
-    sprintfex(pTmpBuf, &byte_4E3318, 0, pSpellStats->pInfos[v60].pShortName);
+    __debugbreak();
+    const char *fmt = "\xC\x25\x30\x35\x75\x9\x30\x36\x30\x25\x73\n";
+    sprintfex(pTmpBuf, fmt, 0, pSpellStats->pInfos[v60].pShortName);
     a1->DrawText(v56, 150, (int)a4, a5, pTmpBuf, 0, 0, 0);
     v58 = LOBYTE(v56->uFontHeight);
     a4 = &a4[v58 - 3];
@@ -4980,7 +4982,6 @@
 //----- (00420EFF) --------------------------------------------------------
 void __cdecl GameUI_WritePointedObjectStatusString()
 {
-  unsigned int zero; // edi@1
   int v1; // ebx@6
   GUIWindow *v2; // edi@7
   GUIButton *i; // ecx@11
@@ -5027,7 +5028,6 @@
   unsigned int pY; // [sp+D8h] [bp-8h]@1
   unsigned int v45; // [sp+DCh] [bp-4h]@21
 
-  zero = 0;
   pMouse->uPointingObjectID = 0;
   pMouse->GetClickPos(&pX, &pY);
   if ( (pX & 0x80000000u) != 0 || (signed int)pX > 639 || (pY & 0x80000000u) != 0 || (signed int)pY > 479 )
@@ -5146,7 +5146,7 @@
     if ( pCurrentScreen == 13 )
     {
       if ( dword_F8B19C != 2
-        || (v16 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]], v16 == zero)
+        || (v16 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]], v16 == 0)
         || v16 == -65536 )
         goto _return;
       v15 = (ItemGen *)((char *)&pParty->pPickedItem + 36 * (v16 + 12 * (unsigned int)ptr_507BC0->ptr_1C) + 4);
@@ -5156,9 +5156,9 @@
 LABEL_50:
       uLastPointedObjectID = 1;
 _return:
-      if ( pMouse->uPointingObjectID == zero )
-      {
-        if ( uLastPointedObjectID != zero )
+      if ( pMouse->uPointingObjectID == 0 )
+      {
+        if ( uLastPointedObjectID != 0 )
         {
           pStatusBarString[0] = 0;
           bForceDrawStatusBar = 1;
@@ -5170,7 +5170,7 @@
     if ( (signed int)pY < 350 )
     {
       v14 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]];
-      if ( v14 == zero || v14 == -65536 || (unsigned int)v14 >= 0x1388 )
+      if ( v14 == 0 || v14 == -65536 || (unsigned int)v14 >= 0x1388 )
         goto _return;
       v15 = (ItemGen *)&pPlayers[uActiveCharacter]->spellbook.pDarkSpellbook.bIsSpellAvailable[36 * v14 + 5];
       goto LABEL_49;
@@ -5181,7 +5181,7 @@
       && (signed int)pY >= (signed int)pWindowList[0].uFrameY
       && (signed int)pY <= (signed int)pWindowList[0].uFrameW )
     {
-      for ( i = pWindowList[0].pControlsHead; i != (GUIButton *)zero; i = i->pNext )
+      for ( i = pWindowList[0].pControlsHead; i != (GUIButton *)0; i = i->pNext )
       {
         if ( i->uButtonType == 1 )
         {
@@ -5191,14 +5191,14 @@
             && (signed int)pY <= (signed int)i->uW )
           {
             v37 = (UIMessageType)i->field_1C;
-            if ( v37 == zero )
+            if ( v37 == 0 )
               goto LABEL_28;
             v38 = i->uControlParam;
             if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
             {
               pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = v37;
               pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v38;
-              *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = zero;
+              *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
               ++pMessageQueue_50CBD0->uNumMessages;
             }
             goto LABEL_131;
@@ -5210,28 +5210,31 @@
           {
             v45 = pX - i->uX;
             v45 = pY - i->uY;
-            if ( (double)(signed int)i->uWidth != 0.0 )
-            {
-              if ( (double)(signed int)i->uHeight != 0.0 )
-              {
-                //UNDEF(v32);
-                if ( v33 | v34 )
+
+            if (pX >= i->uX && pX <= i->uZ &&
+                pY >= i->uY && pY <= i->uW)
+            //if ( (double)(signed int)i->uWidth != 0.0 )
+            //{
+            //  if ( (double)(signed int)i->uHeight != 0.0 )
+            //  {
+                 //UNDEF(v32);
+                //if ( v33 | v34 )
                 {
                   v35 = (UIMessageType)i->field_1C;
-                  if ( v35 != zero )
+                  if ( v35 != 0 )
                   {
                     v36 = i->uControlParam;
                     if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
                     {
                       pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = v35;
                       pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v36;
-                      *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = zero;
+                      *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
                       goto LABEL_27;
                     }
                   }
                   goto LABEL_28;
-                }
-              }
+                //}
+              //}
             }
           }
           else
@@ -5343,16 +5346,11 @@
     --v1;
     if ( v1 <= 0 )
     {
-      zero = 0;
       goto LABEL_38;
     }
   }
 }
-// 4E28F8: using guessed type int pCurrentScreen;
-// 506578: using guessed type int uLastPointedObjectID;
-// 5075E0: using guessed type int pVisibleWindowsIdxs[20];
-// 5C35BC: using guessed type int bForceDrawStatusBar;
-// F8B19C: using guessed type int dword_F8B19C;
+
 
 //----- (00421626) --------------------------------------------------------
 GUIWindow *GameUI_InitializeCharacterWindow(unsigned int _this)
--- a/mm7_2.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/mm7_2.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -3440,7 +3440,7 @@
   window.uFrameWidth = 460;
   window.uFrameZ = 452;
   v0 = pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[575], &window, 13, 0) + 7;
-  pRenderer->SetGameRenderStates();
+  pRenderer->BeginSceneD3D();
 
   if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
     pIndoor->Draw();
@@ -7894,7 +7894,7 @@
     v6->uAlly = 9999;
     v6->uGroup = 0;
     v6->uCurrentActionTime = 0;
-    v6->uAIState = 17;
+    v6->uAIState = Summoned;
     v6->uCurrentActionLength = 256;
     v6->UpdateAnimation();
     if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor
@@ -11237,30 +11237,6 @@
 }
 
 
-
-
-
-
-
-
-
-//----- (0045BAA5) --------------------------------------------------------
-int __thiscall sub_45BAA5(int _this)
-{
-  sub_45BAB6(_this);
-  return 0;
-}
-
-//----- (0045BAB6) --------------------------------------------------------
-std::string *__fastcall sub_45BAB6(int a1)
-{
-  size_t v1; // eax@1
-
-  stru_69BD44 = "effpar03";
-  return &stru_69BD44;
-}
-
-
 //----- (0045E03A) --------------------------------------------------------
 unsigned __int16 *__fastcall MakeScreenshot(signed int width, signed int height)
 {
@@ -11302,7 +11278,7 @@
   v3 = pPixels;
   if ( pRenderer->pRenderD3D )
   {
-    pRenderer->SetGameRenderStates();
+    pRenderer->BeginSceneD3D();
     if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
     {
       pIndoor->Draw();
@@ -13527,7 +13503,7 @@
       drive[0] = 'A' + i;
 
       if (GetDriveTypeA(drive) == DRIVE_CDROM)
-        if (CheckMM7CD(bGotCDFromRegistry))
+        if (CheckMM7CD(*drive))
         {
           cMM7GameCDDriveLetter = *drive;
           WriteWindowsRegistryString("CDDrive", drive);
@@ -14090,6 +14066,9 @@
   RECT Rect; // [sp+Ch] [bp-20h]@15
   int a2[4]; // [sp+1Ch] [bp-10h]@15
 
+  auto mm7text_dll = LoadLibraryW(L"mm7text.dll");
+  sprintfex = (int (__cdecl *)(char *a1, const char *a2, ...))GetProcAddress(mm7text_dll, "_sprintfex");
+
   if (pCmdLine && *pCmdLine)
   {
     if (wcsstr(pCmdLine, L"-usedefs"))
@@ -16439,21 +16418,6 @@
   return v19;
 }
 
-//----- (0046AC59) --------------------------------------------------------
-std::string *__fastcall crt_intit_global_46AC59(int a1)
-{
-  size_t v1; // eax@1
-
-  //std__string_720990.field_0 = BYTE3(a1);
-  //std::string::dtor(&std__string_720990, 0);
-  //v1 = strlen("micon1");
-  //return std::stringoperator_assign__const_char_ptr__(&std__string_720990, "micon1", v1);
-  std__string_720990 = "micon1";
-  return &std__string_720990;
-}
-
-
-
 
 //----- (0046BDA8) --------------------------------------------------------
 unsigned int __cdecl GetGravityStrength()
@@ -16916,7 +16880,7 @@
                   v138 = 0;
                   if ( v2->uItemType == 8030 )
                   {
-                    pActors[v108].uAIState = 0;
+                    pActors[v108].uAIState = Standing;
                     pActors[v108].UpdateAnimation();
                   }
                   ((SpellBuff *)((char *)&pActors[0].pActorBuffs[v136] + v108 * 836))->Apply(
--- a/mm7_3.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/mm7_3.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -1011,7 +1011,7 @@
       v72 = 1;
     if ( v0->uAIState == 5 && v76 && !v72 )
     {
-      v0->uAIState = 11;
+      v0->uAIState = Removed;
       goto LABEL_121;
     }
     if ( v0->uCurrentActionAnimation == 1 )
@@ -1114,7 +1114,7 @@
       v0->vVelocity.y += rand() % 100 - 50;
       v0->vVelocity.z += rand() % 100 - 20;
       v25 = rand();
-      v0->uAIState = 8;
+      v0->uAIState = Stunned;
       v0->uYawAngle += v25 % 32 - 16;
       v0->UpdateAnimation();
     }
@@ -1191,7 +1191,7 @@
             else
               v61 = v68 + 60;
             sub_42F960_create_object(v0->vPosition.x, v0->vPosition.y, v61);
-            v0->uAIState = 11;
+            v0->uAIState = Removed;
             return;
           }
         }
@@ -1372,7 +1372,7 @@
           v0->uYawAngle -= 32;
           v0->uCurrentActionTime = 0;
           v0->uCurrentActionLength = 128;
-          v0->uAIState = 7;
+          v0->uAIState = Fleeing;
         }
       }
     }
@@ -1559,7 +1559,7 @@
           v34 = (TEXTURE_TYPE)v8;
           v32 = "effpar03";
         }
-        Dst.field_20 = (unsigned __int8)(v30 & 0x80) + 128;
+        Dst.timeToLive = (unsigned __int8)(v30 & 0x80) + 128;
         Dst.uTextureID = pBitmaps_LOD->LoadTexture(v32, v34);
         goto LABEL_71;
       }
@@ -1733,7 +1733,7 @@
 LABEL_70:
           Dst.bFree = 512;
           Dst.uDiffuse = rand();
-          Dst.field_20 = 64;
+          Dst.timeToLive = 64;
           Dst.uTextureID = v8;
 LABEL_71:
           Dst.flt_28 = 1.0;
@@ -1746,7 +1746,7 @@
         v33 = (TEXTURE_TYPE)v8;
         v31 = "effpar03";
       }
-      Dst.field_20 = (unsigned __int8)(v11 & 0x80) + 128;
+      Dst.timeToLive = (unsigned __int8)(v11 & 0x80) + 128;
       Dst.uTextureID = pBitmaps_LOD->LoadTexture(v31, v33);
 LABEL_72:
       pGame->pParticleEngine->AddParticle(&Dst);
@@ -1927,7 +1927,7 @@
       {
         Dst.bFree = 512;
         Dst.uDiffuse = rand();
-        Dst.field_20 = 64;
+        Dst.timeToLive = 64;
         Dst.uTextureID = 0;
 LABEL_89:
         Dst.flt_28 = 1.0;
@@ -1941,7 +1941,7 @@
 LABEL_87:
       v47 = "effpar03";
     }
-    Dst.field_20 = (unsigned __int8)(v24 & 0x80) + 128;
+    Dst.timeToLive = (unsigned __int8)(v24 & 0x80) + 128;
     Dst.uTextureID = pBitmaps_LOD->LoadTexture(v47, v48);
     goto LABEL_89;
   }
@@ -2066,7 +2066,7 @@
           v46 = rand();
           Dst.uTextureID = 0;
           Dst.uDiffuse = v46;
-          Dst.field_20 = 64;
+          Dst.timeToLive = 64;
           goto LABEL_89;
         }
         Dst.bFree = 1032;
@@ -8522,7 +8522,7 @@
       {
         v15 = 0;
       }
-      v17 = sub_43F55F(a1, v15);
+      v17 = _43F55F_get_billboard_light_level(a1, v15);
       if ( v17 > 27 )
         v17 = 27;
       if ( !a3 )
@@ -8539,7 +8539,7 @@
     a3a = (double)(signed int)(((unsigned __int64)(11 * v12 / (pOutdoorCamera->shading_dist_shade << 16)) >> 16) + 20)
         * pOutdoor->fFogDensity;
     v13 = a3a + 6.7553994e15;
-    v10 = sub_43F55F(a1, LODWORD(v13) + v11);
+    v10 = _43F55F_get_billboard_light_level(a1, LODWORD(v13) + v11);
     if ( v10 > 27 )
       v10 = 27;
     if ( v10 < a4 )
@@ -8567,7 +8567,7 @@
     {
       v6 = 27;
     }
-    v10 = sub_43F55F(a1, v6);
+    v10 = _43F55F_get_billboard_light_level(a1, v6);
     if ( v10 > 27 || !a3 )
       v10 = 27;
     return PaletteManager::Get_Dark_or_Red_LUT(v4, v10, 1);
@@ -9080,7 +9080,7 @@
     {
 LABEL_20:
       if ( a5 )
-        v6 = 8 * sub_43F55F(a5, v6 >> 3);
+        v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3);
       if ( v6 > 216 )
         v6 = 216;
       return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8);
@@ -9120,7 +9120,7 @@
     }
     v6 = a4a + v12;
     if ( a5 )
-      v6 = 8 * sub_43F55F(a5, v6 >> 3);
+      v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3);
     if ( v6 > 216 )
       v6 = 216;
     if ( v6 < v12 )
@@ -9346,7 +9346,7 @@
   pOutdoorCamera->uNumEdges = 0;
   pOutdoorCamera->uNumSpans = 0;
   pOutdoorCamera->uNumSurfs = 0;
-  pOutdoorCamera->field_3C = 0;
+  pOutdoorCamera->uNumBillboards = 0;
   pOutdoorCamera->field_44 = 0;
 }
 
@@ -12901,7 +12901,7 @@
 
 
 //----- (0043F953) --------------------------------------------------------
-int __cdecl PrepareWallsRenderList_BLV()
+void PrepareWallsRenderList_BLV()
 {
   pStru170->uNumFaceIDs = 0;
   if ( pBLVRenderParams->uRadius )
@@ -12921,7 +12921,7 @@
     pStru170->std__vector_000FA8 = 1;
     sub_440639(0);
   }
-  return pStru170->RenderWalls();
+  pStru170->RenderWalls();
 }
 
 //----- (0043F9E1) --------------------------------------------------------
@@ -13084,15 +13084,15 @@
               HIWORD(v22) = HIWORD(x);
               v15->field_4 = v37;
               v15->field_1E = v30;
-              v15->field_20 = a1;
-              v15->field_22 = a2;
-              v15->field_24 = a3;
-              v15->field_26 = a5;
-              v15->field_28 = a6;
+              v15->some_x = a1;
+              v15->some_y = a2;
+              v15->some_z = a3;
+              v15->uScreenSpaceX = a5;
+              v15->uScreenSpaceY = a6;
               v23 = 8 * v26;
               LOBYTE(v23) = 8 * v26 | 5;
               LOWORD(v22) = 0;
-              v15->field_2C_prolly_tint = 0;
+              v15->uTintColor = 0;
               v15->sZValue = v22 + v23;
               v15->pSpriteFrame = v12;
             }
@@ -13113,7 +13113,7 @@
       local_0.flt_14 = 0.0;
       local_0.flt_18 = 0.0;
       local_0.flt_28 = 1.0;
-      local_0.field_20 = (rand() & 0x80) + 128;
+      local_0.timeToLive = (rand() & 0x80) + 128;
       local_0.uTextureID = pBitmaps_LOD->LoadTexture("effpar01");
       pGame->pParticleEngine->AddParticle(&local_0);
     }
@@ -13122,9 +13122,8 @@
 
 
 //----- (0044028F) --------------------------------------------------------
-void __cdecl PrepareItemsRenderList_BLV()
-{
-  char *v0; // edi@2
+void PrepareItemsRenderList_BLV()
+{
   ObjectDesc *v1; // ebx@4
   __int16 v2; // ax@5
   RenderBillboard *v3; // esi@12
@@ -13137,11 +13136,6 @@
   unsigned __int16 v10; // ax@12
   int *v11; // eax@20
   char v12; // zf@26
-  IndoorCameraD3D **v13; // eax@27
-  double v14; // st7@27
-  float v15; // eax@27
-  double v16; // ST30_8@27
-  signed __int64 v17; // qtt@27
   int v18; // ST5C_4@27
   signed __int64 v19; // qtt@28
   int v20; // ST5C_4@28
@@ -13149,14 +13143,12 @@
   __int16 v22; // ax@29
   int v23; // eax@29
   SpriteFrame *v24; // [sp+1Ch] [bp-40h]@12
-  ObjectDesc *v25; // [sp+20h] [bp-3Ch]@4
   __int16 a5; // [sp+28h] [bp-34h]@12
   int a6; // [sp+2Ch] [bp-30h]@12
   int a2; // [sp+30h] [bp-2Ch]@12
   int a1; // [sp+34h] [bp-28h]@12
   int v30; // [sp+38h] [bp-24h]@12
   int v31; // [sp+38h] [bp-24h]@27
-  signed int v32; // [sp+3Ch] [bp-20h]@1
   int a3; // [sp+40h] [bp-1Ch]@12
   signed __int16 v34; // [sp+44h] [bp-18h]@14
   int v35; // [sp+48h] [bp-14h]@25
@@ -13165,37 +13157,33 @@
   signed int y; // [sp+54h] [bp-8h]@24
   signed int x; // [sp+58h] [bp-4h]@24
 
-  v32 = 0;
-  if ( (signed int)uNumLayingItems > 0 )
-  {
-    v0 = (char *)&pLayingItems[0].uSectorID;
-    do
-    {
-      if ( *((short *)v0 - 13) )
-      {
-        v1 = &pObjectList->pObjects[*((short *)v0 - 13)];
-        v25 = v1;
+  for (uint i = 0; i < uNumLayingItems; ++i)
+  {
+    auto p = pLayingItems + i;
+    if (p->uObjectDescID)
+    {
+      v1 = &pObjectList->pObjects[p->uObjectDescID];
         if ( !(v1->uFlags & 1) )
-        {
-          if ( ((v2 = *((short *)v0 - 14), v2 < 1000) || v2 >= 10000)
+         {
+          if ( ((v2 = p->uItemType, v2 < 1000) || v2 >= 10000)
             && (v2 < 500 || v2 >= 600)
             && (v2 < 811 || v2 >= 815)
-            || pGame->pStru6Instance->_4A81CA((LayingItem *)(v0 - 28)) )
-          {
-            a5 = *(short *)v0;
-            a1 = *((int *)v0 - 6);
-            a2 = *((int *)v0 - 5);
-            a3 = *((int *)v0 - 4);
+            || pGame->pStru6Instance->_4A81CA(p))
+          {
+            a5 = p->uSectorID;
+            a1 = p->vPosition.x;
+            a2 = p->vPosition.y;
+            a3 = p->vPosition.z;
             v3 = &pBillboardRenderList[uNumBillboardsToDraw];
-            v4 = pSpriteFrameTable->GetFrame(v1->uSpriteID, *((short *)v0 + 1));
+            v4 = pSpriteFrameTable->GetFrame(v1->uSpriteID, p->uSpriteFrameID);
             v5 = v4;
             v24 = v4;
             v30 = v4->uFlags;
-            a6 = v4->uGlowRadius * *((short *)v0 + 3);
+            a6 = v4->uGlowRadius * p->field_22;
             v6 = stru_5C6E00->Atan2(
-                   *((int *)v0 - 6) - pBLVRenderParams->vPartyPos.x,
-                   *((int *)v0 - 5) - pBLVRenderParams->vPartyPos.y);
-            LOWORD(v7) = *((short *)v0 - 3);
+                   p->vPosition.x - pBLVRenderParams->vPartyPos.x,
+                   p->vPosition.y - pBLVRenderParams->vPartyPos.y);
+            LOWORD(v7) = p->uFacing;
             v8 = v30;
             v9 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + v7 - v6) >> 8) & 7;
             v10 = v5->pHwSpriteIDs[v9];
@@ -13225,9 +13213,9 @@
                 a3,
                 a5,
                 a6,
-                v25->uParticleTrailColorR,
-                v25->uParticleTrailColorG,
-                v25->uParticleTrailColorB,
+                v1->uParticleTrailColorR,
+                v1->uParticleTrailColorG,
+                v1->uParticleTrailColorB,
                 v11);
             }
             if ( pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(
@@ -13244,7 +13232,7 @@
                 return;
               ++uNumBillboardsToDraw;
               ++uNumSpritesDrawnThisFrame;
-              *(v0 - 2) |= 1u;
+              p->uAttributes |= 1u;
               v12 = pRenderer->pRenderD3D == 0;
               v3->uPalette = v24->uPaletteIndex;
               v3->uIndoorSectorID = a5;
@@ -13258,33 +13246,27 @@
               }
               else
               {
-                v13 = &pGame->pIndoorCameraD3D;
                 v3->flt_8 = pGame->pIndoorCameraD3D->flt_D0;
-                v14 = (*v13)->flt_D4;
-                v15 = v3->flt_8;
-                v3->flt_C = v14;
-                v16 = v15 + 6.7553994e15;
-                LODWORD(v17) = 0;
-                HIDWORD(v17) = SLOWORD(v16);
-                v18 = v17 / x;
-                v3->field_0 = (unsigned __int64)(v24->scale * v17 / x) >> 16;
-                v31 = (unsigned __int64)(v24->scale * (signed __int64)v18) >> 16;
+                v3->flt_C = pGame->pIndoorCameraD3D->flt_D4;
+                v18 = (int)floorf(v3->flt_8 + 0.5f) / x;
+                v3->field_0 = (unsigned __int64)(v24->scale * (__int64)v18) >> 16;
+                v31 = (unsigned __int64)(v24->scale * (__int64)v18) >> 16;
               }
               HIWORD(v21) = HIWORD(x);
               v3->field_4 = v31;
               v3->field_1E = v34;
-              v3->field_20 = a1;
-              v3->field_22 = a2;
-              v3->field_24 = a3;
-              v3->field_26 = v36;
+              v3->some_x = a1;
+              v3->some_y = a2;
+              v3->some_z = a3;
+              v3->uScreenSpaceX = v36;
               v22 = v35;
-              v3->field_2C_prolly_tint = 0;
-              v3->field_28 = v22;
+              v3->uTintColor = 0;
+              v3->uScreenSpaceY = v22;
               LOWORD(v21) = 0;
-              v23 = 8 * v32;
-              LOBYTE(v23) = 8 * v32 | 2;
+              v23 = 8 * i;
+              LOBYTE(v23) = 8 * i | 2;
               v3->pSpriteFrame = v24;
-              v12 = (*(v0 - 2) & 0x20) == 0;
+              v12 = (p->uAttributes & 0x20) == 0;
               v3->sZValue = v21 + v23;
               if ( !v12 )
               {
@@ -13295,10 +13277,6 @@
           }
         }
       }
-      ++v32;
-      v0 += 112;
-    }
-    while ( v32 < (signed int)uNumLayingItems );
   }
 }
 
@@ -13393,20 +13371,18 @@
 //----- (00440DF5) --------------------------------------------------------
 int stru167_wrap::Push(__int16 a2, __int16 a3, __int16 a4, int a5, __int16 bgr)
 {
-  stru167_wrap *v6; // esi@1
   int result; // eax@1
 
-  v6 = this;
-  v6->pElements[v6->uNumElements].field_6 = a2;
-  this->pElements[this->uNumElements].field_8 = a3;
-  this->pElements[this->uNumElements].field_A = a4;
-  v6->pElements[v6->uNumElements].field_C = rand() % 64 + 256;
-  v6->pElements[v6->uNumElements].field_E = v6->pElements[v6->uNumElements].field_C;
-  result = 3 * v6->uNumElements;
-  v6->pElements[v6->uNumElements++].bgr16 = bgr;
-  if ( v6->uNumElements >= 100 )
-    v6->uNumElements = 0;
-  return result;
+  pElements[uNumElements].field_6_rnd_value = a2;
+  pElements[uNumElements].field_8_rnd_value = a3;
+  pElements[uNumElements].field_A_rnd_value = a4;
+  pElements[uNumElements].field_C_time_left = rand() % 64 + 256;
+  pElements[uNumElements].field_E_time_to_live = pElements[uNumElements].field_C_time_left;
+  result = 3 * uNumElements;
+  pElements[uNumElements++].bgr16 = bgr;
+  if (uNumElements >= 100 )
+    uNumElements = 0;
+   return result;
 }
 
 //----- (00440E91) --------------------------------------------------------
@@ -13431,24 +13407,16 @@
 //----- (00440F07) --------------------------------------------------------
 void stru167_wrap::_440F07()
 {
-  char *v1; // esi@1
-  signed int v2; // edi@1
-
-  v1 = (char *)&this->pElements[0].field_6;
-  v2 = 100;
-  do
-  {
-    if ( *((short *)v1 + 3) > 0 )
-    {
-      *((short *)v1 + 2) += rand() % 5 + 4;
-      *(short *)v1 += rand() % 5 - 2;
-      *((short *)v1 + 1) += rand() % 5 - 2;
-      *((short *)v1 + 3) -= LOWORD(pEventTimer->uTimeElapsed);
-    }
-    v1 += 24;
-    --v2;
-  }
-  while ( v2 );
+  for (uint i = 0; i < 100; ++i)
+  {
+    if (pElements[i].field_C_time_left > 0)
+    {
+      pElements[i].field_A_rnd_value += rand() % 5 + 4;
+      pElements[i].field_6_rnd_value += rand() % 5 - 2;
+      pElements[i].field_8_rnd_value += rand() % 5 - 2;
+      pElements[i].field_C_time_left -= (short)pEventTimer->uTimeElapsed;
+    }
+  }
 }
 
 //----- (0044100D) --------------------------------------------------------
@@ -13564,8 +13532,8 @@
       pRenderer->_4A65CC(
         pPartySpellbuffsUI_XYs[v1][0],
         pPartySpellbuffsUI_XYs[v1][1],
-        (Texture *)(v3 != -1 ? (int)&pIcons_LOD->pTextures[v3] : 0),
-        (Texture *)(v3 != -1 ? (int)&pIcons_LOD->pTextures[v3] : 0),
+        (Texture *)(v3 != -1 ? &pIcons_LOD->pTextures[v3] : 0),
+        (Texture *)(v3 != -1 ? &pIcons_LOD->pTextures[v3] : 0),
         v0 + 20 * pPartySpellbuffsUI_smthns[v1],
         0,
         63);
@@ -13687,17 +13655,17 @@
             v11 = *((int *)v3 + 1);
             v13 = v6->scale;
             v13 = (unsigned __int64)(v11 * (signed __int64)v13) >> 16;
-            v10.field_8 = *((short *)v3 - 2);
-            v10.field_C = *((short *)v3 - 1);
+            v10.uScreenSpaceX = *((short *)v3 - 2);
+            v10.uScreenSpaceY = *((short *)v3 - 1);
             v10.field_10 = v13;
             v10.field_14 = v13;
             v10.pPalette = PaletteManager::Get_Dark_or_Red_LUT(v6->uPaletteIndex, 0, 1);
             v8 = *((short *)v3 - 5);
-            v10.field_28 = 0;
+            v10.sZValue = 0;
             v10.uFlags = 0;
             v9 = pOverlayList->pOverlays[v8].uOverlayType;
             if ( !v9 || v9 == 2 )
-              v10.field_C += pSprites_LOD->pSpriteHeaders[v7->pHwSpriteIDs[0]].uHeight >> 1;
+              v10.uScreenSpaceY += pSprites_LOD->pSpriteHeaders[v7->pHwSpriteIDs[0]].uHeight >> 1;
             result = pSprites_LOD->pSpriteHeaders[v7->pHwSpriteIDs[0]]._4AD2D1(&v10, 0);
             ++v12;
             if ( v12 == 5 )
@@ -16511,7 +16479,7 @@
       pInString = 0;
       if ( (signed int)uNumActors > 0 )
       {
-        v55 = &pActors[0].uAIState;
+        v55 = (unsigned short *)&pActors[0].uAIState;
         *(int *)v54 = uNumActors;
         do
         {
@@ -18549,8 +18517,6 @@
 //----- (00448A40) --------------------------------------------------------
 void Actor::ToggleFlag(signed int uActorID, unsigned int uFlag, int bToggle)
 {
-  unsigned __int16 *pState; // eax@6
-
   if ( uActorID >= 0 && uActorID <= (signed int)(uNumActors - 1) )
   {
     if ( bToggle )
@@ -18561,9 +18527,8 @@
     {
       if ( uFlag == 0x10000 )
       {
-        pState = &pActors[uActorID].uAIState;
-        if ( *pState == Disabled )
-          *pState = Standing;
+        if (pActors[uActorID].uAIState == Disabled )
+          pActors[uActorID].uAIState = Standing;
       }
       pActors[uActorID].uAttributes &= ~uFlag;
     }
@@ -20616,7 +20581,7 @@
           Actor::_403F58(uActorID, Dying, 256, 0);
           goto LABEL_78;
         }
-        pActor->uAIState = 0;
+        pActor->uAIState = Standing;
       }
       pActor->uCurrentActionTime = 0;
       pActor->uCurrentActionLength = 0;
@@ -20701,7 +20666,7 @@
         && (SHIDWORD(v21->pActorBuffs[2].uExpireTime) < (signed int)v24
          || LODWORD(v21->pActorBuffs[2].uExpireTime) <= v24) )
       {
-        v21->uAIState = 11;
+        v21->uAIState = Removed;
         goto LABEL_254;
       }
       if ( v21->pActorBuffs[5].uExpireTime || v21->pActorBuffs[6].uExpireTime )
--- a/mm7_4.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/mm7_4.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -3065,12 +3065,6 @@
 //----- (00491F87) --------------------------------------------------------
 void __cdecl DrawHiredNPCs()
 {
-  int v0; // ecx@2
-  char *v1; // eax@2
-  int v2; // edx@4
-  signed int v3; // ebx@6
-  char *v4; // esi@7
-  int v5; // ecx@13
   int v6; // eax@15
   char v7; // al@17
   unsigned int v8; // eax@18
@@ -3081,7 +3075,7 @@
   unsigned int v13; // eax@23
   IconFrame *v14; // eax@24
   unsigned int v15; // eax@26
-  char pContainer; // [sp+Ch] [bp-30h]@18
+  char pContainer[20]; // [sp+Ch] [bp-30h]@18
   unsigned int v17; // [sp+20h] [bp-1Ch]@19
   signed int uFrameID; // [sp+24h] [bp-18h]@19
   int i; // [sp+28h] [bp-14h]@15
@@ -3094,38 +3088,24 @@
   {
     v23 = 0;
     v22 = 0;
-    v0 = 0;
-    v1 = (char *)pParty->pHirelings;
-    do
-    {
-      if ( *(int *)v1 )
-      {
-        v2 = v22++;
-        pTmpBuf[v2] = v0;
-      }
-      v1 += 76;
-      ++v0;
-    }
-    while ( (signed int)v1 < (signed int)&pParty->pPickedItem );
-    v3 = 0;
-    if ( (signed int)pNPCStats->uNumNewNPCs > 0 )
-    {
-      v4 = (char *)pNPCStats->pNewNPCData;
-      do
-      {
-        if ( v4[8] & 0x80 && (!pParty->pHirelings[0].pName || strcmp(*(const char **)v4, pParty->pHirelings[0].pName)) )
-        {
-          if ( !pParty->pHirelings[1].pName || strcmp(*(const char **)v4, pParty->pHirelings[1].pName) )
-          {
-            v5 = v22++;
-            pTmpBuf[v5] = v3 + 2;
-          }
-        }
-        ++v3;
-        v4 += 76;
-      }
-      while ( v3 < (signed int)pNPCStats->uNumNewNPCs );
-    }
+    for (uint i = 0; i < 2; ++i)
+    { 
+      if (pParty->pHirelings[i].pName)
+        pTmpBuf[v22++] = i;
+    }
+
+    for (uint i = 0; i < pNPCStats->uNumNewNPCs; ++i)
+    {
+      if (pNPCStats->pNewNPCData[i].uFlags & 0x80)
+      {
+        if (!pParty->pHirelings[0].pName || strcmp(pNPCStats->pNewNPCData[i].pName, pParty->pHirelings[0].pName))
+        {
+          if (!pParty->pHirelings[1].pName || strcmp(pNPCStats->pNewNPCData[i].pName, pParty->pHirelings[1].pName))
+            pTmpBuf[v22++] = i + 2;
+        }
+      }
+    }
+
     v6 = (unsigned __int8)pParty->field_709;
     for ( i = (unsigned __int8)pParty->field_709; i < v22; v6 = i++ + 1 )
     {
@@ -3134,22 +3114,22 @@
       v7 = pTmpBuf[v6];
       if ( (unsigned __int8)v7 >= 2u )
       {
-        sprintfex(&pContainer, "NPC%03d", pNPCStats->pNPCData[(unsigned __int8)v7 + 499].uPortraitID);
-        v15 = pIcons_LOD->LoadTexture(&pContainer, TEXTURE_16BIT_PALETTE);
+        sprintf(pContainer, "NPC%03d", pNPCStats->pNPCData[(unsigned __int8)v7 + 499].uPortraitID);
+        v15 = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
         pRenderer->DrawTextureIndexed(
           pHiredNPCsIconsOffsetsX[v23],
           pHiredNPCsIconsOffsetsY[v23],
-          (Texture *)(v15 != -1 ? 72 * v15 + 7145548 : 0));
+          (Texture *)(v15 != -1 ? &pIcons_LOD->pTextures[v15] : 0));
       }
       else
       {
-        sprintfex(&pContainer, "NPC%03d", pParty->pHirelings[(unsigned __int8)v7].uPortraitID);
-        v8 = pIcons_LOD->LoadTexture(&pContainer, TEXTURE_16BIT_PALETTE);
+        sprintf(pContainer, "NPC%03d", pParty->pHirelings[(unsigned __int8)v7].uPortraitID);
+        v8 = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
         v9 = v23;
         pRenderer->DrawTextureIndexed(
           pHiredNPCsIconsOffsetsX[v9],
           pHiredNPCsIconsOffsetsY[v9],
-          (Texture *)(v8 != -1 ? (int)&pIcons_LOD->pTextures[v8] : 0));
+          (Texture *)(v8 != -1 ? &pIcons_LOD->pTextures[v8] : 0));
         v10 = (unsigned __int8)pTmpBuf[i];
         if ( pParty->pHirelings[v10].bDrawSomeAnim == 1 )
         {
@@ -3190,12 +3170,7 @@
 //----- (004921C1) --------------------------------------------------------
 void GameUI_DrawPortraits(unsigned int _this)
 {
-  signed int v1; // ebx@2
-  int v2; // ebp@7
-  char *v3; // esi@7
   Texture *v4; // eax@10
-  signed int v5; // edx@13
-  PlayerFrame *v6; // eax@14
   unsigned int v7; // eax@17
   PlayerFrame *v8; // eax@21
   unsigned int v9; // eax@27
@@ -3203,21 +3178,15 @@
   bool v11; // edi@40
   bool v12; // edx@43
   bool v13; // ecx@46
-  int v14; // esi@54
-  char *v15; // edi@55
   int v16; // eax@57
-  __int16 *v17; // esi@59
-  char *v18; // edi@59
   int v19; // eax@62
   Texture *v20; // [sp-4h] [bp-1Ch]@27
-  signed int v21; // [sp+10h] [bp-8h]@7
   unsigned int v22; // [sp+14h] [bp-4h]@1
 
   v22 = _this;
   if ( qword_A750D8 )
   {
     qword_A750D8 -= (signed int)pMiscTimer->uTimeElapsed;
-    v1 = 0;
     if ( qword_A750D8 <= 0 )
     {
       if ( pPlayers[word_A750E2]->CanAct() )
@@ -3225,95 +3194,80 @@
       qword_A750D8 = 0i64;
     }
   }
-  else
-  {
-    v1 = 0;
-  }
-  v2 = 0;
-  v21 = v1;
-  v3 = (char *)&pParty->pPlayers[0].pConditions[14];
-  while ( 1 )
-  {
-    if ( *((_QWORD *)v3 + 2) )
+
+  for (uint i = 0; i < 4; ++i)
+  {
+    auto pPlayer = pParty->pPlayers + i;
+
+    if (pPlayer->Eradicated())
     {
       v4 = pTexture_PlayerFaceEradicated;
 LABEL_27:
       v20 = v4;
-      v9 = pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[v2];
+      v9 = pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i];
       if ( pParty->pPartyBuffs[11].uExpireTime )
         pRenderer->_4A6E7E(v9, 0x183u, v20);
       else
         pRenderer->DrawTextureTransparent(v9 + 1, 0x184u, v20);
-      v10 = *((int *)v3 + 1541) >= v1 && (*((int *)v3 + 1541) > v1 || *((int *)v3 + 1540) > (unsigned int)v1);
-      if ( *((int *)v3 + 1489) >= v1 && (*((int *)v3 + 1489) > v1 || *((int *)v3 + 1488) > (unsigned int)v1) )
-        v1 = 1;
-      v11 = *((_QWORD *)v3 + 758) > 0i64;
-      v12 = *((_QWORD *)v3 + 756) > 0i64;
-      v13 = *((_QWORD *)v3 + 768) > 0i64;
-      if ( v13 | v12 | v11 | v1 | v10 )
-        sub_441A4E(v2);
+      auto _v1 = 0;
+      v10 = pPlayer->pPlayerBuffs[14].uExpireTime > 0;
+      if (pPlayer->pPlayerBuffs[1].uExpireTime > 0)
+        _v1 = 1;
+      v11 = pPlayer->pPlayerBuffs[8].uExpireTime > 0;
+      v12 = pPlayer->pPlayerBuffs[7].uExpireTime > 0;
+      v13 = pPlayer->pPlayerBuffs[13].uExpireTime > 0;
+      if ( v13 | v12 | v11 | _v1 | v10 )
+        sub_441A4E(i);
       goto LABEL_50;
     }
-    if ( *(_QWORD *)v3 )
+    if (pPlayer->Dead())
     {
       v4 = pTexture_PlayerFaceDead;
       goto LABEL_27;
     }
-    v5 = 0;
-    if ( (signed int)pPlayerFrameTable->uNumFrames <= v1 )
-    {
-LABEL_17:
+
       v7 = 0;
-    }
-    else
-    {
-      v6 = pPlayerFrameTable->pFrames;
-      while ( v6->uSequenceID != *((short *)v3 + 3350) )
-      {
-        ++v5;
-        ++v6;
-        if ( v5 >= (signed int)pPlayerFrameTable->uNumFrames )
-          goto LABEL_17;
-      }
-      v7 = v5;
-    }
-    if ( v7 == v1 )
+      for (uint j = 0; j < pPlayerFrameTable->uNumFrames; ++j)
+        if (pPlayerFrameTable->pFrames[j].uSequenceID == pPlayer->uExpressionID)
+        {
+          v7 = j;
+          break;
+        }
+
+    if ( v7 == 0 )
       v7 = 1;
-    if ( *((short *)v3 + 3350) == 21 )
+    if (pPlayer->uExpressionID == 21 )
       v8 = pPlayerFrameTable->GetFrameBy_y(
-             (int *)v3 + 1678,
-             (int *)v3 + 1677,
+             &pPlayer->field_1AA8,
+             &pPlayer->field_1AA4,
              pMiscTimer->uTimeElapsed);
     else
-      v8 = pPlayerFrameTable->GetFrameBy_x(v7, *((short *)v3 + 3351));
-    if ( *((short *)v3 + 3353) != v8->uTextureID - 1 || v22 )
-    {
-      *((short *)v3 + 3353) = v8->uTextureID - 1;
-      v1 = 0;
-      v4 = (Texture *)A74CEC_player_faces_minus1_indexing[v21 + v8->uTextureID];
+      v8 = pPlayerFrameTable->GetFrameBy_x(v7, pPlayer->uExpressionTimePassed);
+    if (pPlayer->field_1AA2 != v8->uTextureID - 1 || v22 )
+    {
+      pPlayer->field_1AA2 = v8->uTextureID - 1;
+      v4 = (Texture *)pTextures_PlayerFaces[i][v8->uTextureID];
       goto LABEL_27;
     }
 LABEL_50:
-    v21 += 56;
-    v3 += 6972;
-    ++v2;
-    if ( (signed int)v3 >= (signed int)&pParty->pHirelings[1].field_24 )
-      break;
-    v1 = 0;
-  }
+    ;
+  }
+
   if ( pParty->bTurnBasedModeOn == 1 )
   {
     if ( pTurnEngine->field_4 != 1 )
     {
       if ( (pTurnEngine->pQueue[0].uPackedID & 7) == 4 )
       {
-        v14 = 0;
+        //v14 = 0;
         if ( pTurnEngine->uActorQueueSize > 0 )
         {
-          v15 = (char *)pTurnEngine->pQueue;
-          do
-          {
-            if ( (*v15 & 7) != 4 )
+          //v15 = (char *)pTurnEngine->pQueue;
+          for (uint i = 0; i < pTurnEngine->uActorQueueSize; ++i)
+          {
+            auto pElem = pTurnEngine->pQueue + i;
+
+            if ( (pElem->uPackedID & 7) != 4 )
               break;
             v16 = dword_5079D0;
             if ( pParty->uFlags & 0x10 )
@@ -3326,24 +3280,20 @@
                 v16 = dword_5079C8;
             }
             pRenderer->DrawTextureTransparent(
-              pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[*(int *)v15 >> 3] - 4,
+              pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[pElem->uPackedID >> 3] - 4,
               0x181u,
-              (Texture *)(v16 != -1 ? (int)&pIcons_LOD->pTextures[v16] : 0));
-            ++v14;
-            v15 += 16;
-          }
-          while ( v14 < pTurnEngine->uActorQueueSize );
-        }
-      }
-    }
-  }
-  else
-  {
-    v17 = pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing;
-    v18 = (char *)pParty->pPlayers;
-    do
-    {
-      if ( ((Player *)v18)->CanAct() && !*((short *)v18 + 3226) )
+              (Texture *)(v16 != -1 ? &pIcons_LOD->pTextures[v16] : 0));
+          }
+        }
+      }
+    }
+  }
+  else
+  {
+    for (uint i = 0; i < 4; ++i)
+    {
+      auto pPlayer = pParty->pPlayers + i;
+      if (pPlayer->CanAct() && !pPlayer->uTimeToRecovery)
       {
         v19 = dword_5079D0;
         if ( pParty->uFlags & 0x10 )
@@ -3356,14 +3306,11 @@
             v19 = dword_5079C8;
         }
         pRenderer->DrawTextureTransparent(
-          *v17 - 4,
+          pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] - 4,
           0x181u,
-          (Texture *)(v19 != -1 ? (int)&pIcons_LOD->pTextures[v19] : 0));
-      }
-      v18 += 6972;
-      ++v17;
-    }
-    while ( (signed int)v18 < (signed int)pParty->pHirelings );
+          (Texture *)(v19 != -1 ? &pIcons_LOD->pTextures[v19] : 0));
+      }
+    }
   }
 }
 
@@ -7134,109 +7081,9 @@
 }
 
 
-//----- (004A1C1E) --------------------------------------------------------
-void __cdecl DoRenderBillboards_D3D()
-{
-  signed int v0; // ebp@1
-  signed int *v1; // esi@2
-  //IDirect3DDevice3Vtbl *v2; // esi@7
-  unsigned int v3; // eax@7
-  unsigned int v4; // [sp+58h] [bp-4h]@2
-
-  v0 = -1;
-  ErrD3D(pRenderer->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, 3u));
-  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 1u));
-  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 0));
-  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1u));
-  if ( ((pRenderer->uNumBillboardsToDraw - 1) & 0x80000000u) == 0 )
-  {
-    v1 = (signed int *)&pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - 1].bOpaque;
-    v4 = pRenderer->uNumBillboardsToDraw;
-    do
-    {
-      ErrD3D(pRenderer->pRenderD3D->pDevice->SetTexture(
-        0,
-        (IDirect3DTexture2 *)*(v1 - 35)));
-      if ( *v1 != v0 )
-      {
-        v0 = *v1;
-        SetBillboardBlendOptions(*v1);
-      }
-      ErrD3D(pRenderer->pRenderD3D->pDevice->DrawPrimitive(
-        D3DPT_TRIANGLEFAN,
-        452,
-        v1 - 33,
-        *(v1 - 34),
-        24));
-      v1 -= 39;
-      --v4;
-    }
-    while ( v4 );
-  }
-  if ( pRenderer->turnFogOn )
-  {
-    pRenderer->turnFogOn = 0;
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1u));
-    //v2 = pRenderer->pRenderD3D->pDevice->lpVtbl;
-    v3 = GetLevelFogColor();
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, v3 & 0xFFFFFF));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0));
-  }
-  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 2u));
-  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1u));
-  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 0));
-  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2u));
-  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 1u));
-  ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 1u));
-}
-
-//----- (004A1DA8) --------------------------------------------------------
-void __fastcall SetBillboardBlendOptions(signed int a1)
-{
-  //IDirect3DDevice3Vtbl *v1; // edi@9
-  unsigned int v2; // eax@9
-  int v3; // [sp+0h] [bp-4h]@0
-
-  if ( !a1 )
-  {
-    if ( pRenderer->turnFogOn )
-    {
-      pRenderer->turnFogOn = 0;
-      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1u));
-      //v1 = pRenderer->pRenderD3D->pDevice->lpVtbl;
-      v2 = GetLevelFogColor();
-      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, v2 & 0xFFFFFF));
-      ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0));
-    }
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 5));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 6u));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 1));
-    return;
-  }
-  if ( a1 > 0 && a1 <= 3 )
-  {
-    if ( pRenderer->bUsingSpecular )
-    {
-      if ( !pRenderer->turnFogOn )
-      {
-        pRenderer->turnFogOn = 1;
-        ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0));
-      }
-    }
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, 2));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, 2u));
-    ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, 0));
-  }
-}
-
-
-
-
-
-
 
 //----- (004A46E6) --------------------------------------------------------
-int __fastcall sub_4A46E6(unsigned int x, signed int y, signed int a3, int a4, unsigned int a5)
+int __fastcall sr_4A46E6_draw_particle_segment(unsigned int x, signed int y, signed int _z, int a4, unsigned int lightColor)
 {
   int v5; // eax@1
   int z; // eax@1
@@ -7259,7 +7106,7 @@
   signed int v23; // [sp+20h] [bp+Ch]@1
 
   v5 = a4;
-  v23 = a3 >> 16;
+  v23 = _z >> 16;
   z = x + v5;
   if ( z >= (signed int)pViewport->uViewportX
     && (signed int)x <= (signed int)pViewport->uViewportZ
@@ -7273,12 +7120,12 @@
     pTarget = &pRenderer->pTargetSurface[x + y * pRenderer->uTargetSurfacePitch];
     v22 = z - x;
     pTargetZ = &pRenderer->pActiveZBuffer[x + 640 * y];
-    v7 = a5 >> 3;
-    v8 = a5 & 0xF0;
+    v7 = lightColor >> 3;
+    v8 = lightColor & 0xF0;
     v9 = v7 & 0x1E0000;
     if ( pRenderer->uTargetGBits == 5 )
     {
-      v10 = (v8 | (((unsigned __int16)(a5 & 0xF000) | (unsigned int)v9) >> 3)) >> 4;
+      v10 = (v8 | (((unsigned __int16)(lightColor & 0xF000) | (unsigned int)v9) >> 3)) >> 4;
       v11 = (int *)pTarget;
       v12 = pTargetZ;
       v13 = v22;
@@ -7325,7 +7172,7 @@
     }
     else
     {
-      v15 = (v8 | (((unsigned __int16)(a5 & 0xF800) | (unsigned int)v9) >> 2)) >> 4;
+      v15 = (v8 | (((unsigned __int16)(lightColor & 0xF800) | (unsigned int)v9) >> 2)) >> 4;
       v16 = (int *)pTarget;
       v17 = pTargetZ;
       v18 = v22;
@@ -13449,7 +13296,7 @@
       ++pMessageQueue_50CBD0->uNumMessages;
     }
     if ( (uDialogue_SpeakingActorNPC_ID & 0x80000000u) == 0 )
-      pDialogue_SpeakingActor->uAIState = 11;
+      pDialogue_SpeakingActor->uAIState = Removed;
     if ( uActiveCharacter )
       pPlayers[uActiveCharacter]->PlaySound(61, 0);
     goto LABEL_87;
@@ -15174,7 +15021,7 @@
               {
                 v4->uCurrentActionTime = 0;
                 v4->uCurrentActionLength = 0;
-                v4->uAIState = 5;
+                v4->uAIState = Dead;
                 v4->UpdateAnimation();
               }
               v1 = v18;
@@ -15251,11 +15098,9 @@
 
 
 //----- (0043FDED) --------------------------------------------------------
-unsigned int __cdecl PrepareActorRenderList_BLV()
+void PrepareActorRenderList_BLV()
 {
   RenderBillboard *v0; // esi@0
-  unsigned int result; // eax@1
-  char *v2; // edi@2
   unsigned __int16 v3; // ax@3
   unsigned int v4; // eax@5
   unsigned __int16 v5; // cx@5
@@ -15266,7 +15111,6 @@
   SpriteFrame *v10; // ebx@18
   int *v11; // eax@18
   int v12; // ecx@28
-  Actor *v13; // ecx@35
   IndoorCameraD3D **v14; // eax@36
   double v15; // st7@36
   float v16; // eax@36
@@ -15292,8 +15136,6 @@
   __int16 a5; // [sp+2Ch] [bp-28h]@5
   int a5a; // [sp+2Ch] [bp-28h]@36
   int a5b; // [sp+2Ch] [bp-28h]@40
-  unsigned int v39; // [sp+30h] [bp-24h]@1
-  int v40; // [sp+34h] [bp-20h]@2
   __int16 v41; // [sp+3Ch] [bp-18h]@18
   int a6; // [sp+40h] [bp-14h]@34
   int v43; // [sp+44h] [bp-10h]@34
@@ -15301,36 +15143,21 @@
   signed int y; // [sp+4Ch] [bp-8h]@32
   int x; // [sp+50h] [bp-4h]@32
 
-  result = 0;
-  v39 = 0;
-  if ( (signed int)uNumActors > 0 )
-  {
-    v40 = 0;
-    v2 = (char *)&pActors[0].uAttributes;
-    while ( 1 )
-    {
-      v3 = *((_WORD *)v2 + 70);
-      *(_DWORD *)v2 &= 0xFFFFFFF7u;
-      if ( v3 != 11 )
-      {
-        if ( v3 != 19 )
-          break;
-      }
-LABEL_48:
-      ++v39;
-      v40 += 32;
-      result = v39;
-      v2 += 836;
-      if ( (signed int)v39 >= (signed int)uNumActors )
-        return result;
-    }
-    a5 = *((_WORD *)v2 + 61);
-    a2 = *((_WORD *)v2 + 54);
-    a1a = *((_WORD *)v2 + 53);
-    a3 = *((_WORD *)v2 + 55);
+  for (uint i = 0; i < uNumActors; ++i)
+  {
+    auto p = pActors + i;
+
+    if (p->uAIState == Removed ||
+        p->uAIState == Disabled)
+      continue;
+
+    a5 = p->uSectorID;
+    a2 = p->vPosition.y;
+    a1a = p->vPosition.x;
+    a3 = p->vPosition.z;
     v4 = stru_5C6E00->Atan2(a1a - pBLVRenderParams->vPartyPos.x, a2 - pBLVRenderParams->vPartyPos.y);
-    LOWORD(v0) = *((_WORD *)v2 + 59);
-    v5 = *((_WORD *)v2 + 71);
+    LOWORD(v0) = p->uYawAngle;
+    v5 = p->uCurrentActionAnimation;
     v6 = ((signed int)((char *)v0 + ((signed int)stru_5C6E00->uIntegerPi >> 3) - v4 + stru_5C6E00->uIntegerPi) >> 8) & 7;
     v32 = v6;
     if ( pParty->bTurnBasedModeOn )
@@ -15347,16 +15174,16 @@
       {
         v7 = pBLVRenderParams->field_0_timer_;
 LABEL_10:
-        v8 = v40 + v7;
+        v8 = i * 32 + v7;
         goto LABEL_12;
       }
     }
-    v8 = *((_DWORD *)v2 + 37);
+    v8 = p->uCurrentActionTime;
 LABEL_12:
-    if ( *((_QWORD *)v2 + 32) > 0i64 || *((_QWORD *)v2 + 34) > 0i64 )
+    if (p->pActorBuffs[5].uExpireTime > 0i64 || p->pActorBuffs[6].uExpireTime > 0i64 )
       v8 = 0;
-    v31 = *(_WORD *)&v2[2 * (signed __int16)v5 + 152];
-    if ( *((_WORD *)v2 + 70) == 16 )
+    v31 = p->pSpriteIDs[v5];
+    if (p->uAIState == 16 )
       v9 = pSpriteFrameTable->GetFrameBy_x(v31, v8);
     else
       v9 = pSpriteFrameTable->GetFrame(v31, v8);
@@ -15388,25 +15215,24 @@
     }
     v12 = 0;
     if ( pStru170->field_53730 <= 0 )
-      goto LABEL_48;
-    while ( pStru170->pSectorIDs_toDrawDecorationsFrom[v12] != *((_WORD *)v2 + 61) )
+      continue;
+    while (pStru170->pSectorIDs_toDrawDecorationsFrom[v12] != p->uSectorID)
     {
       ++v12;
       if ( v12 >= pStru170->field_53730 )
-        goto LABEL_48;
+        continue;
     }
     if ( !pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(a1a, a2, a3, &x, &y, &z, 1)
       || (v0 = (RenderBillboard *)abs(x), (signed int)v0 < abs(y)) )
-      goto LABEL_48;
+      continue;
     pGame->pIndoorCameraD3D->Project(x, y, z, &v43, &a6);
-    result = uNumBillboardsToDraw;
+
     v0 = &pBillboardRenderList[uNumBillboardsToDraw];
-    if ( (signed int)uNumBillboardsToDraw >= 500 )
-      return result;
+    if (uNumBillboardsToDraw >= 500)
+      break;
     ++uNumBillboardsToDraw;
     ++uNumSpritesDrawnThisFrame;
-    v13 = (Actor *)(v2 - 36);
-    *(_DWORD *)v2 |= 8u;
+    p->uAttributes |= 8u;
     v29 = pRenderer->pRenderD3D == 0;
     v0->uHwSpriteID = v10->pHwSpriteIDs[v32];
     v0->uPalette = v10->uPaletteIndex;
@@ -15434,21 +15260,21 @@
       a5a = (unsigned __int64)(v10->scale * (signed __int64)v19) >> 16;
     }
     v0->field_4 = a5a;
-    if ( (signed __int64)v13->pActorBuffs[3].uExpireTime <= 0 )
-    {
-      if ( (signed __int64)v13->pActorBuffs[10].uExpireTime > 0 )
-      {
-        a5b = (unsigned __int64)(pGame->pStru6Instance->_4A806F((Actor *)(v2 - 36)) * (signed __int64)v0->field_4) >> 16;
+    if ( (signed __int64)p->pActorBuffs[3].uExpireTime <= 0 )
+    {
+      if ( (signed __int64)p->pActorBuffs[10].uExpireTime > 0 )
+      {
+        a5b = (unsigned __int64)(pGame->pStru6Instance->_4A806F(p) * (signed __int64)v0->field_4) >> 16;
         goto LABEL_43;
       }
     }
     else
     {
-      v22 = v13->pActorBuffs[3].uPower;
+      v22 = p->pActorBuffs[3].uPower;
       if ( v22 )
       {
         v23 = (unsigned __int64)(65536 / (unsigned __int16)v22 * (signed __int64)v0->field_0) >> 16;
-        v24 = *((_WORD *)v2 + 116);
+        v24 = p->pActorBuffs[3].uPower;
         v0->field_0 = v23;
         a5b = (unsigned __int64)(65536 / v24 * (signed __int64)v0->field_4) >> 16;
 LABEL_43:
@@ -15458,29 +15284,27 @@
     }
 LABEL_44:
     HIWORD(v25) = HIWORD(x);
-    v0->field_20 = a1a;
-    v0->field_22 = a2;
-    v0->field_24 = a3;
-    v0->field_26 = v43;
-    v0->field_28 = a6;
+    v0->some_x = a1a;
+    v0->some_y = a2;
+    v0->some_z = a3;
+    v0->uScreenSpaceX = v43;
+    v0->uScreenSpaceY = a6;
     LOWORD(v25) = 0;
     LOBYTE(v26) = v41;
-    v0->sZValue = v25 + (8 * v39 | 3);
+    v0->sZValue = v25 + (8 * i | 3);
     v27 = pMonsterList->pMonsters;
-    v28 = *((_WORD *)v2 + 30);
-    v29 = *((_DWORD *)v2 + 65) == 0;
-    v30 = *((_DWORD *)v2 + 65) < 0;
+    v28 = p->pMonsterInfo.uID;
+    v29 = HIDWORD(p->pActorBuffs[5].uExpireTime) == 0;
+    v30 = HIDWORD(p->pActorBuffs[5].uExpireTime) < 0;
     v0->field_1E = v41;
     v0->pSpriteFrame = v10;
-    v0->field_2C_prolly_tint = *((_DWORD *)&v27[v28] - 36);
-    if ( !v30 && (!(v30 | v29) || *((_DWORD *)v2 + 64)) )
+    v0->uTintColor = *((_DWORD *)&v27[v28] - 36);
+    if ( !v30 && (!(v30 | v29) || LODWORD(p->pActorBuffs[5].uExpireTime)) )
     {
       HIBYTE(v26) = HIBYTE(v41) | 1;
       v0->field_1E = v26;
     }
-    goto LABEL_48;
-  }
-  return result;
+  }
 }
 
 
--- a/mm7_5.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/mm7_5.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -8957,120 +8957,79 @@
 
 
 //----- (0043F333) --------------------------------------------------------
-int stru170::RenderWalls()
-{
-  signed int result; // eax@1
-  unsigned __int8 v2; // zf@1
-  unsigned __int8 v3; // sf@1
-  stru170_stru0 *v4; // edx@2
-  int v5; // eax@3
+void stru170::RenderWalls()
+{
   int v6; // ebx@3
-  char *v7; // esi@4
-  signed int v8; // [sp+0h] [bp-4h]@1
-
-  result = 0;
-  v2 = this->std__vector_000FA8 == 0;
-  v3 = (this->std__vector_000FA8 & 0x80000000u) != 0;
-  this->field_53730 = 0;
-  v8 = 0;
-  if ( !(v3 | v2) )
-  {
-    v4 = this->field_FA8;
-    do
-    {
-      v5 = this->field_53730;
+
+  field_53730 = 0;
+  for (uint i = 0; i < std__vector_000FA8; ++i)
+  {
       v6 = 0;
-      if ( v5 <= 0 )
+      if (!field_53730)
       {
 LABEL_7:
-        this->pSectorIDs_toDrawDecorationsFrom[v5] = v4->uSectorID;
-        ++this->field_53730;
+        pSectorIDs_toDrawDecorationsFrom[field_53730++] = field_FA8[i].uSectorID;
       }
       else
       {
-        v7 = (char *)this->pSectorIDs_toDrawDecorationsFrom;
-        while ( *(short *)v7 != v4->uSectorID )
+        while (pSectorIDs_toDrawDecorationsFrom[v6] != field_FA8[i].uSectorID )
         {
           ++v6;
-          v7 += 2;
-          if ( v6 >= v5 )
-            goto LABEL_7;
-        }
-      }
-      ++v8;
-      ++v4;
-      result = v8;
-    }
-    while ( v8 < (signed int)this->std__vector_000FA8 );
-  }
-  return result;
+          if ( v6 >= field_53730)
+          {
+            pSectorIDs_toDrawDecorationsFrom[field_53730++] = field_FA8[i].uSectorID;
+            continue;
+          }
+        }
+      }
+  }
 }
 
 
 //----- (0043F515) --------------------------------------------------------
-void __cdecl MessWithBillboards_BLV()
-{
-  signed int v0; // edi@1
-  char *v1; // esi@2
-
-  v0 = 0;
-  if ( (signed int)uNumBillboardsToDraw > 0 )
-  {
-    v1 = (char *)&pBillboardRenderList[0].field_2A;
-    do
-    {
-      if ( *(v1 - 12) & 2 || uCurrentlyLoadedLevelType == LEVEL_Indoor && !*((short *)v1 - 7) )
-        *(short *)v1 = 0;
-      else
-        *(short *)v1 = sub_43F55F((RenderBillboard *)(v1 - 42), -1);
-      ++v0;
-      v1 += 52;
-    }
-    while ( v0 < (signed int)uNumBillboardsToDraw );
+void MessWithBillboards_BLV()
+{
+  for (uint i = 0; i < uNumBillboardsToDraw; ++i)
+  {
+    auto p = pBillboardRenderList + i;
+
+    if (p->field_1E & 2 || uCurrentlyLoadedLevelType == LEVEL_Indoor && !p->uIndoorSectorID)
+      p->uPaletteSubindex = 0;
+    else
+      p->uPaletteSubindex = _43F55F_get_billboard_light_level(p, -1);
   }
 }
 
 //----- (0043F55F) --------------------------------------------------------
-signed int __fastcall sub_43F55F(RenderBillboard *a1, signed int a2)
-{
-  RenderBillboard *v2; // eax@1
+int __fastcall _43F55F_get_billboard_light_level(RenderBillboard *a1, int uBaseLightLevel)
+{
   signed int v3; // ecx@2
-  float v4; // ST08_4@6
-  float v5; // ST04_4@6
-  float v6; // ST00_4@6
-
-  v2 = a1;
+
   if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
   {
     v3 = pIndoor->pSectors[a1->uIndoorSectorID].uMinAmbientLightLevel;
   }
   else
   {
-    if ( a2 == -1 )
-      v3 = a1->field_2A;
+    if ( uBaseLightLevel == -1 )
+      v3 = a1->uPaletteSubindex;
     else
-      v3 = a2;
-  }
-  v4 = (double)v2->field_24;
-  v5 = (double)v2->field_22;
-  v6 = (double)v2->field_20;
-  return sub_43F5C8(v3, v2->uIndoorSectorID, v6, v5, v4);
+      v3 = uBaseLightLevel;
+  }
+  return _43F5C8_get_point_light_level_with_respect_to_lights(v3, a1->uIndoorSectorID, a1->some_x, a1->some_y, a1->some_z);
 }
 
 //----- (0043F5C8) --------------------------------------------------------
-signed int __fastcall sub_43F5C8(signed int a1, int a2, float a3, float a4, float a5)
+int __fastcall _43F5C8_get_point_light_level_with_respect_to_lights(unsigned int uBaseLightLevel, int uSectorID, float x, float y, float z)
 {
   int v5; // esi@1
   signed int v6; // edi@1
-  char *v7; // ebx@2
   int v8; // eax@6
   int v9; // ebx@6
   unsigned int v10; // ecx@6
   unsigned int v11; // edx@9
   unsigned int v12; // edx@11
   signed int v13; // ecx@12
-  BLVSector *v14; // esi@17
-  int v15; // ecx@17
   BLVLightMM7 *v16; // esi@20
   int v17; // ebx@21
   int v18; // eax@24
@@ -9080,7 +9039,6 @@
   unsigned int v22; // edx@27
   unsigned int v23; // edx@29
   signed int v24; // ecx@30
-  char *v25; // esi@34
   int v26; // ebx@35
   int v27; // eax@38
   int v28; // ebx@38
@@ -9089,53 +9047,41 @@
   unsigned int v31; // edx@41
   unsigned int v32; // edx@43
   signed int v33; // ecx@44
-  int v35; // [sp+Ch] [bp-18h]@4
-  BLVSector *v36; // [sp+Ch] [bp-18h]@17
   int v37; // [sp+Ch] [bp-18h]@37
   int v38; // [sp+10h] [bp-14h]@5
   int v39; // [sp+10h] [bp-14h]@23
   int v40; // [sp+10h] [bp-14h]@36
-  int v41; // [sp+14h] [bp-10h]@3
   int v42; // [sp+14h] [bp-10h]@22
   unsigned int v43; // [sp+18h] [bp-Ch]@12
   unsigned int v44; // [sp+18h] [bp-Ch]@30
   unsigned int v45; // [sp+18h] [bp-Ch]@44
-  char *v46; // [sp+1Ch] [bp-8h]@2
-  int v47; // [sp+1Ch] [bp-8h]@17
-  int v48; // [sp+20h] [bp-4h]@1
-  int v49; // [sp+20h] [bp-4h]@17
-  int v50; // [sp+20h] [bp-4h]@33
-
-  v48 = 0;
-  v5 = a2;
-  v6 = a1;
-  if ( uNumMobileLightsApplied > 0 )
-  {
-    v7 = (char *)&pMobileLights[0].uRadius;
-    v46 = (char *)&pMobileLights[0].uRadius;
-    do
-    {
-      v41 = abs((signed __int64)((double)*((short *)v7 - 3) - a3));
-      if ( v41 <= *(short *)v7 )
-      {
-        v35 = abs((signed __int64)((double)*((short *)v7 - 2) - a4));
-        if ( v35 <= *(short *)v7 )
-        {
-          v38 = abs((signed __int64)((double)*((short *)v7 - 1) - a5));
-          if ( v38 <= *(short *)v7 )
-          {
-            v8 = v41;
-            v9 = v35;
-            v10 = v38;
-            if ( v41 < v35 )
-            {
-              v8 = v35;
-              v9 = v41;
-            }
-            if ( v8 < v38 )
+
+  v6 = uBaseLightLevel;
+  for (uint i = 0; i < uNumMobileLightsApplied; ++i)
+  {
+    auto p = pMobileLights + i;
+
+      auto distX = abs(p->vPosition.x - x);
+      if ( distX <= p->uRadius)
+      {
+        auto distY = abs(p->vPosition.y - y);
+        if ( distY <= p->uRadius)
+        {
+          auto distZ = abs(p->vPosition.z - z);
+          if ( distZ <= p->uRadius)
+          {
+            v8 = distX;
+            v9 = distY;
+            v10 = distZ;
+            if (distX < distY)
+            {
+              v8 = distY;
+              v9 = distX;
+            }
+            if ( v8 < distZ )
             {
               v11 = v8;
-              v8 = v38;
+              v8 = distZ;
               v10 = v11;
             }
             if ( v9 < (signed int)v10 )
@@ -9144,41 +9090,31 @@
               v10 = v9;
               v9 = v12;
             }
-            v43 = ((unsigned int)(11 * v9) >> 5) + (v10 >> 2) + v8;
-            v13 = *(short *)v46;
+            v43 = ((unsigned int)(11 * v9) / 32) + (v10 / 4) + v8;
+            v13 = p->uRadius;
             if ( (signed int)v43 < v13 )
-              v6 = v6 + ((unsigned __int64)(30i64 * (signed int)(v43 << 16) / v13) >> 16) - 30;
-            v7 = v46;
-          }
-        }
-      }
-      ++v48;
-      v7 += 18;
-      v46 = v7;
-    }
-    while ( v48 < uNumMobileLightsApplied );
-  }
+              v6 += ((unsigned __int64)(30i64 * (signed int)(v43 << 16) / v13) >> 16) - 30;
+          }
+        }
+      }
+  }
+
   if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
   {
-    v14 = &pIndoor->pSectors[v5];
-    v15 = 0;
-    v49 = 0;
-    v36 = v14;
-    v47 = v14->uNumLights;
-    if ( v14->uNumLights > 0 )
-    {
-      while ( 1 )
-      {
-        v16 = &pIndoor->pLights[*(&v14->pLights->vPosition.x + v15)];
+    auto pSector = pIndoor->pSectors + uSectorID;
+
+    for (uint i = 0; i < pSector->uNumLights; ++i)
+    {
+        v16 = pIndoor->pLights + *(&pSector->pLights->vPosition.x + i);
         if ( !(v16->uAtributes & 8) )
         {
-          v17 = abs((signed __int64)((double)v16->vPosition.x - a3));
+          v17 = abs(v16->vPosition.x - x);
           if ( v17 <= v16->uRadius )
           {
-            v42 = abs((signed __int64)((double)v16->vPosition.y - a4));
+            v42 = abs(v16->vPosition.y - y);
             if ( v42 <= v16->uRadius )
             {
-              v39 = abs((signed __int64)((double)v16->vPosition.z - a5));
+              v39 = abs(v16->vPosition.z - z);
               if ( v39 <= v16->uRadius )
               {
                 v18 = v17;
@@ -9205,32 +9141,25 @@
                 v44 = ((unsigned int)(11 * v19) >> 5) + (v20 >> 2) + v18;
                 v24 = v16->uRadius;
                 if ( (signed int)v44 < v24 )
-                  v6 = v6 + ((unsigned __int64)(30i64 * (signed int)(v44 << 16) / v24) >> 16) - 30;
+                  v6 += ((unsigned __int64)(30i64 * (signed int)(v44 << 16) / v24) >> 16) - 30;
               }
             }
           }
         }
-        v15 = v49++ + 1;
-        if ( v49 >= v47 )
-          break;
-        v14 = v36;
-      }
-    }
-  }
-  v50 = 0;
-  if ( uNumStationaryLightsApplied > 0 )
-  {
-    v25 = (char *)&pStationaryLights[0].uRadius;
-    do
-    {
-      v26 = abs((signed __int64)((double)*((short *)v25 - 3) - a3));
-      if ( v26 <= *(short *)v25 )
-      {
-        v40 = abs((signed __int64)((double)*((short *)v25 - 2) - a4));
-        if ( v40 <= *(short *)v25 )
-        {
-          v37 = abs((signed __int64)((double)*((short *)v25 - 1) - a5));
-          if ( v37 <= *(short *)v25 )
+    }
+  }
+
+  for (uint i = 0; i < uNumStationaryLightsApplied; ++i)
+  {
+    auto p = pStationaryLights + i;
+      v26 = abs(p->vPosition.x - x);
+      if ( v26 <= p->uRadius)
+      {
+        v40 = abs(p->vPosition.y - y);
+        if ( v40 <= p->uRadius)
+        {
+          v37 = abs(p->vPosition.z - z);
+          if ( v37 <= p->uRadius)
           {
             v27 = v26;
             v28 = v40;
@@ -9254,17 +9183,14 @@
               v28 = v32;
             }
             v45 = ((unsigned int)(11 * v28) >> 5) + (v29 >> 2) + v27;
-            v33 = *(short *)v25;
+            v33 = p->uRadius;
             if ( (signed int)v45 < v33 )
-              v6 = v6 + ((unsigned __int64)(30i64 * (signed int)(v45 << 16) / v33) >> 16) - 30;
-          }
-        }
-      }
-      ++v50;
-      v25 += 12;
-    }
-    while ( v50 < uNumStationaryLightsApplied );
-  }
+              v6 += ((unsigned __int64)(30i64 * (signed int)(v45 << 16) / v33) >> 16) - 30;
+          }
+        }
+      }
+  }
+
   if ( v6 <= 31 )
   {
     if ( v6 < 0 )
@@ -9276,7 +9202,6 @@
   }
   return v6;
 }
-// 519AB4: using guessed type int uNumStationaryLightsApplied;
 
 //----- (00406051) --------------------------------------------------------
 __int16 stru262_TurnBased::StartTurn()
@@ -9483,7 +9408,7 @@
         if ( (signed __int16)v6 == 4 )
         {
           v3 = 0;
-          v5->uAIState = 5;
+          v5->uAIState = Dead;
           v5->uCurrentActionTime = 0;
           v5->uCurrentActionLength = 0;
           v5->UpdateAnimation();
@@ -10235,7 +10160,7 @@
             {
               v6->uCurrentActionTime = 0;
               v6->uCurrentActionLength = 0;
-              v6->uAIState = 5;
+              v6->uAIState = Dead;
               v6->UpdateAnimation();
             }
             if ( !thisa->_406D10(a2) )
@@ -10506,11 +10431,11 @@
                 v5->uCurrentActionTime += pMiscTimer->uTimeElapsed;
                 if ( (signed int)v5->uCurrentActionTime >= v5->uCurrentActionLength )
                 {
-                  if ( v5->uAIState == 4 )
+                  if (v5->uAIState == Dying)
                   {
                     v5->uCurrentActionTime = 0;
                     v5->uCurrentActionLength = 0;
-                    v5->uAIState = 5;
+                    v5->uAIState = Dead;
                     v5->UpdateAnimation();
                     return;
                   }
@@ -11915,7 +11840,7 @@
 }
 
 //----- (00408896) --------------------------------------------------------
-char *__cdecl UpdateLayingItems()
+void UpdateLayingItems()
 {
   unsigned int v0; // edi@1
   char *v1; // esi@1
@@ -11931,14 +11856,9 @@
     ++v0;
   }
   while ( (signed int)v1 < (signed int)((char *)&pObjectList->uNumObjects + 2) );
-  result = (char *)&array_5118E8.pElements[0].field_C;
-  do
-  {
-    *(short *)result = 0;
-    result += 24;
-  }
-  while ( (signed int)result < (signed int)&pBillboardRenderList[0].field_4 );
-  return result;
+
+  for (uint i = 0; i < 100; ++i)
+    array_5118E8.pElements[i].field_C_time_left = 0;
 }
 
 //----- (004088E9) --------------------------------------------------------
@@ -17286,7 +17206,7 @@
     v4 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, 0xFFu, 0);
   else
     v4 = 0xFFFFu;
-  sprintfex(pTmpBuf2, &byte_4E2F14, pGlobalTXT_LocalizationStrings[207], v4, pPlayer->uSkillPoints);
+  sprintfex(pTmpBuf2, "\xC" "00000\xD" "180%s: \xC%05d%d\xC" "00000\n\n\n", pGlobalTXT_LocalizationStrings[207], v4, pPlayer->uSkillPoints);
   strcat(pTmpBuf, pTmpBuf2);
   pGUIWindow_CurrentMenu->DrawText(pFontArrus, 26, 18, 0, pTmpBuf, 0, 0, 0);
   v5 = pPlayer->GetBaseStrength();
--- a/mm7_6.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/mm7_6.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -8862,8 +8862,6 @@
 //----- (0042FC4E) --------------------------------------------------------
 void __cdecl ProcessInputActions()
 {
-  Keyboard *v0; // ecx@1
-  signed int _1; // ebx@7
   ActionQueue *pActionQueue; // esi@7
   Keyboard *v3; // ecx@8
   char v4; // al@9
@@ -8889,24 +8887,27 @@
   int v24; // [sp+4h] [bp-4h]@87
 
   pGame->pKeyboardInstance->EnterCriticalSection();
-  v0 = pGame->pKeyboardInstance;
-  if ( !bAlwaysRun )
+  auto pKeyboard = pGame->pKeyboardInstance;
+  if (!bAlwaysRun)
   {
-    if ( v0->IsShiftHeld() )
-      goto _set_running;
-_set_not_running:
-    pParty->uFlags2 &= 0xFFFFFFFDu;
-    goto LABEL_6;
+    if (pKeyboard->IsShiftHeld())
+      pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
+    else
+      pParty->uFlags2 &= ~PARTY_FLAGS_2_RUNNING;
+   }
+  else
+  {
+    if (pKeyboard->IsShiftHeld())
+      pParty->uFlags2 &= ~PARTY_FLAGS_2_RUNNING;
+    else
+      pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
   }
-  if ( v0->IsShiftHeld() )
-    goto _set_not_running;
-_set_running:
+
   pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
 LABEL_6:
   if ( !pEventTimer->bPaused )
   {
     inputAction = (InputAction)0;
-    _1 = 1;
     pActionQueue = pPartyActionQueue;
     while ( 1 )
     {
@@ -8923,9 +8924,9 @@
           case INPUT_MoveForward:
             if ( pCurrentScreen )
               break;
-            if ( pParty->bTurnBasedModeOn != _1 )
+            if (!pParty->bTurnBasedModeOn)
               goto _do_move_forward;
-            if ( pTurnEngine->field_4 != _1 && pTurnEngine->field_4 != 2 && pTurnEngine->uActionPointsLeft > 0 )
+            if (pTurnEngine->field_4 != 1 && pTurnEngine->field_4 != 2 && pTurnEngine->uActionPointsLeft > 0 )
             {
               pTurnEngine->uActionPointsLeft -= 26;
 _do_move_forward:
@@ -8940,9 +8941,9 @@
           case INPUT_MoveBackwards:
             if ( pCurrentScreen )
               break;
-            if ( pParty->bTurnBasedModeOn != _1 )
+            if (!pParty->bTurnBasedModeOn)
               goto _do_move_backwards;
-            if ( pTurnEngine->field_4 != _1 && pTurnEngine->field_4 != 2 && pTurnEngine->uActionPointsLeft > 0 )
+            if ( pTurnEngine->field_4 != 1 && pTurnEngine->field_4 != 2 && pTurnEngine->uActionPointsLeft > 0 )
             {
               pTurnEngine->uActionPointsLeft -= 26;
 _do_move_backwards:
@@ -8957,9 +8958,9 @@
           case INPUT_StrafeLeft:
             if ( pCurrentScreen )
               break;
-            if ( pParty->bTurnBasedModeOn != _1 )
+            if (!pParty->bTurnBasedModeOn)
               goto _do_strafe_left;
-            if ( pTurnEngine->field_4 == _1 || pTurnEngine->field_4 == 2 || pTurnEngine->uActionPointsLeft <= 0 )
+            if ( pTurnEngine->field_4 == 1 || pTurnEngine->field_4 == 2 || pTurnEngine->uActionPointsLeft <= 0 )
               break;
             pTurnEngine->uActionPointsLeft -= 26;
 _do_strafe_left:
@@ -8968,9 +8969,9 @@
           case INPUT_StrafeRight:
             if ( pCurrentScreen )
               break;
-            if ( pParty->bTurnBasedModeOn != _1 )
+            if (!pParty->bTurnBasedModeOn)
               goto _do_strafe_right;
-            if ( pTurnEngine->field_4 == _1 || pTurnEngine->field_4 == 2 || pTurnEngine->uActionPointsLeft <= 0 )
+            if ( pTurnEngine->field_4 == 1 || pTurnEngine->field_4 == 2 || pTurnEngine->uActionPointsLeft <= 0 )
               break;
             pTurnEngine->uActionPointsLeft -= 26;
 _do_strafe_right:
@@ -8981,9 +8982,9 @@
               break;
             if ( GetAsyncKeyState(VK_CONTROL) ) // strafing
             {
-              if ( pParty->bTurnBasedModeOn == _1 )
+              if (pParty->bTurnBasedModeOn)
               {
-                if ( pTurnEngine->field_4 == _1 || pTurnEngine->field_4 == 2 || pTurnEngine->uActionPointsLeft <= 0 )
+                if ( pTurnEngine->field_4 == 1 || pTurnEngine->field_4 == 2 || pTurnEngine->uActionPointsLeft <= 0 )
                   break;
                 pTurnEngine->uActionPointsLeft -= 26;
               }
@@ -8994,10 +8995,10 @@
               if ( pParty->uFlags2 & 2 )
                 partyAction_ = PARTY_FastTurnLeft;
               else
-                partyAction_ = (PartyAction)_1;
+                partyAction_ = PARTY_TurnLeft;
             }
             pActionQueue->Add(partyAction_);
-            if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor && pWeather->bRenderSnow == _1 )
+            if (uCurrentlyLoadedLevelType == LEVEL_Outdoor && pWeather->bRenderSnow)
             {
               v20 = 10;
               goto LABEL_75;
@@ -9008,9 +9009,9 @@
               break;
             if ( GetAsyncKeyState(17) )         // strafing
             {
-              if ( pParty->bTurnBasedModeOn == _1 )
+              if (pParty->bTurnBasedModeOn)
               {
-                if ( pTurnEngine->field_4 == _1 || pTurnEngine->field_4 == 2 || pTurnEngine->uActionPointsLeft <= 0 )
+                if ( pTurnEngine->field_4 == 1 || pTurnEngine->field_4 == 2 || pTurnEngine->uActionPointsLeft <= 0 )
                   break;
                 pTurnEngine->uActionPointsLeft -= 26;
               }
@@ -9024,7 +9025,7 @@
                 v21 = 2;
             }
             pActionQueue->Add((PartyAction)v21);
-            if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor && pWeather->bRenderSnow == _1 )
+            if (uCurrentlyLoadedLevelType == LEVEL_Outdoor && pWeather->bRenderSnow)
             {
               v20 = -10;
 LABEL_75:
@@ -9033,7 +9034,7 @@
             break;
           case INPUT_Jump:
             if ( pCurrentScreen
-              || pParty->bTurnBasedModeOn == _1 )
+              || pParty->bTurnBasedModeOn)
               break;
             partyAction = (PartyAction)12;
             goto _add_action_and_continue_;
@@ -9048,7 +9049,7 @@
           case INPUT_Pass:
             if ( pCurrentScreen )
               break;
-            if ( pParty->bTurnBasedModeOn == _1 && pTurnEngine->field_4 == 3 )
+            if (pParty->bTurnBasedModeOn && pTurnEngine->field_4 == 3)
               goto LABEL_118;
             if ( uActiveCharacter )
             {
@@ -9067,25 +9068,25 @@
           case INPUT_Combat:
             if ( !pCurrentScreen )
             {
-              if ( pParty->bTurnBasedModeOn == _1 )
+              if (pParty->bTurnBasedModeOn)
               {
                 if ( pTurnEngine->field_4 == 3 || (pTurnEngine->pQueue[0].uPackedID & 7) == 4 )
                 {
                   pParty->bTurnBasedModeOn = 0;
-                  pTurnEngine->End(_1);
+                  pTurnEngine->End(true);
                 }
               }
               else
               {
                 pTurnEngine->Start();
-                pParty->bTurnBasedModeOn = _1;
+                pParty->bTurnBasedModeOn = true;
               }
             }
             break;
           case INPUT_CastReady:
             if ( pCurrentScreen )
               break;
-            if ( pParty->bTurnBasedModeOn == _1 && pTurnEngine->field_4 == 3 )
+            if (pParty->bTurnBasedModeOn && pTurnEngine->field_4 == 3)
               goto LABEL_118;
             if ( !uActiveCharacter )
               break;
@@ -9097,7 +9098,6 @@
                   v10 > v7->sMana) )
             {
               pActionQueue = pPartyActionQueue;
-              _1 = 1;
 LABEL_120:
               if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
               {
@@ -9115,7 +9115,6 @@
                 *(&dword_50C9E8 + 3 * dword_50C9E8 + 3) = 0;
                 ++dword_50C9E8;
               }
-              _1 = 1;
             }
             break;
           default:
@@ -9123,7 +9122,7 @@
           case INPUT_Attack:
             if ( pCurrentScreen )
               break;
-            if ( pParty->bTurnBasedModeOn != _1 || pTurnEngine->field_4 != 3 )
+            if (!pParty->bTurnBasedModeOn || pTurnEngine->field_4 != 3)
               goto LABEL_120;
 LABEL_118:
             pTurnEngine->field_18 |= 8u;
@@ -9143,8 +9142,8 @@
               {
                 if ( pMessageQueue_50CBD0->pMessages[0].field_8 )
                 {
-                  v11 = _1;
-                  pMessageQueue_50CBD0->uNumMessages = _1;
+                  v11 = 1;
+                  pMessageQueue_50CBD0->uNumMessages = 1;
 LABEL_132:
                   pMessageQueue_50CBD0->pMessages[v11].eType = (UIMessageType)113;
 _send_message:
--- a/mm7_data.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/mm7_data.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -332,7 +332,6 @@
 char byte_4D864C; // weak
 int dword_4D86CC; // weak
 int dword_4D86D8; // weak
-int dword_4D86F0; // weak
 int dword_4DAFCC; // weak
 int (__stdcall *off_4DAFDC)(char); // weak
 char asc_4DB724[777]; // idb
@@ -543,270 +542,12 @@
 char aSS_0[777]; // idb
 char aS_5[4]; // idb
 _UNKNOWN unk_4E2EB8; // weak
-char aS_4[2]; // idb
-char aS_0[2]; // idb
-char byte_4E2F14; // idb
-char aFr_stats[777]; // idb
-char aS1772d[777]; // idb
-char aS_10[3]; // idb
-char aS177S[777]; // idb
-char aS4002d[777]; // idb
-char aS_9[3]; // idb
-char aS400S[777]; // idb
-char aS_8[38];
-char aFr_skill[777]; // idb
-char byte_4E2FD4[7];
-char aS_11[3]; // idb
-char aFr_award[777]; // idb
-char aSptext01[777]; // idb
-char aSp28a[6]; // weak
-char aSp30a[6]; // weak
-char aSp91a[6]; // weak
-char aFr_strip[777]; // idb
-char a261SD[777]; // idb
-char aS_12[4]; // idb
-char aD_2[4];
-char aLu[4];
-char aQuikref[777]; // idb
-char aIbCd1D[777]; // idb
-char aIbCd2D[777]; // idb
-char aIbCd4D[777]; // idb
-char aIbCd3D[777]; // idb
-char a028Lu[777]; // idb
-char a087Lu[777]; // idb
-char aComic_fnt[777]; // idb
-char aSmallnum_fnt[777]; // idb
-char aCreate_fnt[777]; // idb
-char aLucida_fnt[777]; // idb
-char aArrus_fnt[777]; // idb
-char aIbTd5A[777]; // idb
-char aIbTd4A[777]; // idb
-char aIbTd3A[777]; // idb
-char aIbTd2A[777]; // idb
-char aIbTd1A[777]; // idb
-char aButtmake2[777]; // idb
-char aButtmake[777]; // idb
-char aButtyes2[777]; // idb
-char aX_ok_u[777]; // idb
-char aButtesc2[777]; // idb
-char aX_x_u[777]; // idb
-char aIbground[777]; // idb
-char aLeather[777]; // idb
-char aMhp_yel[777]; // idb
-char aMhp_red[777]; // idb
-char aMhp_grn[777]; // idb
-char aMhp_capr[777]; // idb
-char aMhp_capl[777]; // idb
-char aMhp_bg[777]; // idb
-char aIbStatr[777]; // idb
-char aIbStaty[777]; // idb
-char aIbStatg[777]; // idb
-char aIbStatb[777]; // idb
-char aMapdir7[777]; // idb
-char aMapdir6[777]; // idb
-char aMapdir5[777]; // idb
-char aMapdir4[777]; // idb
-char aMapdir3[777]; // idb
-char aMapdir2[777]; // idb
-char aMapdir1[777]; // idb
-char aMapdir8[777]; // idb
-char aTorcha[777]; // idb
-char aTorchb[777]; // idb
-char aTorchc[777]; // idb
-char aWizeyea[777]; // idb
-char aWizeyeb[777]; // idb
-char aWizeyec[777]; // idb
-char aTest[777]; // idb
-char aMicon2[777]; // idb
-char aButton[777]; // idb
-char aDS[777]; // idb
-char a020[777]; // idb
-char aS_14[4]; // idb
-char aS_13[5]; // idb
 char string_4E3294[8];
-char aDMn[777]; // idb
-char aDHr[777]; // idb
-char aDDy[777]; // idb
-char aDMo[777]; // idb
-char aDYr[777]; // idb
-char aDuration[777]; // idb
-char aSLu[777]; // idb
-char aSSD[777]; // idb
-char aSD_1[777]; // idb
-char aD_0[777]; // idb
-char aSDSDdD[777]; // idb
-char aS_21[2]; // idb
-char byte_4E3318; // idb
-char aS_20[2]; // idb
-char aS_19[2]; // idb
-char aS_18[2]; // idb
-char aS_17[2]; // idb
-char aS_16[2]; // idb
-char aS_15[2]; // idb
-char aTerra03d[777]; // idb
-char aRestexit[777]; // idb
-char aRestb4[777]; // idb
-char aRestb3[777]; // idb
-char aRestb2[777]; // idb
-char aRestb1[777]; // idb
-char aRestmain[777]; // idb
-char aD29_blv[777]; // idb
-char aS190D[777]; // idb
-char aD02dS[777]; // idb
-char a408D[777]; // idb
-char aHglas03d[777]; // idb
-char aChest02d[777]; // idb
-char aMicon1[777]; // idb
-char aEndcapB[777]; // idb
-char aEdge_topB[777]; // idb
-char aEdge_rtB[777]; // idb
-char aEdge_lfB[777]; // idb
-char aEdge_btmB[777]; // idb
-char aCornr_urB[777]; // idb
-char aCornr_ulB[777]; // idb
-char aCornr_lrB[777]; // idb
-char aCornr_llB[777]; // idb
-char aFr_invenB[777]; // idb
-char aEvtnpcB[777]; // idb
-char aIbBcuB[777]; // idb
-char aIsg04B[777]; // idb
-char aIsg03B[777]; // idb
-char aIsg02B[777]; // idb
-char aIsg01B[777]; // idb
-char aIbM4dB[777]; // idb
-char aIbM3dB[777]; // idb
-char aIbM2dB[777]; // idb
-char aIbM1dB[777]; // idb
-char aIbSelecB[777]; // idb
-char aIbAutinB[777]; // idb
-char aIbAutoutB[777]; // idb
-char aIbNpcrdB[777]; // idb
-char aIbNpcldB[777]; // idb
-char aIbInitrB[777]; // idb
-char aIbInityB[777]; // idb
-char aIbInitgB[777]; // idb
-char aIbCompB[777]; // idb
-char aIbAutmaskB[777]; // idb
-char aIbMbB[777]; // idb
-char aIbFootB_pcx[777]; // idb
-char aIbLB_pcx[777]; // idb
-char aIbTB_pcx[777]; // idb
-char aIbBB_pcx[777]; // idb
-char aIbRB_pcx[777]; // idb
-char aIbSelecA_0[777]; // idb
-char aIbNpcrdA_0[777]; // idb
-char aIbNpcldA_0[777]; // idb
-char aIbCompA_0[777]; // idb
-char aIbMbA_0[777]; // idb
-char aIbLA_pcx_0[777]; // idb
-char aIbTA_pcx_0[777]; // idb
-char aIbBA_pcx_0[777]; // idb
-char aIbRA_pcx_0[777]; // idb
-char aEndcap[777]; // idb
-char aEdge_top[777]; // idb
-char aEdge_rt[777]; // idb
-char aEdge_lf[777]; // idb
-char aEdge_btm[777]; // idb
-char aCornr_ur[777]; // idb
-char aCornr_ul[777]; // idb
-char aCornr_lr[777]; // idb
-char aCornr_ll[777]; // idb
-char aEvtnpc[777]; // idb
-char aIsg04A[777]; // idb
-char aIsg03A[777]; // idb
-char aIsg02A[777]; // idb
-char aIsg01A[777]; // idb
-char aIbBcuA[777]; // idb
-char aIbAutinA[777]; // idb
-char aIbAutoutA[777]; // idb
-char aIbM4dA[777]; // idb
-char aIbM3dA[777]; // idb
-char aIbM2dA[777]; // idb
-char aIbM1dA[777]; // idb
-char aIbSelecA[777]; // idb
-char aIbNpcrdA[777]; // idb
-char aIbNpcldA[777]; // idb
-char aIbInitrA[777]; // idb
-char aIbInityA[777]; // idb
-char aIbInitgA[777]; // idb
-char aIbCompA[777]; // idb
-char aIbAutmaskA[777]; // idb
-char aIbMbA[777]; // idb
-char aIbFootA_pcx[777]; // idb
-char aIbLA_pcx[11]; // weak
-char aIbTA_pcx[11]; // weak
-char aIbBA_pcx[11]; // weak
-char aIbRA_pcx[11]; // weak
-char aEndcapC[777]; // idb
-char aEdge_topC[777]; // idb
-char aEdge_rtC[777]; // idb
-char aEdge_lfC[777]; // idb
-char aEdge_btmC[777]; // idb
-char aCornr_urC[777]; // idb
-char aCornr_ulC[777]; // idb
-char aCornr_lrC[777]; // idb
-char aCornr_llC[777]; // idb
-char aParchment[777]; // idb
-char pContainer[777]; // idb
-char aIbBC_pcx_0[777]; // idb
-char aFr_inven[777]; // idb
-char aEvtnpcC[777]; // idb
-char aIsg04C[777]; // idb
-char aIsg03C[777]; // idb
-char aIsg02C[777]; // idb
-char aIsg01C[777]; // idb
-char aIbBcuC[777]; // idb
-char aIbM4dC[777]; // idb
-char aIbM3dC[777]; // idb
-char aIbM2dC[777]; // idb
-char aIbM1dC[777]; // idb
-char aIbSelecC[777]; // idb
-char aIbAutinC[777]; // idb
-char aIbAutoutC[777]; // idb
-char aIbNpcrdC[777]; // idb
-char aIbNpcldC[777]; // idb
-char aIbInitrC[777]; // idb
-char aIbInityC[777]; // idb
-char aIbInitgC[777]; // idb
-char aIbCompC[777]; // idb
-char aIbAutmaskC[777]; // idb
-char aIbMbC[777]; // idb
-char aIbFootC_pcx[777]; // idb
-char aIbLC_pcx[777]; // idb
-char aIbTC_pcx[777]; // idb
-char aIbBC_pcx[11]; // weak
-char aIbRC_pcx[777]; // idb
-char a10i10iS[777]; // idb
-char aSizeIII[777]; // idb
-char aDwavailvirtual[777]; // idb
-char aDwtotalvirtual[777]; // idb
-char aDwavailpagefil[777]; // idb
-char aDwtotalpagefil[777]; // idb
-char aDwavailphysD[777]; // idb
-char aDwtotalphysD[777]; // idb
-char aDwmemoryloadD[777]; // idb
-char aDwlengthD[777]; // idb
 char Format[777]; // idb
 char aMem03i_txt[777]; // idb
 char aMemory[777]; // idb
 char aIdSSizeI[16]; // idb
 __int16 word_4E3C66[777]; // idb
-char aSpell96[777]; // idb
-char aNothing[777]; // idb
-char aS_22[5]; // weak
-char aDGold[777]; // idb
-char aSAndDGold[777]; // idb
-char aD05_blv[777]; // idb
-char aSpell11[777]; // idb
-char aAframe1[777]; // idb
-char aTurnstart[777]; // idb
-char aTurnhour[777]; // idb
-char aTurnstop[777]; // idb
-char aTurn4[777]; // idb
-char aTurn3[777]; // idb
-char aTurn2[777]; // idb
-char aTurn1[777]; // idb
-char aTurn0[777]; // idb
 int dword_4E455C; // weak
 int dword_4E4560[6];
 int dword_4E4578[6];
@@ -1985,81 +1726,6 @@
 
 char aDD[777]; // idb
 char off_4EE75C[777]; // idb
-char aFacemask[777]; // idb
-char aDead_0[777]; // idb
-char aEradcate[777]; // idb
-char aS02d[777]; // idb
-char aUnableToSaveDp[777]; // idb
-char aDataDpft_bin[777]; // idb
-char aPlayerframet_1[777]; // idb
-char aPlayerframet_0[777]; // idb
-char aPlayerframetab[777]; // idb
-char aUnableToSaveDi[777]; // idb
-char aDataDift_bin[777]; // idb
-char aIFrames[777]; // idb
-char aIconframetab_0[777]; // idb
-char aIconframetable[777]; // idb
-char aInvalidStrin_1[22]; // weak
-char a03uS[777]; // idb
-char aS03dD[777]; // idb
-char aCchar_fnt[777]; // idb
-char aArrowrD[777]; // idb
-char aArrowlD[777]; // idb
-char aPresleft[777]; // idb
-char aPresrigh[777]; // idb
-char aButtplus[777]; // idb
-char aButtminu[777]; // idb
-char aS01[777]; // idb
-char aMakesky[777]; // idb
-char aMaketop[777]; // idb
-char aIc_sorc[777]; // idb
-char aIc_druid[777]; // idb
-char aIc_cler[777]; // idb
-char aIc_ranger[777]; // idb
-char aIc_arch[777]; // idb
-char aIc_palad[777]; // idb
-char aIc_monk[777]; // idb
-char aIc_thief[777]; // idb
-char aIc_knight[777]; // idb
-char aScrollermap[777]; // idb
-char aCredits_txt[777]; // idb
-char aMm6title_pcx[13]; // weak
-char aQuick_fnt[777]; // idb
-char aL_map[777]; // idb
-char aL_bsp[777]; // idb
-char aL_d[777]; // idb
-char aL_l[777]; // idb
-char aL_r[777]; // idb
-char aL_fx[777]; // idb
-char aL_f[777]; // idb
-char aL_v[777]; // idb
-char aD29_dlv[777]; // idb
-char a_dlv[777]; // idb
-char aEWorkMsdevM_20[777]; // idb
-char a_blv[777]; // idb
-char aL_ddata[777]; // idb
-char aL_rldata[777]; // idb
-char aL_rdata[777]; // idb
-char aL_fdata[777]; // idb
-char aHwsplat04[777]; // idb
-char aErrorFailedT_0[777]; // idb
-char aEWorkMsdevM_21[777]; // idb
-char aReferenceRaste[777]; // idb
-char aRgbEmulation[777]; // idb
-char aInitFailedTo_7[777]; // idb
-char aInitFailedTo_6[777]; // idb
-char aInitFailedToAt[777]; // idb
-char aInitFailedTo_5[777]; // idb
-char aInitFailedToGe[37]; // weak
-char aInitFailedTo_4[39]; // weak
-char aInitFailedTo_3[36]; // weak
-char aInitFailedToEn[46]; // weak
-char aInitFailedTo_2[34]; // weak
-char aInitFailedTo_1[38]; // weak
-char aInitDesktopIsn[777]; // idb
-char aInitFailedToSe[777]; // idb
-char aInitFailedTo_0[777]; // idb
-char aInitFailedToCr[777]; // idb
 int dword_4EED78; // weak
 _UNKNOWN unk_4EED80; // weak
 int dword_4EFA80; // weak
@@ -2611,7 +2277,6 @@
 int dword_69B010[64];
 int dword_69B138; // weak
 char byte_69BD41_unused; // weak
-std::string stru_69BD44; // idb
 unsigned int uTextureID_x_u;
 unsigned int uTextureID_LS_saveU;
 unsigned int uTextureID_LS_loadU;
@@ -2722,7 +2387,6 @@
 int uTextureID_720980; // weak
 int _720984_unused; // weak
 char _72098C_unused; // weak
-std::string std__string_720990; // idb
 __int16 word_7209A0_intercepts_ys_plus_ys[104];
 __int16 word_720A70_intercepts_xs_plus_xs[104];
 __int16 word_720B40_intercepts_zs[104];
@@ -2850,7 +2514,6 @@
 Vec3_float_ stru_AE4F7C; // idb
 int dword_AE4F88; // weak
 char byte_AE5B91; // weak
-std::string std__string_AE5B94; // idb
 int dword_F1B430[32]; // weak
 int dword_F8B144; // idb
 char byte_F8B148[16];
--- a/mm7_data.h	Tue Oct 23 17:33:33 2012 +0600
+++ b/mm7_data.h	Tue Oct 23 17:34:20 2012 +0600
@@ -319,7 +319,6 @@
 extern char byte_4D864C; // weak
 extern int dword_4D86CC; // weak
 extern int dword_4D86D8; // weak
-extern int dword_4D86F0; // weak
 extern int dword_4DAFCC; // weak
 extern int (__stdcall *off_4DAFDC)(char); // weak
 extern char asc_4DB724[]; // idb
@@ -530,270 +529,12 @@
 extern char aSS_0[]; // idb
 extern char aS_5[4]; // idb
 extern _UNKNOWN unk_4E2EB8; // weak
-extern char aS_4[2]; // idb
-extern char aS_0[2]; // idb
-extern char byte_4E2F14; // idb
-extern char aFr_stats[]; // idb
-extern char aS1772d[]; // idb
-extern char aS_10[3]; // idb
-extern char aS177S[]; // idb
-extern char aS4002d[]; // idb
-extern char aS_9[3]; // idb
-extern char aS400S[]; // idb
-extern char aS_8[38];
-extern char aFr_skill[]; // idb
-extern char byte_4E2FD4[7];
-extern char aS_11[3]; // idb
-extern char aFr_award[]; // idb
-extern char aSptext01[]; // idb
-extern char aSp28a[6]; // weak
-extern char aSp30a[6]; // weak
-extern char aSp91a[6]; // weak
-extern char aFr_strip[]; // idb
-extern char a261SD[]; // idb
-extern char aS_12[4]; // idb
-extern char aD_2[4];
-extern char aLu[4];
-extern char aQuikref[]; // idb
-extern char aIbCd1D[]; // idb
-extern char aIbCd2D[]; // idb
-extern char aIbCd4D[]; // idb
-extern char aIbCd3D[]; // idb
-extern char a028Lu[]; // idb
-extern char a087Lu[]; // idb
-extern char aComic_fnt[]; // idb
-extern char aSmallnum_fnt[]; // idb
-extern char aCreate_fnt[]; // idb
-extern char aLucida_fnt[]; // idb
-extern char aArrus_fnt[]; // idb
-extern char aIbTd5A[]; // idb
-extern char aIbTd4A[]; // idb
-extern char aIbTd3A[]; // idb
-extern char aIbTd2A[]; // idb
-extern char aIbTd1A[]; // idb
-extern char aButtmake2[]; // idb
-extern char aButtmake[]; // idb
-extern char aButtyes2[]; // idb
-extern char aX_ok_u[]; // idb
-extern char aButtesc2[]; // idb
-extern char aX_x_u[]; // idb
-extern char aIbground[]; // idb
-extern char aLeather[]; // idb
-extern char aMhp_yel[]; // idb
-extern char aMhp_red[]; // idb
-extern char aMhp_grn[]; // idb
-extern char aMhp_capr[]; // idb
-extern char aMhp_capl[]; // idb
-extern char aMhp_bg[]; // idb
-extern char aIbStatr[]; // idb
-extern char aIbStaty[]; // idb
-extern char aIbStatg[]; // idb
-extern char aIbStatb[]; // idb
-extern char aMapdir7[]; // idb
-extern char aMapdir6[]; // idb
-extern char aMapdir5[]; // idb
-extern char aMapdir4[]; // idb
-extern char aMapdir3[]; // idb
-extern char aMapdir2[]; // idb
-extern char aMapdir1[]; // idb
-extern char aMapdir8[]; // idb
-extern char aTorcha[]; // idb
-extern char aTorchb[]; // idb
-extern char aTorchc[]; // idb
-extern char aWizeyea[]; // idb
-extern char aWizeyeb[]; // idb
-extern char aWizeyec[]; // idb
-extern char aTest[]; // idb
-extern char aMicon2[]; // idb
-extern char aButton[]; // idb
-extern char aDS[]; // idb
-extern char a020[]; // idb
-extern char aS_14[4]; // idb
-extern char aS_13[5]; // idb
 extern char string_4E3294[8];
-extern char aDMn[]; // idb
-extern char aDHr[]; // idb
-extern char aDDy[]; // idb
-extern char aDMo[]; // idb
-extern char aDYr[]; // idb
-extern char aDuration[]; // idb
-extern char aSLu[]; // idb
-extern char aSSD[]; // idb
-extern char aSD_1[]; // idb
-extern char aD_0[]; // idb
-extern char aSDSDdD[]; // idb
-extern char aS_21[2]; // idb
-extern char byte_4E3318; // idb
-extern char aS_20[2]; // idb
-extern char aS_19[2]; // idb
-extern char aS_18[2]; // idb
-extern char aS_17[2]; // idb
-extern char aS_16[2]; // idb
-extern char aS_15[2]; // idb
-extern char aTerra03d[]; // idb
-extern char aRestexit[]; // idb
-extern char aRestb4[]; // idb
-extern char aRestb3[]; // idb
-extern char aRestb2[]; // idb
-extern char aRestb1[]; // idb
-extern char aRestmain[]; // idb
-extern char aD29_blv[]; // idb
-extern char aS190D[]; // idb
-extern char aD02dS[]; // idb
-extern char a408D[]; // idb
-extern char aHglas03d[]; // idb
-extern char aChest02d[]; // idb
-extern char aMicon1[]; // idb
-extern char aEndcapB[]; // idb
-extern char aEdge_topB[]; // idb
-extern char aEdge_rtB[]; // idb
-extern char aEdge_lfB[]; // idb
-extern char aEdge_btmB[]; // idb
-extern char aCornr_urB[]; // idb
-extern char aCornr_ulB[]; // idb
-extern char aCornr_lrB[]; // idb
-extern char aCornr_llB[]; // idb
-extern char aFr_invenB[]; // idb
-extern char aEvtnpcB[]; // idb
-extern char aIbBcuB[]; // idb
-extern char aIsg04B[]; // idb
-extern char aIsg03B[]; // idb
-extern char aIsg02B[]; // idb
-extern char aIsg01B[]; // idb
-extern char aIbM4dB[]; // idb
-extern char aIbM3dB[]; // idb
-extern char aIbM2dB[]; // idb
-extern char aIbM1dB[]; // idb
-extern char aIbSelecB[]; // idb
-extern char aIbAutinB[]; // idb
-extern char aIbAutoutB[]; // idb
-extern char aIbNpcrdB[]; // idb
-extern char aIbNpcldB[]; // idb
-extern char aIbInitrB[]; // idb
-extern char aIbInityB[]; // idb
-extern char aIbInitgB[]; // idb
-extern char aIbCompB[]; // idb
-extern char aIbAutmaskB[]; // idb
-extern char aIbMbB[]; // idb
-extern char aIbFootB_pcx[]; // idb
-extern char aIbLB_pcx[]; // idb
-extern char aIbTB_pcx[]; // idb
-extern char aIbBB_pcx[]; // idb
-extern char aIbRB_pcx[]; // idb
-extern char aIbSelecA_0[]; // idb
-extern char aIbNpcrdA_0[]; // idb
-extern char aIbNpcldA_0[]; // idb
-extern char aIbCompA_0[]; // idb
-extern char aIbMbA_0[]; // idb
-extern char aIbLA_pcx_0[]; // idb
-extern char aIbTA_pcx_0[]; // idb
-extern char aIbBA_pcx_0[]; // idb
-extern char aIbRA_pcx_0[]; // idb
-extern char aEndcap[]; // idb
-extern char aEdge_top[]; // idb
-extern char aEdge_rt[]; // idb
-extern char aEdge_lf[]; // idb
-extern char aEdge_btm[]; // idb
-extern char aCornr_ur[]; // idb
-extern char aCornr_ul[]; // idb
-extern char aCornr_lr[]; // idb
-extern char aCornr_ll[]; // idb
-extern char aEvtnpc[]; // idb
-extern char aIsg04A[]; // idb
-extern char aIsg03A[]; // idb
-extern char aIsg02A[]; // idb
-extern char aIsg01A[]; // idb
-extern char aIbBcuA[]; // idb
-extern char aIbAutinA[]; // idb
-extern char aIbAutoutA[]; // idb
-extern char aIbM4dA[]; // idb
-extern char aIbM3dA[]; // idb
-extern char aIbM2dA[]; // idb
-extern char aIbM1dA[]; // idb
-extern char aIbSelecA[]; // idb
-extern char aIbNpcrdA[]; // idb
-extern char aIbNpcldA[]; // idb
-extern char aIbInitrA[]; // idb
-extern char aIbInityA[]; // idb
-extern char aIbInitgA[]; // idb
-extern char aIbCompA[]; // idb
-extern char aIbAutmaskA[]; // idb
-extern char aIbMbA[]; // idb
-extern char aIbFootA_pcx[]; // idb
-extern char aIbLA_pcx[11]; // weak
-extern char aIbTA_pcx[11]; // weak
-extern char aIbBA_pcx[11]; // weak
-extern char aIbRA_pcx[11]; // weak
-extern char aEndcapC[]; // idb
-extern char aEdge_topC[]; // idb
-extern char aEdge_rtC[]; // idb
-extern char aEdge_lfC[]; // idb
-extern char aEdge_btmC[]; // idb
-extern char aCornr_urC[]; // idb
-extern char aCornr_ulC[]; // idb
-extern char aCornr_lrC[]; // idb
-extern char aCornr_llC[]; // idb
-extern char aParchment[]; // idb
-extern char pContainer[]; // idb
-extern char aIbBC_pcx_0[]; // idb
-extern char aFr_inven[]; // idb
-extern char aEvtnpcC[]; // idb
-extern char aIsg04C[]; // idb
-extern char aIsg03C[]; // idb
-extern char aIsg02C[]; // idb
-extern char aIsg01C[]; // idb
-extern char aIbBcuC[]; // idb
-extern char aIbM4dC[]; // idb
-extern char aIbM3dC[]; // idb
-extern char aIbM2dC[]; // idb
-extern char aIbM1dC[]; // idb
-extern char aIbSelecC[]; // idb
-extern char aIbAutinC[]; // idb
-extern char aIbAutoutC[]; // idb
-extern char aIbNpcrdC[]; // idb
-extern char aIbNpcldC[]; // idb
-extern char aIbInitrC[]; // idb
-extern char aIbInityC[]; // idb
-extern char aIbInitgC[]; // idb
-extern char aIbCompC[]; // idb
-extern char aIbAutmaskC[]; // idb
-extern char aIbMbC[]; // idb
-extern char aIbFootC_pcx[]; // idb
-extern char aIbLC_pcx[]; // idb
-extern char aIbTC_pcx[]; // idb
-extern char aIbBC_pcx[11]; // weak
-extern char aIbRC_pcx[]; // idb
-extern char a10i10iS[]; // idb
-extern char aSizeIII[]; // idb
-extern char aDwavailvirtual[]; // idb
-extern char aDwtotalvirtual[]; // idb
-extern char aDwavailpagefil[]; // idb
-extern char aDwtotalpagefil[]; // idb
-extern char aDwavailphysD[]; // idb
-extern char aDwtotalphysD[]; // idb
-extern char aDwmemoryloadD[]; // idb
-extern char aDwlengthD[]; // idb
 extern char Format[]; // idb
 extern char aMem03i_txt[]; // idb
 extern char aMemory[]; // idb
 extern char aIdSSizeI[16]; // idb
 extern __int16 word_4E3C66[]; // idb
-extern char aSpell96[]; // idb
-extern char aNothing[]; // idb
-extern char aS_22[5]; // weak
-extern char aDGold[]; // idb
-extern char aSAndDGold[]; // idb
-extern char aD05_blv[]; // idb
-extern char aSpell11[]; // idb
-extern char aAframe1[]; // idb
-extern char aTurnstart[]; // idb
-extern char aTurnhour[]; // idb
-extern char aTurnstop[]; // idb
-extern char aTurn4[]; // idb
-extern char aTurn3[]; // idb
-extern char aTurn2[]; // idb
-extern char aTurn1[]; // idb
-extern char aTurn0[]; // idb
 extern int dword_4E455C; // weak
 extern int dword_4E4560[6];
 extern int dword_4E4578[6];
@@ -1937,81 +1678,6 @@
 extern short word_4EE150[];
 extern char aDD[]; // idb
 extern char off_4EE75C[]; // idb
-extern char aFacemask[]; // idb
-extern char aDead_0[]; // idb
-extern char aEradcate[]; // idb
-extern char aS02d[]; // idb
-extern char aUnableToSaveDp[]; // idb
-extern char aDataDpft_bin[]; // idb
-extern char aPlayerframet_1[]; // idb
-extern char aPlayerframet_0[]; // idb
-extern char aPlayerframetab[]; // idb
-extern char aUnableToSaveDi[]; // idb
-extern char aDataDift_bin[]; // idb
-extern char aIFrames[]; // idb
-extern char aIconframetab_0[]; // idb
-extern char aIconframetable[]; // idb
-extern char aInvalidStrin_1[22]; // weak
-extern char a03uS[]; // idb
-extern char aS03dD[]; // idb
-extern char aCchar_fnt[]; // idb
-extern char aArrowrD[]; // idb
-extern char aArrowlD[]; // idb
-extern char aPresleft[]; // idb
-extern char aPresrigh[]; // idb
-extern char aButtplus[]; // idb
-extern char aButtminu[]; // idb
-extern char aS01[]; // idb
-extern char aMakesky[]; // idb
-extern char aMaketop[]; // idb
-extern char aIc_sorc[]; // idb
-extern char aIc_druid[]; // idb
-extern char aIc_cler[]; // idb
-extern char aIc_ranger[]; // idb
-extern char aIc_arch[]; // idb
-extern char aIc_palad[]; // idb
-extern char aIc_monk[]; // idb
-extern char aIc_thief[]; // idb
-extern char aIc_knight[]; // idb
-extern char aScrollermap[]; // idb
-extern char aCredits_txt[]; // idb
-extern char aMm6title_pcx[13]; // weak
-extern char aQuick_fnt[]; // idb
-extern char aL_map[]; // idb
-extern char aL_bsp[]; // idb
-extern char aL_d[]; // idb
-extern char aL_l[]; // idb
-extern char aL_r[]; // idb
-extern char aL_fx[]; // idb
-extern char aL_f[]; // idb
-extern char aL_v[]; // idb
-extern char aD29_dlv[]; // idb
-extern char a_dlv[]; // idb
-extern char aEWorkMsdevM_20[]; // idb
-extern char a_blv[]; // idb
-extern char aL_ddata[]; // idb
-extern char aL_rldata[]; // idb
-extern char aL_rdata[]; // idb
-extern char aL_fdata[]; // idb
-extern char aHwsplat04[]; // idb
-extern char aErrorFailedT_0[]; // idb
-extern char aEWorkMsdevM_21[]; // idb
-extern char aReferenceRaste[]; // idb
-extern char aRgbEmulation[]; // idb
-extern char aInitFailedTo_7[]; // idb
-extern char aInitFailedTo_6[]; // idb
-extern char aInitFailedToAt[]; // idb
-extern char aInitFailedTo_5[]; // idb
-extern char aInitFailedToGe[37]; // weak
-extern char aInitFailedTo_4[39]; // weak
-extern char aInitFailedTo_3[36]; // weak
-extern char aInitFailedToEn[46]; // weak
-extern char aInitFailedTo_2[34]; // weak
-extern char aInitFailedTo_1[38]; // weak
-extern char aInitDesktopIsn[]; // idb
-extern char aInitFailedToSe[]; // idb
-extern char aInitFailedTo_0[]; // idb
-extern char aInitFailedToCr[]; // idb
 extern int dword_4EED78; // weak
 extern _UNKNOWN unk_4EED80; // weak
 extern int dword_4EFA80; // weak
@@ -2564,7 +2230,6 @@
 extern int dword_69B010[64];
 extern int dword_69B138; // weak
 extern char byte_69BD41_unused; // weak
-extern std::string stru_69BD44; // idb
 extern struct SavegameHeader *pSavegameHeader;
 extern unsigned int uTextureID_x_u;
 extern unsigned int uTextureID_LS_saveU;
@@ -2679,7 +2344,6 @@
 extern int uTextureID_720980; // weak
 extern int _720984_unused; // weak
 extern char _72098C_unused; // weak
-extern std::string std__string_720990; // idb
 extern __int16 word_7209A0_intercepts_ys_plus_ys[104];
 extern __int16 word_720A70_intercepts_xs_plus_xs[104];
 extern __int16 word_720B40_intercepts_zs[104];
@@ -2806,7 +2470,6 @@
 extern Vec3_float_ stru_AE4F7C; // idb
 extern int dword_AE4F88; // weak
 extern char byte_AE5B91; // weak
-extern std::string std__string_AE5B94; // idb
 extern int dword_F1B430[32]; // weak
 extern int dword_F8B144; // idb
 extern char byte_F8B148[16];
@@ -2885,8 +2548,8 @@
 bool __fastcall sub_4075DB(int a1, int a2, int a3, struct BLVFace *a4);
 bool __fastcall sub_4077F1(int a1, int a2, int a3, struct ODMFace *a4, struct BSPVertexBuffer *a5);
 bool __fastcall sub_407A1C(int x, int z, int y, struct Vec3_int_ v); // idb
-char __cdecl UpdateActors();
-char *__cdecl UpdateLayingItems();
+char UpdateActors();
+void UpdateLayingItems();
 int __fastcall sub_4088E9(int a1, int a2, int a3, int a4, int a5, int a6);
 unsigned int __thiscall SearchAliveActors(unsigned int *pTotalActors);
 unsigned int __fastcall SearchActorByMonsterID(unsigned int *pTotalActors, int uMonsterID);
@@ -3110,20 +2773,20 @@
 int /*__usercall*/ sr_sub_4D6FB0/*<eax>*/(struct stru315 *a1/*<ebp>*/);
 int /*__usercall*/ sr_sub_4D705A/*<eax>*/(struct stru315 *a1/*<ebp>*/);
 void __cdecl MessWithBillboards_BLV();
-signed int __fastcall sub_43F55F(struct RenderBillboard *a1, signed int a2);
-signed int __fastcall sub_43F5C8(signed int a1, int a2, float a3, float a4, float a5);
-int __cdecl PrepareWallsRenderList_BLV();
+int __fastcall _43F55F_get_billboard_light_level(struct RenderBillboard *a1, int uBaseLightLevel);
+int __fastcall _43F5C8_get_point_light_level_with_respect_to_lights(unsigned int uBaseLightLevel, int uSectorID, float x, float y, float z);
+void PrepareWallsRenderList_BLV();
 void __fastcall PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID);
-unsigned int __cdecl PrepareActorRenderList_BLV();
-void __cdecl PrepareItemsRenderList_BLV();
+void PrepareActorRenderList_BLV();
+void PrepareItemsRenderList_BLV();
 void __fastcall sub_440639(int a1);
 void __fastcall sub_4406BC(int a1, unsigned int uFirstNode); // idb
 void __fastcall sub_440BED(struct IndoorLocation_drawstru *_this);
-bool __cdecl sub_44100D();
-void __cdecl GameUI_DrawTorchlightAndWizardEye();
-void __cdecl GameUI_DrawCharacterSelectionFrame();
-void __cdecl Load_isn_spells_21_27();
-void __cdecl GameUI_DrawPartySpells();
+bool sub_44100D();
+void GameUI_DrawTorchlightAndWizardEye();
+void GameUI_DrawCharacterSelectionFrame();
+void Load_isn_spells_21_27();
+void GameUI_DrawPartySpells();
 __int16 __fastcall sub_441A4E(int a1);
 void __fastcall GameUI_DrawMinimap(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW, unsigned int uZoom, unsigned int flags);
 int __fastcall DrawSpellbook_Map_sub(unsigned int x, unsigned int y, unsigned int a4, int a5, int _48074); // idb
@@ -3212,9 +2875,6 @@
 int __fastcall ParseMissleAttackType(const char *Str1);
 unsigned int __fastcall SkillToMastery(unsigned __int16 a1);
 unsigned int __fastcall GetSpellColor(signed int a1);
-int __thiscall sub_45BAA5(int _this);
-std::string *__fastcall sub_45BAB6(int a1);
-// void __cdecl crt_45BAE9(); idb
 void *__thiscall unknown_vdtor_6(void *_this, bool a2);
 unsigned __int16 *__fastcall MakeScreenshot(signed int width, signed int height);
 void __thiscall SaveScreenshot(const char *pFilename);
@@ -3281,10 +2941,7 @@
 int __fastcall sub_46A7C8(int a1, int a2, signed int a3);
 int __fastcall sub_46A89E(int a1, int a2, signed int a3);
 int __cdecl sub_46A99B();
-// int __thiscall crt_construct_46AC48_ptr_720990(int this);
-std::string *__fastcall crt_intit_global_46AC59(int a1);
 void *__thiscall unknown_libname_8(void *_this, char a2);
-// void __cdecl crt_init_globals_46BD9F();
 unsigned int __cdecl GetGravityStrength();
 void __cdecl sub_46BDC0_UpdateUserInput_and_MapSpecificStuff();
 void __cdecl BLV_UpdateUserInputAndOther();
@@ -3411,8 +3068,7 @@
 bool __cdecl AreRenderSurfacesOk();
 int __fastcall sub_4A19D8(unsigned int, unsigned int); // weak
 void __cdecl DoRenderBillboards_D3D();
-void __fastcall SetBillboardBlendOptions(signed int a1);
-int __fastcall sub_4A46E6(unsigned int x, signed int y, signed int a3, int a4, unsigned int a5);
+int __fastcall sr_4A46E6_draw_particle_segment(unsigned int x, signed int y, signed int z, int a4, unsigned int lightColor);
 void __cdecl Present_ColorKey();
 void __cdecl Present_NoColorKey();
 int __thiscall sub_4A7063(unsigned int uDiffuse, float a2); // idb
--- a/stru346.h	Tue Oct 23 17:33:33 2012 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-#pragma once
-
-
-/*  386 */
-#pragma pack(push, 1)
-struct stru346
-{
-  int field_0;
-  int field_4;
-  int field_8;
-  int field_C;
-  int field_10;
-  int field_14;
-  int field_18;
-  int field_1C;
-  int field_20;
-  int field_24;
-  int field_28;
-  int field_2C;
-  int field_30;
-  int field_34;
-  int field_38;
-  int field_3C;
-  int field_40;
-  int field_44;
-  int uParentBillboardID;
-};
-#pragma pack(pop)
-
--- a/stru6.cpp	Tue Oct 23 17:33:33 2012 +0600
+++ b/stru6.cpp	Tue Oct 23 17:34:20 2012 +0600
@@ -88,92 +88,61 @@
 {
   int v8; // eax@1
 
-  v8 = this->uNumProjectiles;
+  v8 = uNumProjectiles;
   if ( v8 != 32 )
   {
-    this->pProjectiles[v8].srcX = srcX;
-    *((float *)&this->array_0[0].uSpellAnimLength + 7 * (this->uNumProjectiles + 21)) = srcY;
-    this->pProjectiles[this->uNumProjectiles].srcZ = srcZ;
-    this->pProjectiles[this->uNumProjectiles].dstX = dstX;
-    this->pProjectiles[this->uNumProjectiles].dstY = dstY;
-    this->pProjectiles[this->uNumProjectiles].dstZ = dstZ;
-    this->pProjectiles[this->uNumProjectiles++].uTextureID = uTextureID;
+    pProjectiles[v8].srcX = srcX;
+    *((float *)&this->array_0[0].uSpellAnimLength + 7 * (uNumProjectiles + 21)) = srcY;
+    pProjectiles[uNumProjectiles].srcZ = srcZ;
+    pProjectiles[uNumProjectiles].dstX = dstX;
+    pProjectiles[uNumProjectiles].dstY = dstY;
+    pProjectiles[uNumProjectiles].dstZ = dstZ;
+    pProjectiles[uNumProjectiles++].uTextureID = uTextureID;
   }
 }
 
 //----- (004A7298) --------------------------------------------------------
-int stru6::DrawProjectiles()
+void stru6::DrawProjectiles()
 {
-  stru6 *v1; // ebx@1
-  char *v2; // eax@1
-  signed int v3; // ecx@1
-  unsigned __int8 v4; // zf@3
-  unsigned __int8 v5; // sf@3
-  IndoorCameraD3D *v6; // edi@3
-  int result; // eax@3
-  int v8; // esi@4
-  int v9; // eax@5
   float v10; // ST1C_4@8
   float v11; // ST0C_4@8
   IDirect3DTexture2 *v12; // [sp+20h] [bp-78h]@6
-  RenderVertexSoft v13[2]; // [sp+30h] [bp-68h]@1
-  float v14; // [sp+90h] [bp-8h]@3
-  int v15; // [sp+94h] [bp-4h]@3
-
-  v1 = this;
-  v2 = (char *)&v13[0].flt_2C;
-  v3 = 2;
-  do
-  {
-    *(float *)v2 = 0.0;
-    v2 += 48;
-    --v3;
-  }
-  while ( v3 );
-  v15 = 0;
-  v4 = v1->uNumProjectiles == 0;
-  v5 = v1->uNumProjectiles < 0;
-  v6 = pGame->pIndoorCameraD3D;
-  result = LODWORD(v6->flt_D0);
-  v14 = v6->flt_D0;
-  if ( !(v5 | v4) )
+  RenderVertexSoft v[2]; // [sp+30h] [bp-68h]@1
+  
+  for (uint i = 0; i < uNumProjectiles; ++i)
   {
-    v8 = (int)&v1->pProjectiles[0].srcY;
-    do
-    {
-      v13[0].vWorldPosition.x = *(float *)(v8 - 4);
-      v13[0].vWorldPosition.y = *(float *)v8;
-      v13[0].vWorldPosition.z = *(float *)(v8 + 4);
-      v13[1].vWorldPosition.x = *(float *)(v8 + 8);
-      v13[1].vWorldPosition.y = *(float *)(v8 + 12);
-      v13[1].vWorldPosition.z = *(float *)(v8 + 16);
-      v6->ViewTransform(v13, 2u);
-      sr_42620A(v13);
-      v6->_436BB7_project_and_stuff(v13, 2u, 0);
-      v9 = *(int *)(v8 + 20);
-      if ( v9 == -1 )
-        v12 = 0;
-      else
-        v12 = pBitmaps_LOD->pHardwareTextures[v9];
-      v10 = v14 / v13[1].vWorldViewPosition.x * 20.0;
-      v11 = v14 / v13[0].vWorldViewPosition.x * 20.0;
-      pRenderer->DrawProjectile(
-        v13[0].vWorldViewProjX,
-        v13[0].vWorldViewProjY,
-        v13[0].vWorldViewPosition.x,
-        v11,
-        v13[1].vWorldViewProjX,
-        v13[1].vWorldViewProjY,
-        v13[1].vWorldViewPosition.x,
-        v10,
-        v12);
-      ++v15;
-      v8 += 28;
-      result = v15;
-    }
-    while ( v15 < v1->uNumProjectiles );
-  }
-  return result;
+    auto p = pProjectiles + i;
+
+    v[0].vWorldPosition.x = p->srcX;
+    v[0].vWorldPosition.y = p->srcY;
+    v[0].vWorldPosition.z = p->srcZ;
+    v[1].vWorldPosition.x = p->dstX;
+    v[1].vWorldPosition.y = p->dstY;
+    v[1].vWorldPosition.z = p->dstZ;
+    pGame->pIndoorCameraD3D->ViewTransform(v, 2);
+
+    sr_42620A(v);
+
+    pGame->pIndoorCameraD3D->_436BB7_project_and_stuff(v, 2, 0);
+
+    if (p->uTextureID != -1)
+      v12 = pBitmaps_LOD->pHardwareTextures[p->uTextureID];
+    else
+      v12 = 0;
+
+    v10 = pGame->pIndoorCameraD3D->flt_D0 / v[1].vWorldViewPosition.x * 20.0;
+    v11 = pGame->pIndoorCameraD3D->flt_D0 / v[0].vWorldViewPosition.x * 20.0;
+    pRenderer->DrawProjectile(
+        v[0].vWorldViewProjX,
+        v[0].vWorldViewProjY,
+        v[0].vWorldViewPosition.x,
+         v11,
+        v[1].vWorldViewProjX,
+        v[1].vWorldViewProjY,
+        v[1].vWorldViewPosition.x,
+         v10,
+         v12);
+   }
 }
 
 //----- (004A73AA) --------------------------------------------------------
@@ -207,7 +176,7 @@
     local_0.flt_10 = 0.0;
     local_0.flt_14 = 0.0;
     local_0.flt_18 = 0.0;
-    local_0.field_20 = (rand() & 0x40) + 96;
+    local_0.timeToLive = (rand() & 0x40) + 96;
     local_0.uTextureID = uTextureID;
     local_0.flt_28 = 1.0;
     pGame->pParticleEngine->AddParticle(&local_0);
@@ -239,7 +208,7 @@
     local_0.flt_14 = 0.0;
     local_0.flt_18 = 0.0;
     local_0.flt_28 = 1.0;
-    local_0.field_20 = (rand() & 0x7F) + 128;
+    local_0.timeToLive = (rand() & 0x7F) + 128;
     local_0.uTextureID = uTextureID;
     pGame->pParticleEngine->AddParticle(&local_0);
     local_0.x = (double)a2->vPosition.x - 4.0;
@@ -262,7 +231,7 @@
   local_0.uDiffuse = uDiffuse;
   local_0.z = v4;
   v5 = 10;
-  local_0.field_20 = (rand() & 0x7F) + 128;
+  local_0.timeToLive = (rand() & 0x7F) + 128;
   local_0.uTextureID = uTextureID;
   local_0.flt_28 = 1.0;
   do
@@ -312,7 +281,7 @@
   local_0.x = v5;
   local_0.y = (double)a2->vPosition.y;
   local_0.z = (double)a2->vPosition.z;
-  local_0.field_20 = (rand() & 0x7F) + 128;
+  local_0.timeToLive = (rand() & 0x7F) + 128;
   local_0.uTextureID = pBitmaps_LOD->LoadTexture("effpar01", TEXTURE_DEFAULT);
   i = 10;
   local_0.flt_28 = 1.0;
@@ -388,7 +357,7 @@
   v4 = (double)a1->vPosition.y;
   local_0.bFree = 2048;
   local_0.uDiffuse = 0x7F7F7Fu;
-  local_0.field_20 = 1;
+  local_0.timeToLive = 1;
   local_0.y = v4;
   local_0.z = (double)a1->vPosition.z;
   local_0.flt_10 = 0.0;
@@ -422,7 +391,7 @@
   v5 = rand();
   v6 = 10;
   Dst.flt_28 = 1.0;
-  Dst.field_20 = (v5 & 0x7F) + 128;
+  Dst.timeToLive = (v5 & 0x7F) + 128;
   do
   {
     Dst.flt_10 = (double)(rand() & 0x1FF) - 255.0;
@@ -475,7 +444,7 @@
   v6 = rand();
   local_0.flt_28 = 1.0;
   v7 = 0.0 * a4;
-  local_0.field_20 = (v6 & 0x7F) + 128;
+  local_0.timeToLive = (v6 & 0x7F) + 128;
   local_0.uTextureID = uTextureID;
   a1a = v7;
   local_0.flt_10 = v7;
@@ -557,7 +526,7 @@
     local_0.flt_18 = 0.0;
     v10 = rand();
     LODWORD(local_0.flt_28) = 0x40400000u;
-    local_0.field_20 = (v10 & 0x3F) + 64;
+    local_0.timeToLive = (v10 & 0x3F) + 64;
     local_0.uTextureID = pSpriteFrameTable->GetFrame(v5->uSpriteID, v3->uSpriteFrameID)->pHwSpriteIDs[0];
     pGame->pParticleEngine->AddParticle(&local_0);
     v11 = (double)v3->vPosition.x;
@@ -565,7 +534,7 @@
     local_0.x = v11;
     local_0.y = (double)v3->vPosition.y;
     local_0.z = (double)v3->vPosition.z;
-    local_0.field_20 = (rand() & 0x3F) + 64;
+    local_0.timeToLive = (rand() & 0x3F) + 64;
     pGame->pParticleEngine->AddParticle(&local_0);
     v2->array_0[v3->field_54 & 0x1F].flt_4 = (double)v3->vPosition.x;
     v2->array_0[v3->field_54 & 0x1F].flt_8 = (double)v3->vPosition.y;
@@ -587,7 +556,7 @@
     local_0.flt_10 = 0.0;
     local_0.flt_14 = 0.0;
     local_0.flt_18 = 0.0;
-    local_0.field_20 = (rand() & 0x3F) + 64;
+    local_0.timeToLive = (rand() & 0x3F) + 64;
     local_0.uTextureID = pSpriteFrameTable->GetFrame(v5->uSpriteID, a2->uSpriteFrameID)->pHwSpriteIDs[0];
     pGame->pParticleEngine->AddParticle(&local_0);
   }
@@ -637,7 +606,7 @@
 
   memset(&Dst, 0, 0x68u);
   Dst.bFree = 1036;
-  Dst.field_20 = (rand() & 0x7F) + 128;
+  Dst.timeToLive = (rand() & 0x7F) + 128;
   v3 = pActor;
   Dst.uTextureID = pBitmaps_LOD->LoadTexture("effpar02", TEXTURE_DEFAULT);
   pActora = 50;
@@ -687,7 +656,7 @@
   v5 = rand();
   local_0.flt_28 = 1.0;
   v6 = 8;
-  local_0.field_20 = (v5 & 0x7F) + 128;
+  local_0.timeToLive = (v5 & 0x7F) + 128;
   v7 = v4->uTextureID_effpar1;
   v12 = (double)x;
   local_0.uTextureID = v7;
@@ -752,7 +721,7 @@
   memset(&local_0, 0, 0x68u);
   local_0.bFree = 1029;
   local_0.uDiffuse = 0x7E7E7Eu;
-  local_0.field_20 = (rand() & 0x7F) + 128;
+  local_0.timeToLive = (rand() & 0x7F) + 128;
   local_0.uTextureID = v2->uTextureID_effpar1;
   v3 = 8;
   local_0.flt_28 = 1.0;
@@ -1489,11 +1458,8 @@
 }
 
 //----- (004A8C27) --------------------------------------------------------
-HRESULT stru6::RenderSpecialEffects()
+void stru6::RenderSpecialEffects()
 {
-  stru6 *v1; // ebx@1
-  int *v2; // edi@1
-  HRESULT result; // eax@3
   double v4; // st7@4
   double v5; // st6@4
   double v6; // st7@4
@@ -1518,41 +1484,36 @@
   SpriteFrame *v70; // [sp+E4h] [bp-8h]@8
   unsigned int v26; // [sp+E8h] [bp-4h]@3
 
-  //by the time we first get in this function, dword_0005D4  is still not initialized in the original exe
-  //maybe the following code in never executed at all
-
-  v1 = this;
-  v2 = &this->uNumProjectiles;
-  if ( this->uNumProjectiles )
+  if (uNumProjectiles)
   {
     DrawProjectiles();
-    *v2 = 0;
+    uNumProjectiles = 0;
   }
-  result = v1->uFadeTime;
-  v1->field_204 = 0;
-  v26 = result;
-  if ( result > 0 )
+
+  field_204 = 0;
+  v26 = uFadeTime;
+  if ( v26 > 0 )
   {
-    v4 = (double)(signed int)v26 / (double)v1->uFadeTime2;
+    v4 = (double)(signed int)v26 / (double)uFadeTime2;
     v5 = 1.0 - v4 * v4;
     v6 = v5;
     if ( v5 > 0.9 )
       v6 = 1.0 - (v5 - 0.9) * 10.0;
     v7 = v6;
-    pRenderer->_4A52F1(v1->uFadeColor, v7);
-    result = pEventTimer->uTimeElapsed;
-    v1->uFadeTime -= pEventTimer->uTimeElapsed;
+    pRenderer->_4A52F1(uFadeColor, v7);
+    uFadeTime -= pEventTimer->uTimeElapsed;
   }
-  if ( v1->uAnimLength > 0 )
+
+  if (uAnimLength > 0)
   {
     v8 = 8
        * pSpriteFrameTable->pSpriteSFrames[pSpriteFrameTable->FastFindSprite("spell84")].uAnimLength
-       - v1->uAnimLength;
+       - uAnimLength;
     v9 = pSpriteFrameTable->FastFindSprite("spell84");
     v10 = pSpriteFrameTable->GetFrame(v9, v8);
     v11 = v10->pHwSpriteIDs[0];
     v70 = v10;
-    v1->uAnimLength -= pEventTimer->uTimeElapsed;
+    uAnimLength -= pEventTimer->uTimeElapsed;
     if ( pRenderer->pRenderD3D )
     {
       v12 = (double)(signed int)pViewport->uViewportX;
@@ -1615,15 +1576,15 @@
       pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, 0);
       pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true);
       pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, true);
-      result = pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, 2);
+      pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, 2);
     }
     else
     {
       vsr.pTarget = pRenderer->pTargetSurface;
       vsr.uParentBillboardID = -1;
       vsr.pTargetZ = pRenderer->pActiveZBuffer;
-      vsr.field_8 = (signed int)(pViewport->uViewportZ - pViewport->uViewportX) / 2;
-      vsr.field_C = pViewport->uViewportW;
+      vsr.uScreenSpaceX = (signed int)(pViewport->uViewportZ - pViewport->uViewportX) / 2;
+      vsr.uScreenSpaceY = pViewport->uViewportW;
       v24 = 16777216;
       LODWORD(v18) = 0;
       HIDWORD(v18) = (signed __int16)(LOWORD(pViewport->uViewportZ) - LOWORD(pViewport->uViewportX));
@@ -1638,15 +1599,13 @@
       vsr.uViewportX = pViewport->uViewportX;
       vsr.uViewportZ = pViewport->uViewportZ;
       vsr.uViewportY = pViewport->uViewportY;
-      result = pViewport->uViewportW;
-      vsr.field_28 = 0;
+      vsr.sZValue = 0;
       vsr.uViewportW = pViewport->uViewportW;
       vsr.uFlags = 0;
       if ( v11 >= 0 )
-        result = pSprites_LOD->pSpriteHeaders[v11]._4ACC38(&vsr, 1);
+        pSprites_LOD->pSpriteHeaders[v11]._4ACC38(&vsr, 1);
     }
   }
-  return result;
 }
 
 //----- (004A902A) --------------------------------------------------------
--- a/stru6.h	Tue Oct 23 17:33:33 2012 +0600
+++ b/stru6.h	Tue Oct 23 17:34:20 2012 +0600
@@ -117,7 +117,7 @@
   }
 
   void DoAddProjectile(float srcX, float srcY, float srcZ, float dstX, float dstY, float dstZ, unsigned int uTextureID);
-  int DrawProjectiles();
+  void DrawProjectiles();
   void _4A73AA_hanging_trace_particles___like_fire_strike_ice_blast_etc(struct LayingItem *a2, unsigned int uDiffuse, unsigned int uTextureID);
   void _4A75CC_single_spell_collision_particle(struct LayingItem *a1, unsigned int uDiffuse, unsigned int uTextureID);
   void _4A7688_fireball_collision_particle(struct LayingItem *a2);
@@ -136,7 +136,7 @@
   int SetPlayerBuffAnim(unsigned __int16 uSpellID, unsigned __int16 uPlayerID);
   void FadeScreen__like_Turn_Undead_and_mb_Armageddon(unsigned int uDiffuseColor, unsigned int uFadeTime);
   int _4A8BFC();
-  HRESULT RenderSpecialEffects();
+  void RenderSpecialEffects();
   void DrawPlayerBuffAnims();
   void LoadAnimations();