changeset 2324:b2e3ac05f2b3

Merge
author Grumpy7
date Thu, 27 Mar 2014 23:30:02 +0100
parents 983b8c995127 (current diff) a59892f99d31 (diff)
children 846e28e41fb4 c889e521af1f
files
diffstat 23 files changed, 3017 insertions(+), 1625 deletions(-) [+]
line wrap: on
line diff
--- a/Build/Visual Studio 2010/World of Might and Magic.vcxproj	Thu Mar 27 23:28:54 2014 +0100
+++ b/Build/Visual Studio 2010/World of Might and Magic.vcxproj	Thu Mar 27 23:30:02 2014 +0100
@@ -180,6 +180,7 @@
     <ClCompile Include="..\..\Log.cpp" />
     <ClCompile Include="..\..\LuaVM.cpp" />
     <ClCompile Include="..\..\MapInfo.cpp" />
+    <ClCompile Include="..\..\MediaPlayer.cpp" />
     <ClCompile Include="..\..\mm7text_ru.cpp" />
     <ClCompile Include="..\..\mm7_2.cpp" />
     <ClCompile Include="..\..\mm7_3.cpp" />
@@ -424,6 +425,7 @@
     <ClInclude Include="..\..\Log.h" />
     <ClInclude Include="..\..\LuaVM.h" />
     <ClInclude Include="..\..\MapInfo.h" />
+    <ClInclude Include="..\..\MediaPlayer.h" />
     <ClInclude Include="..\..\MM7.h" />
     <ClInclude Include="..\..\mm7_data.h" />
     <ClInclude Include="..\..\mm7_unsorted_subs.h" />
@@ -435,6 +437,7 @@
     <ClInclude Include="..\..\NPC.h" />
     <ClInclude Include="..\..\NZIArray.h" />
     <ClInclude Include="..\..\ObjectList.h" />
+    <ClInclude Include="..\..\OpenALSoundProvider.h" />
     <ClInclude Include="..\..\OSAPI.h" />
     <ClInclude Include="..\..\OSInfo.h" />
     <ClInclude Include="..\..\OSWindow.h" />
@@ -465,6 +468,7 @@
     <ClInclude Include="..\..\stru367.h" />
     <ClInclude Include="..\..\stru6.h" />
     <ClInclude Include="..\..\stru9.h" />
+    <ClInclude Include="..\..\stuff.h" />
     <ClInclude Include="..\..\texts.h" />
     <ClInclude Include="..\..\Texture.h" />
     <ClInclude Include="..\..\TileFrameTable.h" />
--- a/Build/Visual Studio 2010/World of Might and Magic.vcxproj.filters	Thu Mar 27 23:28:54 2014 +0100
+++ b/Build/Visual Studio 2010/World of Might and Magic.vcxproj.filters	Thu Mar 27 23:30:02 2014 +0100
@@ -524,6 +524,9 @@
       <Filter>lib\libpng</Filter>
     </ClInclude>
     <ClInclude Include="..\..\MMT.h" />
+    <ClInclude Include="..\..\MediaPlayer.h" />
+    <ClInclude Include="..\..\stuff.h" />
+    <ClInclude Include="..\..\OpenALSoundProvider.h" />
   </ItemGroup>
   <ItemGroup>
     <Filter Include="lib">
@@ -948,6 +951,7 @@
       <Filter>lib\libpng</Filter>
     </ClCompile>
     <ClCompile Include="..\..\MMT.cpp" />
+    <ClCompile Include="..\..\MediaPlayer.cpp" />
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="..\..\NewUI\Core\UIControlModule.swig">
--- a/Build/Visual Studio 2012/World of Might and Magic.vcxproj	Thu Mar 27 23:28:54 2014 +0100
+++ b/Build/Visual Studio 2012/World of Might and Magic.vcxproj	Thu Mar 27 23:30:02 2014 +0100
@@ -184,6 +184,7 @@
     <ClCompile Include="..\..\Log.cpp" />
     <ClCompile Include="..\..\LuaVM.cpp" />
     <ClCompile Include="..\..\MapInfo.cpp" />
+    <ClCompile Include="..\..\MediaPlayer.cpp" />
     <ClCompile Include="..\..\mm7text_ru.cpp" />
     <ClCompile Include="..\..\mm7_2.cpp" />
     <ClCompile Include="..\..\mm7_3.cpp" />
@@ -425,6 +426,7 @@
     <ClInclude Include="..\..\Log.h" />
     <ClInclude Include="..\..\LuaVM.h" />
     <ClInclude Include="..\..\MapInfo.h" />
+    <ClInclude Include="..\..\MediaPlayer.h" />
     <ClInclude Include="..\..\MM7.h" />
     <ClInclude Include="..\..\mm7_data.h" />
     <ClInclude Include="..\..\mm7_unsorted_subs.h" />
@@ -436,6 +438,7 @@
     <ClInclude Include="..\..\NPC.h" />
     <ClInclude Include="..\..\NZIArray.h" />
     <ClInclude Include="..\..\ObjectList.h" />
+    <ClInclude Include="..\..\OpenALSoundProvider.h" />
     <ClInclude Include="..\..\OSAPI.h" />
     <ClInclude Include="..\..\OSInfo.h" />
     <ClInclude Include="..\..\OSWindow.h" />
@@ -465,6 +468,7 @@
     <ClInclude Include="..\..\stru367.h" />
     <ClInclude Include="..\..\stru6.h" />
     <ClInclude Include="..\..\stru9.h" />
+    <ClInclude Include="..\..\stuff.h" />
     <ClInclude Include="..\..\TestClass.h" />
     <ClInclude Include="..\..\texts.h" />
     <ClInclude Include="..\..\Texture.h" />
--- a/Build/Visual Studio 2012/World of Might and Magic.vcxproj.filters	Thu Mar 27 23:28:54 2014 +0100
+++ b/Build/Visual Studio 2012/World of Might and Magic.vcxproj.filters	Thu Mar 27 23:30:02 2014 +0100
@@ -384,6 +384,7 @@
     <ClCompile Include="..\..\lib\libpng\pngwutil.c">
       <Filter>lib\libpng</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\MediaPlayer.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\Level\Decoration.h" />
@@ -907,6 +908,9 @@
     <ClInclude Include="..\..\lib\libpng\pngstruct.h">
       <Filter>lib\libpng</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\MediaPlayer.h" />
+    <ClInclude Include="..\..\OpenALSoundProvider.h" />
+    <ClInclude Include="..\..\stuff.h" />
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\Player.swig" />
--- a/DecalBuilder.cpp	Thu Mar 27 23:28:54 2014 +0100
+++ b/DecalBuilder.cpp	Thu Mar 27 23:30:02 2014 +0100
@@ -37,24 +37,18 @@
 }
 
 //----- (0043B6EF) --------------------------------------------------------
-void BloodsplatContainer::AddBloodsplat(float x, float y, float z, float radius, char r, char g, char b)
+void BloodsplatContainer::AddBloodsplat(float x, float y, float z, float radius, unsigned char r, unsigned char g, unsigned char b)
 {
-  int v8; // esi@1
-  int v9; // eax@3
-  Bloodsplat *v10; // eax@3
-
-  v8 = this->uNumBloodsplats;
+  int i = this->uNumBloodsplats;
   if ( this->uNumBloodsplats == 64 )
-    v8 = 0;
-  v9 = 5 * (v8 + 1);
-  v10 = &this->std__vector_pBloodsplats[8 * v9 / 40];
-  v10->x = x;
-  v10->y = y;
-  v10->z = z;
-  v10->radius = radius;
-  v10->r = r;
-  v10->g = g;
-  v10->b = b;
+    i = 0;
+  this->std__vector_pBloodsplats[i].x = x;
+  this->std__vector_pBloodsplats[i].y = y;
+  this->std__vector_pBloodsplats[i].z = z;
+  this->std__vector_pBloodsplats[i].radius = radius;
+  this->std__vector_pBloodsplats[i].r = r;
+  this->std__vector_pBloodsplats[i].g = g;
+  this->std__vector_pBloodsplats[i].b = b;
   this->std__vector_pBloodsplats_size = min(this->std__vector_pBloodsplats_size + 1, 64);
 }
 
@@ -99,44 +93,44 @@
 //----- (0049B540) --------------------------------------------------------
 char DecalBuilder::ApplyDecals(int light_level, char a3, stru154 *a4, int a5, RenderVertexSoft *a6, IndoorCameraD3D_Vec4 *a7, char a8, unsigned int uSectorID)
 {
-  char *v9; // eax@3
-  signed int v10; // ecx@3
-  RenderVertexSoft *v11; // eax@10
-  unsigned int v12; // edx@10
-  RenderVertexSoft *v13; // esi@11
-  RenderVertexSoft *v14; // edi@11
-  char v15; // zf@11
+  //char *v9; // eax@3
+  //signed int v10; // ecx@3
+  //RenderVertexSoft *v11; // eax@10
+  //unsigned int v12; // edx@10
+  //RenderVertexSoft *v13; // esi@11
+  //RenderVertexSoft *v14; // edi@11
+  //char v15; // zf@11
   stru154 *v16; // esi@12
-  double v18; // st7@17
-  double v19; // st6@17
-  float v20; // eax@17
-  Bloodsplat *v21; // esi@21
-  int v22; // eax@21
-  int v23; // ecx@21
-  double v24; // st7@21
+  //double v18; // st7@17
+  //double v19; // st6@17
+  //float v20; // eax@17
+  //Bloodsplat *v21; // esi@21
+  //int v22; // eax@21
+  //int v23; // ecx@21
+  //double v24; // st7@21
   int v25; // ebx@21
-  double v26; // st7@21
-  int v27; // edi@21
-  double v28; // st7@21
-  float v29; // ST10_4@21
+  //double v26; // st7@21
+  //int v27; // edi@21
+  //double v28; // st7@21
+  //float v29; // ST10_4@21
   int v30; // ST08_4@21
   //DecalBuilder *v31; // esi@21
-  int v32; // [sp+4h] [bp-44h]@18
-  float v33; // [sp+8h] [bp-40h]@21
-  stru314 *v34; // [sp+Ch] [bp-3Ch]@21
-  float v35; // [sp+10h] [bp-38h]@21
-  float v36; // [sp+14h] [bp-34h]@17
-  int v37; // [sp+18h] [bp-30h]@17
-  int a5a; // [sp+28h] [bp-20h]@21
-  int v39; // [sp+2Ch] [bp-1Ch]@21
-  int v40; // [sp+30h] [bp-18h]@21
-  int v41; // [sp+34h] [bp-14h]@22
-  int v42; // [sp+38h] [bp-10h]@21
+  //int v32; // [sp+4h] [bp-44h]@18
+  //float v33; // [sp+8h] [bp-40h]@21
+  //stru314 *v34; // [sp+Ch] [bp-3Ch]@21
+  //float v35; // [sp+10h] [bp-38h]@21
+  //float v36; // [sp+14h] [bp-34h]@17
+  //int v37; // [sp+18h] [bp-30h]@17
+  //int a5a; // [sp+28h] [bp-20h]@21
+  //int v39; // [sp+2Ch] [bp-1Ch]@21
+  //int v40; // [sp+30h] [bp-18h]@21
+  //int v41; // [sp+34h] [bp-14h]@22
+  //int v42; // [sp+38h] [bp-10h]@21
   int v43; // [sp+3Ch] [bp-Ch]@21
   //DecalBuilder *thisa; // [sp+40h] [bp-8h]@1
   //RenderVertexSoft *a11; // [sp+44h] [bp-4h]@8
   int a6a;
-  int *a6b;
+  //int *a6b;
 
 
 //  __debugbreak();
@@ -184,61 +178,63 @@
     }
   }
   else
-  {
     v16 = a4;
-  }
-  v18 = v16->face_plane.vNormal.z;
-  v19 = v16->face_plane.vNormal.y;
-  v20 = v16->face_plane.vNormal.x;
-  v37 = (int)&static_AE4F60.field_1C;
-  static_AE4F60.field_4.y = v19;
-  static_AE4F60.field_4.x = v20;
-  LODWORD(v36) = (DWORD)&static_AE4F60.field_10;
-  static_AE4F60.field_4.z = v18;
+  //v18 = v16->face_plane.vNormal.z;
+  //v19 = v16->face_plane.vNormal.y;
+  //v20 = v16->face_plane.vNormal.x;
+  //v37 = (int)&static_AE4F60.field_1C;
+  static_AE4F60.field_4.y = v16->face_plane.vNormal.y;
+  static_AE4F60.field_4.x = v16->face_plane.vNormal.x;
+  //LODWORD(v36) = (DWORD)&static_AE4F60.field_10;
+  static_AE4F60.field_4.z = v16->face_plane.vNormal.z;
   static_AE4F60.dist = v16->face_plane.dist;
-  if ( !pGame->pIndoorCameraD3D->GetFacetOrientation(v16->polygonType, &static_AE4F60.field_4, &static_AE4F60.field_10, &static_AE4F60.field_1C) )
-  {
+  if ( !pGame->pIndoorCameraD3D->GetFacetOrientation(v16->polygonType, &static_AE4F60.field_4,
+     &static_AE4F60.field_10, &static_AE4F60.field_1C) )
       MessageBoxW(nullptr, L"Error: Failed to get the facet orientation", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:101", 0);
-  }
-  int _a7 = 0;
+  
   if ( this->uNumDecals > 0 )
   {
-    a6b = this->std__vector_30B00C;
-    do
+    //a6b = this->std__vector_30B00C;
+    for ( int i = 0; i < this->uNumDecals; ++i )
     {
-      v21 = &pBloodsplatContainer->std__vector_pBloodsplats[*a6b];
-      v22 = _43F5C8_get_point_light_level_with_respect_to_lights(light_level, uSectorID, v21->x, v21->y, v21->z);
-      v23 = v21->b;
-      v24 = v21->x;
-      v42 = v22;
-      BYTE3(v22) = 0;
-      *(short *)((char *)&v22 + 1) = v21->r;
-      LOBYTE(v22) = v21->g;
-      v43 = v23 | (v22 << 8);
-      v25 = (signed __int64)v24;
-      v26 = v21->z;
-      v27 = (signed __int64)v21->y;
-      v37 = a8;
-      v40 = (signed __int64)v26;
-      v28 = v21->dot_dist;
+      //v21 = &pBloodsplatContainer->std__vector_pBloodsplats[*a6b];
+      int point_light_level = _43F5C8_get_point_light_level_with_respect_to_lights(light_level, uSectorID,
+                                  pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].x,
+                                  pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].y,
+                                  pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].z);
+      //v23 = pBloodsplatContainer->std__vector_pBloodsplats[*a6b].b;
+      //v24 = pBloodsplatContainer->std__vector_pBloodsplats[*a6b].x;
+      //v42 = v22;
+      //BYTE3(v22) = 0;
+      //*(short *)((char *)&v22 + 1) = pBloodsplatContainer->std__vector_pBloodsplats[*a6b].r;
+      //LOBYTE(v22) = pBloodsplatContainer->std__vector_pBloodsplats[*a6b].g;
+      v43 = pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].b |
+           ((unsigned int)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].g << 8) |
+           ((unsigned int)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].r << 16);
+      v25 = (signed __int64)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].x;
+      //v27 = (signed __int64)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].y;
+      //v37 = a8;
+      //v40 = (signed __int64)pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].z;
+      //v28 = pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].dot_dist;
       //LODWORD(v36) = (uint32)a6;
-      a5a = v25;
-      v39 = v27;
-      LODWORD(v35) = a5;
-      v34 = &static_AE4F60;
-      v33 = v28;
-      v32 = v23 | (v22 << 8);
-      v29 = v21->radius;
+      //a5a = v25;
+      //v39 = v27;
+      //LODWORD(v35) = a5;
+      //v34 = &static_AE4F60;
+      //v33 = v28;
+      //v32 = pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].b | (v22 << 8);
+      //v29 = pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].radius;
       //v30 = (int)v21;
       //v31 = thisa;
-      if ( !this->_49B790_build_decal_geometry(v42, a3, (Bloodsplat *)v21, (int)&a5a, SLODWORD(v29), v43, v33, &static_AE4F60, a5, a6, a8) )
-      {
-      MessageBoxW(nullptr, L"Error: Failed to build decal geometry", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:114", 0);
-      }
-      ++_a7;
-      ++a6b;
+      if ( !this->_49B790_build_decal_geometry(point_light_level, a3,
+		  &pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]],
+		  (int)&v25,
+		  pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].radius,
+		  v43,
+		  pBloodsplatContainer->std__vector_pBloodsplats[this->std__vector_30B00C[i]].dot_dist,
+		  &static_AE4F60, a5, a6, a8) )
+        MessageBoxW(nullptr, L"Error: Failed to build decal geometry", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\PolyProjector.cpp:114", 0);
     }
-    while ( _a7 < this->uNumDecals );
   }
   return 1;
 }
@@ -296,16 +292,17 @@
   //v17 = a5;
   //v18 = a9;
   this->flt_30C030 = 1.0 - (a6 - this->field_30C02C) / a6;
-  v13->field_C08 = (signed __int64)((double)*(signed int *)a5 - a8 * a9->field_4.x);
-  v13->field_C0A = (signed __int64)((double)*(signed int *)(a5 + 4) - a8 * a9->field_4.y);
+  v13->field_C08 = (signed __int64)(a4->x - a8 * a9->field_4.x);
+  v13->field_C0A = (signed __int64)(a4->y - a8 * a9->field_4.y);
   //v19 = a6;
-  v13->field_C0C = (signed __int64)((double)*(signed int *)(a5 + 8) - a8 * a9->field_4.z);
+  v13->field_C0C = (signed __int64)(a4->z - a8 * a9->field_4.z);
   //v20 = a6 * this->flt_30C030;
   //a8a = v13->pVertices;
   this->field_30C034 = a6 * this->flt_30C030;
   this->field_30C010 = this->field_30C034 * a9->field_10.x;
   this->field_30C014 = this->field_30C034 * a9->field_10.y;
   this->field_30C018 = this->field_30C034 * a9->field_10.z;
+
   this->field_30C01C = this->field_30C034 * a9->field_1C.x;
   this->field_30C020 = this->field_30C034 * a9->field_1C.y;
   this->field_30C024 = this->field_30C034 * a9->field_1C.z;
--- a/DecalBuilder.h	Thu Mar 27 23:28:54 2014 +0100
+++ b/DecalBuilder.h	Thu Mar 27 23:30:02 2014 +0100
@@ -31,9 +31,9 @@
   float z;
   float radius;
   float dot_dist;
-  char r;
-  char g;
-  char b;
+  unsigned char r;
+  unsigned char g;
+  unsigned char b;
   char field_1B;
   int field_1C;
   unsigned long long field_20;
@@ -66,7 +66,7 @@
 
 
   void AddBloodsplat(float x, float y, float z, float r, float g, float b, float radius, int a8, int a9);
-  void AddBloodsplat(float x, float y, float z, float radius, char r, char g, char b);
+  void AddBloodsplat(float x, float y, float z, float radius, unsigned char r, unsigned char g, unsigned char b);
 
 
   //void ( ***vdestructor_ptr)(BloodsplatContainer *, bool);
--- a/Indoor.cpp	Thu Mar 27 23:28:54 2014 +0100
+++ b/Indoor.cpp	Thu Mar 27 23:30:02 2014 +0100
@@ -5507,16 +5507,16 @@
     for ( uint i = 1; i <= pFace->uNumVertices; ++i)
     {
       next_vertices_flag = PortalFace._view_transformed_z[i + 3] >= 0x80000; //524288;// 8.0
-      if ( current_vertices_flag ^ next_vertices_flag )//или текущая или следующая вершина за ближней границей
+      if ( current_vertices_flag ^ next_vertices_flag )//или текущая или следующая вершина за ближней границей - v5
       {
         if ( next_vertices_flag )//следующая вершина за ближней границей
         {
-          //t = near_clip - v0.z / v1.z - v0.z
+          //t = near_clip - v4.z / v5.z - v4.z
           t = fixpoint_div(0x80000 - PortalFace._view_transformed_z[i + 2], PortalFace._view_transformed_z[i + 3] - PortalFace._view_transformed_z[i + 2]);
-          //New_x = (v1.x - v0.x)*t + v0.x
+          //New_x = (v5.x - v4.x)*t + v4.x
           PortalFace._view_transformed_x[depth_num_vertices] = fixpoint_mul((PortalFace._view_transformed_x[i + 3] - PortalFace._view_transformed_x[i + 2]), t) 
                                                                + PortalFace._view_transformed_x[i + 2];
-          //New_y = (v1.y - v0.y)*t + v0.y
+          //New_y = (v5.y - v4.y)*t + v4.y
           PortalFace._view_transformed_y[depth_num_vertices] = fixpoint_mul((PortalFace._view_transformed_y[i + 3] - PortalFace._view_transformed_y[i + 2]), t)
                                                                + PortalFace._view_transformed_y[i + 2];
           //New_z = 8.0(0x80000)
--- a/IndoorCameraD3D.cpp	Thu Mar 27 23:28:54 2014 +0100
+++ b/IndoorCameraD3D.cpp	Thu Mar 27 23:30:02 2014 +0100
@@ -1394,29 +1394,17 @@
 //----- (00436A40) --------------------------------------------------------
 double IndoorCameraD3D::GetPolygonMaxZ(RenderVertexSoft *pVertex, unsigned int uStripType)
 {
-  unsigned int v3; // edx@1
   double result; // st7@1
-  float *v5; // ecx@2
 
-  v3 = uStripType;
   result = 1.1754944e-38;
-  if ( (signed int)uStripType > 0 )
+  for ( uint i = 0; i < uStripType; i++ )
   {
-    v5 = &pVertex->vWorldPosition.z;
-    do
-    {
-      if ( *v5 > result )
-        result = *v5;
-      v5 += 12;
-      --v3;
-    }
-    while ( v3 );
+    if ( pVertex[i].vWorldPosition.z > result )
+      result = pVertex[i].vWorldPosition.z;
   }
   return result;
 }
 
-
-
 // -- new
 // merged from IndoorCamera::Initialize2
 //         and ODMRenderParams::RotationToInts
--- a/LightmapBuilder.cpp	Thu Mar 27 23:28:54 2014 +0100
+++ b/LightmapBuilder.cpp	Thu Mar 27 23:30:02 2014 +0100
@@ -240,7 +240,7 @@
   if (!v11->uNumVertices)
     return true;
 
-  v45 = _45C6D6(uNumVertices, a9, v11);
+  v45 = _45C6D6(uNumVertices, a9, v11);//освещён ли фейс(есть ошибка)
   if ( v45 != uNumVertices && v45 > 0 )
     _45C4B9(uNumVertices, a9, v11);
   //v59 = v11->uNumVertices;
@@ -332,7 +332,7 @@
   double v17; // st6@24
   signed int v18; // edx@33
   int v20; // [sp+4h] [bp-1Ch]@3
-  int v21; // [sp+8h] [bp-18h]@8
+  //int v21; // [sp+8h] [bp-18h]@8
   float v22; // [sp+Ch] [bp-14h]@23
   float v23; // [sp+10h] [bp-10h]@20
   int v24; // [sp+14h] [bp-Ch]@1
@@ -340,6 +340,8 @@
   char v26; // [sp+1Eh] [bp-2h]@17
   char v27; // [sp+1Fh] [bp-1h]@17
 
+  __debugbreak();//Ritor1: needed cleaning
+
   v4 = pLightmap;
   v5 = 0;
   v6 = pLightmap->uNumVertices;
@@ -357,23 +359,20 @@
         || v7->vWorldPosition.y != v4->pVertices[v8].vWorldPosition.y
         || v7->vWorldPosition.z != v4->pVertices[v8].vWorldPosition.z )
       {
-        v10 = 0;
+        //v10 = 0;
         if ( a2 > 0 )
         {
-          v11 = (char *)&a3->vWorldPosition.z;
-          do
+          //v11 = (char *)&a3->vWorldPosition.z;
+          for ( v10 = 1; v10 <= a2; ++v10 )
           {
-            v21 = v10 + 1;
-            v12 = &a3[(v10 + 1) % a2];
-            if ( (*((float *)v11 - 2) != v12->vWorldPosition.x
-               || *((float *)v11 - 1) != v12->vWorldPosition.y
-               || *(float *)v11 != v12->vWorldPosition.z)
-              && v7->vWorldPosition.x == *((float *)v11 - 2)
-              && v7->vWorldPosition.y == *((float *)v11 - 1)
-              && v7->vWorldPosition.z == *(float *)v11
+            //v21 = v10 + 1;
+            v12 = &a3[v10 % a2];
+            if ((a3[v10].vWorldPosition.x != v12->vWorldPosition.x
+              || a3[v10].vWorldPosition.y != v12->vWorldPosition.y || a3[v10].vWorldPosition.z != v12->vWorldPosition.z)
+              && v7->vWorldPosition.x == a3[v10].vWorldPosition.x
+              && v7->vWorldPosition.y == a3[v10].vWorldPosition.y && v7->vWorldPosition.z == a3[v10].vWorldPosition.z
               && (v9->vWorldPosition.x != v12->vWorldPosition.x
-               || v9->vWorldPosition.y != v12->vWorldPosition.y
-               || v9->vWorldPosition.z != v12->vWorldPosition.z) )
+               || v9->vWorldPosition.y != v12->vWorldPosition.y || v9->vWorldPosition.z != v12->vWorldPosition.z) )
             {
               v13 = 0;
               v14 = 0;
@@ -384,11 +383,13 @@
               else
                 v15 = v9->vWorldPosition.x - v12->vWorldPosition.x;
               v23 = v15;
+
               if ( v9->vWorldPosition.y <= (double)v12->vWorldPosition.y )
                 v16 = v12->vWorldPosition.y - v9->vWorldPosition.y;
               else
                 v16 = v9->vWorldPosition.y - v12->vWorldPosition.y;
               v22 = v16;
+
               if ( v9->vWorldPosition.z <= (double)v12->vWorldPosition.z )
                 v17 = v12->vWorldPosition.z - v9->vWorldPosition.z;
               else
@@ -431,10 +432,10 @@
               }
               v7 = v25;
             }
-            ++v10;
-            v11 += 48;
+            //++v10;
+            //v11 += 48;
           }
-          while ( v21 < a2 );
+          //while ( v21 < a2 );
           v4 = pLightmap;
         }
       }
@@ -486,7 +487,7 @@
                   : pLightmap->pVertices[i].vWorldPosition.z - a3[j].vWorldPosition.z;
               if ( v11 < 2.0 )
               {
-                v12 = v9 + v11 + v10;
+                v12 = v9 + v11 + v10;//Ritor1: Ошибка: В ИДА сюда заходит в данже рядом с факелом, а у нас нет, причину не нашёл
                 if ( v12 < v16 )
                 {
                   v16 = v12;
@@ -611,15 +612,17 @@
   int a5; // [sp+2Ch] [bp-1Ch]@1
   float v19; // [sp+30h] [bp-18h]@1
   float v20; // [sp+34h] [bp-14h]@1
-  LightmapBuilder *thisa; // [sp+38h] [bp-10h]@1
+  //LightmapBuilder *thisa; // [sp+38h] [bp-10h]@1
   int v22; // [sp+3Ch] [bp-Ch]@1
   int *j; // [sp+40h] [bp-8h]@3
   int i; // [sp+44h] [bp-4h]@1
   int a3a; // [sp+58h] [bp+10h]@2
 
+  __debugbreak();//Ritor1: needed cleaning
+
   *(float *)&a5 = 0.0;
   v19 = 0.0;
-  thisa = this;
+  //thisa = this;
   v20 = 0.0;
   result = _45CBD4(a3, a4, dword_69B010.data(), &v22);
   for ( i = 0; i < v22; result = i )
@@ -1164,7 +1167,16 @@
         X = LODWORD(v61),
         v52 = v63,
         SLODWORD(v61) > v63) )*/
-  if (0)
+        v49 = pNormal;
+        Vec3_float_::NegDot(&v11->vWorldPosition, pNormal, a3);
+        *(float *)a3 = (double)v8->vPosition.x * v49->x
+                      + (double)v8->vPosition.y * v49->y
+                      + (double)v8->vPosition.z * v49->z + *a3;
+        v61 = *(float *)a3 + 6.7553994e15;
+        result = LODWORD(v61);
+        X = LODWORD(v61);
+        v52 = v63;
+  if ( SLODWORD(v61) > v63)
     return 0;
   v53 = pSlot;
   v60 = X;
--- a/MMT.cpp	Thu Mar 27 23:28:54 2014 +0100
+++ b/MMT.cpp	Thu Mar 27 23:30:02 2014 +0100
@@ -12,6 +12,7 @@
 #include "CShow.h"
 #include "GUIFont.h"
 #include "lib/libpng/png.h"
+#include "MediaPlayer.h"
 
 void  ShowLogoVideo()
 {
@@ -181,6 +182,20 @@
 
   pGUIWindow2 = 0;
   pAudioPlayer->StopChannels(-1, -1);//остановить/подготовить канал
+
+  if (!bNoSound )
+  {
+    Media::Player *p = new Media::Player;//создаётся плеер
+    Media::ITrack *track = p->LoadTrack(L"Sounds\\New_Sounds/Stronghold_Theme.mp3");
+    track->Play();
+  }
+  /*if (!bNoVideo )
+  {
+    Media::Player *p = new Media::Player;//создаётся плеер
+	Media::IMovie *track = p->LoadMovie(L"Anims\\New_Video/3DOLOGO.smk", 640, 480, 0);
+    track->Play();
+  }	 */
+
   pMouse->RemoveHoldingItem();//избавить курсор от вещи
 
   pIcons_LOD->_inlined_sub2();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MediaPlayer.cpp	Thu Mar 27 23:30:02 2014 +0100
@@ -0,0 +1,817 @@
+extern "C"
+{
+  #include "lib/libavcodec/avcodec.h"
+  #include "lib/libavformat/avformat.h"
+  #include "lib/libavutil/avutil.h"
+  #include "lib/libavutil/imgutils.h"
+  #include "lib/libswscale/swscale.h"
+  #include "lib/libswresample/swresample.h"
+  #include "lib/libavutil/opt.h"
+}
+#pragma comment(lib, "avcodec.lib")
+#pragma comment(lib, "avformat.lib")
+#pragma comment(lib, "avutil.lib")
+#pragma comment(lib, "swscale.lib")
+#pragma comment(lib, "swresample.lib")
+
+#include <vector>
+#include <deque>
+
+#include "stuff.h"
+#include "OpenALSoundProvider.h"
+
+#include "MediaPlayer.h"
+using namespace Media;
+
+
+class MemoryStream
+{
+  public:
+    inline MemoryStream(void *data, size_t data_size)
+    {
+      this->data_size = data_size;
+      this->data = data;
+      this->current_pos = 0;
+    }
+    inline MemoryStream()
+    {
+      this->data_size = 0;
+      this->data = nullptr;
+      this->current_pos = 0;
+    }
+
+    inline ~MemoryStream()
+    {
+      if (data)
+        delete [] data;
+    }
+
+    inline size_t Write(void *buffer, size_t num_bytes)
+    {
+      if (!data)
+      {
+        data_size = 32 + num_bytes;
+        data = new char[data_size];
+        current_pos = 0;
+      }
+      else if (current_pos + num_bytes >= data_size)
+      {
+        int  new_data_size = data_size + num_bytes + data_size / 8 + 4;
+        auto new_data = new char[new_data_size];
+
+        memcpy(new_data, data, data_size);
+        delete [] data;
+        
+        data_size = new_data_size;
+        data = new_data;
+      }
+      memcpy((char *)data + current_pos, buffer, num_bytes);
+      current_pos += num_bytes;
+      return num_bytes;
+    }
+
+    inline size_t Read(void *buffer, size_t num_bytes)
+    {
+      size_t read_size = min(num_bytes, data_size - current_pos);
+      if (read_size)
+      {
+        memcpy(buffer, (char *)data + current_pos, read_size);
+        current_pos += read_size;
+      }
+      return read_size;
+    }
+
+    inline void Reset()
+    {
+      current_pos = 0;
+    }
+    inline void SeekToEnd()
+    {
+      current_pos = data_size;
+    }
+
+    inline size_t Unwind(size_t bytes)
+    {
+      if (bytes > current_pos)
+        current_pos = 0;
+      else
+        current_pos -= bytes;
+      return current_pos;
+    }
+    
+    inline size_t Rewind(size_t bytes)
+    {
+      if (current_pos + bytes >= data_size)
+        current_pos = data_size;
+      else
+        current_pos += bytes;
+      return current_pos;
+    }
+
+    inline size_t  Size() const    {return data_size;}
+    inline size_t  Current() const {return current_pos;}
+    inline void   *Ptr() const     {return data;}
+
+  private:
+    void   *data;
+    size_t  data_size;
+    size_t  current_pos;
+};
+
+
+
+
+OpenALSoundProvider *provider = nullptr;
+
+
+
+static int av_num_bytes_per_sample(AVSampleFormat sample_fmt)
+{
+  switch (sample_fmt)
+  {
+    case AV_SAMPLE_FMT_U8:
+    case AV_SAMPLE_FMT_U8P:
+      return 1;
+          
+    case AV_SAMPLE_FMT_S16:
+    case AV_SAMPLE_FMT_S16P:
+      return 2;
+
+    case AV_SAMPLE_FMT_S32:
+    case AV_SAMPLE_FMT_S32P:
+    case AV_SAMPLE_FMT_FLT:
+    case AV_SAMPLE_FMT_FLTP:
+      return 4;
+
+    case AV_SAMPLE_FMT_DBL:
+    case AV_SAMPLE_FMT_DBLP:
+      return 8;
+
+    default:
+    case AV_SAMPLE_FMT_NONE:
+      Error("Invalid av sample format: %u", sample_fmt);
+  }
+  return 0;
+}
+
+
+
+struct AVStreamWrapper
+{
+  inline AVStreamWrapper()
+  {
+    this->type = AVMEDIA_TYPE_UNKNOWN;
+    this->stream_idx = -1;
+    this->stream = nullptr;
+    this->dec = nullptr;
+    this->dec_ctx = nullptr;
+  }
+
+  inline void Release()
+  {
+    type = AVMEDIA_TYPE_UNKNOWN;
+    stream_idx = -1;
+    stream = nullptr;
+    dec = nullptr;
+    if (dec_ctx)
+    {
+      avcodec_close(dec_ctx);
+      dec_ctx = nullptr;
+    }
+  }
+
+  AVMediaType      type;
+  int              stream_idx;
+  AVStream        *stream;
+  AVCodec         *dec;
+  AVCodecContext  *dec_ctx;
+};
+
+struct AVAudioStream: public AVStreamWrapper
+{
+  inline AVAudioStream():
+    AVStreamWrapper()
+  {
+    this->bytes_per_sample = 0;
+    this->bytes_per_second = 0;
+  }
+
+  int bytes_per_sample;
+  int bytes_per_second;
+};
+
+struct AVVideoStream: public AVStreamWrapper
+{
+  inline AVVideoStream():
+    AVStreamWrapper()
+  {
+    this->frames_per_second = 0.0;
+  }
+
+  double frames_per_second;
+};
+
+static bool av_open_stream(AVFormatContext *format_ctx, AVMediaType type, AVStreamWrapper *out_stream)
+{
+  int stream_idx = av_find_best_stream(format_ctx, type, -1, -1, nullptr, 0);
+  if (stream_idx >= 0)
+  {
+    auto stream = format_ctx->streams[stream_idx];
+    auto dec_ctx = stream->codec;
+    auto dec = avcodec_find_decoder(dec_ctx->codec_id);
+    if (dec)
+    {
+      if (avcodec_open2(dec_ctx, dec, nullptr) >= 0)
+      {
+        out_stream->type = type;
+        out_stream->stream_idx = stream_idx;
+        out_stream->stream = stream;
+        out_stream->dec = dec;
+        out_stream->dec_ctx = dec_ctx;
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+static bool av_open_audio_stream(AVFormatContext *format_ctx, AVAudioStream *out_stream)
+{
+  if (!av_open_stream(format_ctx, AVMEDIA_TYPE_AUDIO, out_stream))
+    return Error("Audio stream not found"), false;
+  
+  // we support only 2-channel audio for now
+  if (out_stream->dec_ctx->channels != 2)
+  {
+    out_stream->Release();
+    return Error("Unsupported number of channels: %u", out_stream->dec_ctx->channels), false;
+  }
+  
+  out_stream->bytes_per_sample = av_num_bytes_per_sample(out_stream->dec_ctx->sample_fmt);
+  out_stream->bytes_per_second = out_stream->dec_ctx->channels * out_stream->dec_ctx->sample_rate * out_stream->bytes_per_sample;
+
+  return true;
+}
+
+static bool av_open_video_stream(AVFormatContext *format_ctx, AVVideoStream *out_stream)
+{
+  if (!av_open_stream(format_ctx, AVMEDIA_TYPE_VIDEO, out_stream))
+    return Error("Video stream not found"), false;
+
+  out_stream->frames_per_second = (double)out_stream->dec_ctx->time_base.den / (double)out_stream->dec_ctx->time_base.num;
+  return true;
+}
+
+
+
+void InterleaveAudioData(MemoryStream *stream, AVSampleFormat src_format, int num_channels, int num_samples, uint8_t **channels)
+{
+  unsigned int bytes_per_sample;
+  switch (src_format)
+  {
+    case AV_SAMPLE_FMT_U8:
+    case AV_SAMPLE_FMT_U8P:
+      __debugbreak();
+
+    case AV_SAMPLE_FMT_S16:
+      bytes_per_sample = sizeof(__int16);
+      stream->Write(channels[0], num_channels * num_samples * bytes_per_sample);
+    break;
+
+    case AV_SAMPLE_FMT_S16P:
+    {
+      bytes_per_sample = sizeof(__int16);
+      for (int i = 0; i < num_samples; ++i)
+        for (int j = 0; j < num_channels; ++j)
+          stream->Write(channels[j] + i * bytes_per_sample, bytes_per_sample);
+    }
+    break;
+
+    case AV_SAMPLE_FMT_FLT:
+    {
+      SwrContext *converter = swr_alloc();
+      av_opt_set_int(converter, "in_channel_layout",    av_get_default_channel_layout(2), 0);
+      //av_opt_set_int(converter, "in_sample_rate",       sample_ra, 0);
+      av_opt_set_sample_fmt(converter, "in_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
+
+      av_opt_set_int(converter, "out_channel_layout",    av_get_default_channel_layout(2), 0);
+      //av_opt_set_int(converter, "out_sample_rate",       dst_sample_rate, 0);
+      av_opt_set_sample_fmt(converter, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
+
+      if (swr_init(converter) < 0)
+      {
+        __debugbreak();
+        swr_free(&converter);
+        return;
+      }
+
+      uint8_t **dst_channels;
+      int       dst_linesize[8];
+      //int dst_nb_channels = av_get_channel_layout_nb_channels(dst_channel_layout);
+      if (av_samples_alloc_array_and_samples(&dst_channels, dst_linesize, 2, num_channels * num_samples, AV_SAMPLE_FMT_S16, 0) < 0)
+      {
+        __debugbreak();
+        swr_free(&converter);
+        return;
+      }
+
+      if (swr_convert(converter, dst_channels, num_channels * num_samples, (const uint8_t **)channels, num_channels * num_samples) >= 0)
+        stream->Write(dst_channels[0], num_channels * num_samples * sizeof(__int16));
+      else
+        __debugbreak();
+
+      av_free(dst_channels[0]);
+      swr_free(&converter);
+    }
+    break;
+
+    default:
+      __debugbreak();
+      //if (Resample(next_frame->avframe, next_frame->avframe->channel_layout, next_frame->avframe->sample_rate,
+      //                                            av_get_default_channel_layout(2),    next_frame->avframe->sample_rate, AV_SAMPLE_FMT_S16P, resampled_data))
+  }
+}
+
+
+
+bool DecodeAudioFrame(AVCodecContext *dec_ctx, AVPacket *avpacket, AVFrame *avframe, MemoryStream *out_audio_data, int *out_num_audio_samples)
+{
+  volatile int decoded = false;
+  do
+  {
+    if (avcodec_decode_audio4(dec_ctx, avframe, (int *)&decoded, avpacket) < 0)
+    {
+      log("Cannot decode audio frame\n");
+      return false;
+    }
+
+    if (!decoded)
+      log("Cannot decode audio frame in one piece\n");
+  } while (!decoded);
+
+  switch (dec_ctx->codec_id)
+  {
+    case AV_CODEC_ID_BINKAUDIO_RDFT:
+    {//pts	samples		dpts
+     //    0	960
+     //17280	960		17280    18x960
+     //18240	960		960       1x960
+     //20160	960		1920      2x960
+     //21120	960		960       1x960
+     //23040	960		1920      2x960
+      static int bink_next_pts = 0;
+
+        // there's a gap in the sound - fill empty samples in
+      if (bink_next_pts < avpacket->pts)
+      {
+        short silence[1024];
+        memset(silence, 0, sizeof(silence));
+
+        int samples_to_fill = /*dec_ctx->channels * */(avpacket->pts - bink_next_pts);
+        while (samples_to_fill > 0)
+        {
+          int samples_to_fill_this_step = samples_to_fill >= 1024 ? 1024 : samples_to_fill;
+          out_audio_data->Write(silence, samples_to_fill_this_step  * sizeof(short));
+
+          samples_to_fill -= samples_to_fill_this_step;
+        }
+      }
+
+      bink_next_pts = avpacket->pts + /*dec_ctx->channels * */avframe->nb_samples;
+    }
+    break;
+                /*
+      case AV_CODEC_ID_SMACKAUDIO:
+      {
+        static int smack_debug_next_audio_time = 0;
+        if (smack_debug_next_audio_time != packet->pts)
+        {
+          Error("There's a gap in the sound before frame %u\n", num_audio_frames);
+          __debugbreak(); // there's a gap in the sound
+        }
+
+        int num_actual_data_channels = 0;
+        switch (dec_ctx->sample_fmt)
+        {
+          case AV_SAMPLE_FMT_U8:
+          case AV_SAMPLE_FMT_S16:
+          case AV_SAMPLE_FMT_S32:
+          case AV_SAMPLE_FMT_FLT:
+          case AV_SAMPLE_FMT_DBL:
+            num_actual_data_channels = 1;
+          break;
+
+          case AV_SAMPLE_FMT_U8P:
+          case AV_SAMPLE_FMT_S16P:
+          case AV_SAMPLE_FMT_S32P:
+          case AV_SAMPLE_FMT_FLTP:
+          case AV_SAMPLE_FMT_DBLP:
+            num_actual_data_channels = dec_ctx->channels;
+          break;
+
+          default:
+          case AV_SAMPLE_FMT_NONE:
+          case AV_SAMPLE_FMT_NB:
+            __debugbreak();
+        }
+
+        smack_debug_next_audio_time += dec_ctx->channels * frame->nb_samples * bytes_per_sample;
+        Assert(frame->avframe->linesize[0] == audio.dec_ctx->channels * frame->avframe->nb_samples * audio.bytes_per_sample / num_actual_data_channels,
+               "Smack audio size mismatch in frame %u in %s\n", audio_num_read_frames, movie_filename);
+
+        frame->play_time = (double)frame->avpacket->pts / (double)audio.bytes_per_second;
+      }
+      break;
+
+                case AV_CODEC_ID_MP3:
+                {
+                  static int mp3_samples_decoded_so_far = 0;
+                  static int mp3_prev_samples_count = frame->avframe->nb_samples; // mp3 seems to always feed same amount of samples
+                  frame->play_time = (double)mp3_samples_decoded_so_far / (double)audio.dec_ctx->sample_rate;
+
+                  mp3_samples_decoded_so_far += frame->avframe->nb_samples;
+                  Assert(mp3_prev_samples_count == frame->avframe->nb_samples,
+                          "MP3 audio have variable sample count in frame %u in %s\n", audio_num_read_frames, movie_filename);
+                }
+                break;
+
+                default:
+                {
+                  __debugbreak();
+                  double samples_per_second = (double)audio.dec_ctx->time_base.den / (double)audio.dec_ctx->time_base.num;
+                  double play_length = frame->avframe->nb_samples / samples_per_second;
+                  frame->play_time = (double)frame->avpacket->pts / samples_per_second;
+                }
+                break;*/
+  }
+
+  if (!avframe->channel_layout)
+  {
+    log("Audio channel layout not specified, rolling back to default\n");
+    avframe->channel_layout = av_get_default_channel_layout(dec_ctx->channels);
+  }
+
+  *out_num_audio_samples = dec_ctx->channels * avframe->nb_samples;
+  InterleaveAudioData(out_audio_data, dec_ctx->sample_fmt,
+                      dec_ctx->channels, avframe->nb_samples, avframe->data);
+  return true;
+}
+
+
+bool LoadAudioTrack(AVFormatContext *format_ctx, AVCodecContext *dec_ctx, int audio_stream_idx, MemoryStream *out_audio_stream, int *out_num_audio_frames, int *out_num_audio_samples)
+{
+  out_audio_stream->Reset();
+
+  AVFrame  *frame = avcodec_alloc_frame();
+  AVPacket *packet = new AVPacket;
+  av_init_packet(packet);
+
+  int num_audio_frames = 0;
+  int num_audio_samples = 0;
+  while (av_read_frame(format_ctx, packet) >= 0)
+  {
+    if (packet->stream_index != audio_stream_idx)
+    {
+      //log("Suspicious stream id %u in %s", packet->stream_index, filenamea);
+      continue;
+    }
+
+    int num_samples_decoded;
+    DecodeAudioFrame(dec_ctx, packet, frame, out_audio_stream, &num_samples_decoded);
+
+    num_audio_samples += num_samples_decoded;
+    num_audio_frames++;
+  }
+  *out_num_audio_frames = num_audio_frames;
+  *out_num_audio_samples = num_audio_samples;
+
+  avcodec_free_frame(&frame);
+  delete packet;
+
+  return true;
+}
+
+
+class Track: public Media::ITrack
+{
+  public:
+    inline Track()
+    {
+      this->format_ctx = nullptr;
+      this->audio_num_samples = 0;
+    }
+
+    void Release()
+    {
+      ReleaseAvcodec();
+    }
+
+    void ReleaseAvcodec()
+    {
+      audio.Release();
+      if (format_ctx)
+      {
+        av_close_input_file(format_ctx);
+        format_ctx = nullptr;
+      }
+    }
+
+    bool Load(const wchar_t *filename)
+    {
+      char filenamea[1024];
+      sprintf(filenamea, "%S", filename);
+
+      if (avformat_open_input(&format_ctx, filenamea, nullptr, nullptr) >= 0)
+      {
+        if (avformat_find_stream_info(format_ctx, nullptr) >= 0)
+        {
+          av_dump_format(format_ctx, 0, filenamea, 0);
+
+          if (!av_open_audio_stream(format_ctx, &audio))
+          {
+            Error("Cannot open strack: %s", filenamea);
+            return Release(), false;
+          }
+          
+          MemoryStream audio_plain_data;
+          int          num_audio_frames;
+          int          num_audio_samples;
+          if (LoadAudioTrack(format_ctx, audio.dec_ctx, audio.stream_idx, &audio_plain_data, &num_audio_frames, &num_audio_samples))
+          {
+            /*#ifdef _DEBUG
+              char debug_filename[1024];
+              sprintf(debug_filename, "%s.wav", filenamea);
+              FILE *wav = fopen(debug_filename, "w+b");
+
+              extern void write_wav_header(FILE *wav, int channel_count = 2, int sample_rate = 22050, int bytes_per_sample = 2);
+              write_wav_header(wav, audio.dec_ctx->channels, audio.dec_ctx->sample_rate, audio.bytes_per_sample);
+
+              fwrite(audio_plain_data.Ptr(), audio_plain_data.Current(), 1, wav);
+            
+              extern void fix_wav_header(FILE *wav, int wav_bytes_in_stream);
+              fix_wav_header(wav, audio_plain_data.Current());
+            #endif*/
+
+            device_buffer = provider->CreateTrack16(audio.dec_ctx->channels, audio.dec_ctx->sample_rate, 2, num_audio_samples, audio_plain_data.Ptr());
+
+            ReleaseAvcodec();
+            return true;
+          }
+        }
+        Release();
+      }
+      return false;
+    }
+
+    virtual void Play(bool loop)
+    {
+      provider->PlayTrack16(device_buffer, loop);
+    }
+
+
+  protected:
+    AVFormatContext *format_ctx;
+    AVAudioStream    audio;
+    int              audio_num_samples;
+
+    OpenALSoundProvider::TrackBuffer *device_buffer;
+};
+
+
+
+class Movie: public Media::IMovie
+{
+  public:
+    inline Movie()
+    {
+      this->movie_filename[0] = 0;
+      this->width = 0;
+      this->height = 0;
+      this->format_ctx = nullptr;
+      this->end_of_file = false;
+      this->playback_time = 0.0;
+
+      this->num_audio_frames = 0;
+      this->num_audio_samples = 0;
+
+      this->last_resampled_frame_num = -1;
+      memset(last_resampled_frame_data, 0, sizeof(last_resampled_frame_data));
+      memset(last_resampled_frame_linesize, 0, sizeof(last_resampled_frame_linesize));
+    }
+
+
+    inline void Release()
+    {
+      ReleaseAVCodec();
+    }
+
+    inline void ReleaseAVCodec()
+    {
+      audio.Release();
+      video.Release();
+      if (format_ctx)
+      {
+        av_close_input_file(format_ctx);
+        format_ctx = nullptr;
+      }
+    }
+
+    bool Load(const wchar_t *filename, int dst_width, int dst_height, int cache_ms)
+    {
+      char filenamea[1024];
+      sprintf(filenamea, "%S", filename);
+      sprintf(movie_filename, "%S", filename);
+
+      width = dst_width;
+      height = dst_height;
+      if (avformat_open_input(&format_ctx, filenamea, nullptr, nullptr) >= 0)
+      {
+        if (avformat_find_stream_info(format_ctx, nullptr) >= 0)
+        {
+          av_dump_format(format_ctx, 0, filenamea, 0);
+
+          if (!av_open_audio_stream(format_ctx, &audio))
+          {
+            Error("Cannot open audio stream: %s", filenamea);
+            return Release(), false;
+          }
+          
+          if (!av_open_video_stream(format_ctx, &video))
+          {
+            Error("Cannot open video stream: %s", filenamea);
+            return Release(), false;
+          }
+          
+          decoding_packet = new AVPacket;
+          av_init_packet(decoding_packet);
+      
+          decoding_frame = avcodec_alloc_frame();
+
+          audio_data_in_device = provider->CreateStreamingTrack16(audio.dec_ctx->channels, audio.dec_ctx->sample_rate, 2);
+
+          return true;
+        }
+      }
+      return false;
+    }
+
+    virtual void Play()
+    {
+    }
+
+    virtual void GetNextFrame(double dt, void *dst_surface)// рисует сразу на экран
+    {
+      playback_time += dt;//изменение времени
+
+      AVPacket *avpacket = decoding_packet;
+      AVFrame *avframe = decoding_frame;
+      avcodec_get_frame_defaults(avframe);
+
+      int desired_frame_number = floor(playback_time * video.dec_ctx->time_base.den / video.dec_ctx->time_base.num + 0.5);
+      if (last_resampled_frame_num == desired_frame_number)
+      {
+        memcpy(dst_surface, last_resampled_frame_data[0], height * last_resampled_frame_linesize[0]);
+        return;
+      }
+
+      volatile int decoded = false;
+      do
+      {
+        if (av_read_frame(format_ctx, avpacket) < 0) //воспроизведение завершено
+        {
+          // probably movie is finished
+          __debugbreak();
+        }
+
+        // audio packet - queue into playing
+        if (avpacket->stream_index == audio.stream_idx)
+        {
+          MemoryStream audio_data;
+          if (DecodeAudioFrame(audio.dec_ctx, avpacket, avframe, &audio_data, &num_audio_samples))
+            provider->Stream16(audio_data_in_device, num_audio_samples, audio_data.Ptr());
+        }
+        // video packet - decode & maybe show
+        else if (avpacket->stream_index == video.stream_idx)
+        {
+          do
+          {
+            if (avcodec_decode_video2(video.dec_ctx, avframe, (int *)&decoded, avpacket) < 0)
+              __debugbreak();
+          } while (!decoded);
+        }
+
+      } while (avpacket->stream_index != video.stream_idx ||
+               avpacket->pts != desired_frame_number);
+
+      if (decoded)
+      {
+        if (last_resampled_frame_data[0])
+          av_freep(&last_resampled_frame_data[0]);
+
+        AVPixelFormat  rescaled_format = AV_PIX_FMT_RGB32;
+        uint8_t       *rescaled_data[4] = {nullptr, nullptr, nullptr, nullptr};
+        int            rescaled_linesize[4] = {0, 0, 0, 0};
+        if (av_image_alloc(rescaled_data, rescaled_linesize, width, height, rescaled_format, 1) >= 0)
+        {
+          SwsContext *converter = sws_getContext(avframe->width, avframe->height, (AVPixelFormat)avframe->format,
+                                                 width, height, rescaled_format,
+                                                 SWS_BICUBIC, nullptr, nullptr, nullptr);
+          sws_scale(converter, avframe->data, avframe->linesize, 0, avframe->height, rescaled_data, rescaled_linesize);
+          sws_freeContext(converter);
+
+          memcpy(dst_surface, rescaled_data[0], height * rescaled_linesize[0]);
+
+          last_resampled_frame_num = desired_frame_number;
+          memcpy(last_resampled_frame_data, rescaled_data, sizeof(rescaled_data));
+          memcpy(last_resampled_frame_linesize, rescaled_linesize, sizeof(rescaled_linesize));
+        }
+      }
+      else
+        memset(dst_surface, 0, width * height * 4);
+    }
+
+  protected:
+    char             movie_filename[256];
+    int              width;
+    int              height;
+    AVFormatContext *format_ctx;
+    double           playback_time;
+    bool             end_of_file;
+
+    AVPacket        *decoding_packet;
+    AVFrame         *decoding_frame;
+
+    AVAudioStream   audio;
+    int             num_audio_frames;
+    int             num_audio_samples;
+    OpenALSoundProvider::StreamingTrackBuffer *audio_data_in_device;
+
+    AVVideoStream   video;
+    int             last_resampled_frame_num;
+    uint8_t        *last_resampled_frame_data[4];
+    int             last_resampled_frame_linesize[4];
+};
+
+
+ITrack *Player::LoadTrack(const wchar_t *filename)
+{
+  auto track = new Track;
+  if (!track->Load(filename))
+  {
+    delete track;
+    track = nullptr;
+  }
+  return track;
+}
+
+
+IMovie *Player::LoadMovie(const wchar_t *filename, int width, int height, int cache_ms)
+{
+  auto movie = new Movie;
+  if (!movie->Load(filename, width, height, cache_ms))
+  {
+    delete movie;
+    movie = nullptr;
+  }
+  return movie;
+}
+
+
+
+
+
+
+void av_logger(void *, int, const char *format, va_list args)
+{
+  va_list va;
+  va_start(va, format);
+  char msg[256];
+  vsprintf(msg, format, va);
+  va_end(va);
+
+  log("av: %s", msg);
+}
+
+Player::Player()
+{
+  static int libavcodec_initialized = false;
+
+  if (!libavcodec_initialized)
+  {
+    av_log_set_callback(av_logger);
+    avcodec_register_all();
+    av_register_all();
+
+    libavcodec_initialized = true;
+  }
+
+  if (!provider)
+  {
+    provider = new OpenALSoundProvider;
+    provider->Initialize();
+  }
+}
+
+Player::~Player()
+{
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MediaPlayer.h	Thu Mar 27 23:30:02 2014 +0100
@@ -0,0 +1,26 @@
+#pragma once
+
+namespace Media
+{
+  class ITrack
+  {
+    public: virtual void Play(bool loop = false) = 0;
+  };
+
+  class IMovie
+  {
+    public: virtual void Play() = 0;
+            virtual void GetNextFrame(double dt, void *target_surface) = 0;
+  };
+
+  class Player
+  {
+    public:
+               Player();
+      virtual ~Player();
+
+
+      ITrack *LoadTrack(const wchar_t *name);
+      IMovie *LoadMovie(const wchar_t *name, int width, int height, int cache_ms);
+  };
+};
\ No newline at end of file
--- a/OSWindow.cpp	Thu Mar 27 23:28:54 2014 +0100
+++ b/OSWindow.cpp	Thu Mar 27 23:30:02 2014 +0100
@@ -31,6 +31,7 @@
 bool draw_portals_loops = false;    //видны рамки порталов
 bool new_speed = false;
 bool bSnow = false;
+bool draw_terrain_dist_mist = false;//новая дальность отрисовки тайлов
 
 bool OSWindow::OnMouseLeftClick(int x, int y)
 {
@@ -751,6 +752,12 @@
         AppendMenuW(other_snow, MF_ENABLED | MF_STRING, 40117, L"Snowfall on");
         AppendMenuW(other_snow, MF_ENABLED | MF_STRING, 40118, L"Snowfall off");
       }
+      HMENU other_draw_terrain_dist_mist = CreatePopupMenu();
+      AppendMenuW(other, MF_ENABLED | MF_STRING | MF_POPUP, (UINT_PTR)other_draw_terrain_dist_mist, L"New draw terrain distance");
+      {
+        AppendMenuW(other_draw_terrain_dist_mist, MF_ENABLED | MF_STRING, 40119, L"New draw terrain distance on");
+        AppendMenuW(other_draw_terrain_dist_mist, MF_ENABLED | MF_STRING, 40120, L"New draw terrain distance off");
+      }
 
     }
   }
@@ -887,6 +894,8 @@
     case 40116:  new_speed = false;  break;                          //включить двойную скорость
     case 40117:  bSnow = true;  break;                           //включить снег
     case 40118:  bSnow = false;  break;                          //включить снег
+    case 40119:  draw_terrain_dist_mist = true;  break;                           //новая дальность отрисовки тайлов
+    case 40120:  draw_terrain_dist_mist = false;  break;                          //обычная дальность отрисовки тайлов
 
   }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OpenALSoundProvider.h	Thu Mar 27 23:30:02 2014 +0100
@@ -0,0 +1,343 @@
+#pragma once
+#include "lib/OpenAL/al.h"
+#include "lib/OpenAL/alc.h"
+#pragma comment(lib, "OpenAL32.lib")
+
+#include "stuff.h"
+
+class OpenALSoundProvider
+{
+  public:
+    struct TrackBuffer
+    {
+      unsigned int source_id;
+      unsigned int buffer_id;
+    };
+
+    struct StreamingTrackBuffer
+    {
+      unsigned int source_id;
+      ALenum       sample_format;
+      int          sample_rate;
+    };
+
+    inline OpenALSoundProvider()
+    {
+      this->device = nullptr;
+      this->context = nullptr;
+    }
+
+    inline bool Initialize()
+    {
+      auto device_names = alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER);
+      if (!device_names)
+        device_names = alcGetString(nullptr, ALC_DEVICE_SPECIFIER);
+      if (device_names)
+      {
+        for (auto device_name = device_names; device_name[0]; device_name += strlen(device_name))
+        {
+          continue;
+        }
+      }
+
+      device = alcOpenDevice(nullptr);
+      if (!device || CheckError())
+        return false;
+
+      context = alcCreateContext(device, nullptr);
+      if (!context || CheckError())
+        return Release(), false;
+
+      alcMakeContextCurrent(context);
+
+      bool eax2 = alIsExtensionPresent("EAX2.0");
+      bool eax3 = alIsExtensionPresent("EAX3.0");
+      bool eax4 = alIsExtensionPresent("EAX4.0");
+      bool eax5 = alIsExtensionPresent("EAX5.0");
+      
+      auto vendor = alGetString(AL_VENDOR);
+      auto version = alGetString(AL_VERSION);
+      auto extensions = alcGetString(device, ALC_EXTENSIONS);
+
+      return true;
+    }
+
+    void Release()
+    {
+      alcMakeContextCurrent(nullptr);
+      if (context)
+      {
+        alcDestroyContext(context);
+        context = nullptr;
+      }
+      if (device)
+      {
+        alcCloseDevice(device);
+        device = nullptr;
+      }
+    }
+
+
+    void DeleteBuffer16(TrackBuffer **buffer)
+    {
+      alDeleteBuffers(1, &(*buffer)->buffer_id);
+      CheckError();
+
+      delete *buffer;
+      *buffer = nullptr;
+    }
+
+    float alBufferLength(unsigned int buffer)
+    {
+      int size, bits, channels, freq;
+
+      alGetBufferi(buffer, AL_SIZE, &size);
+      alGetBufferi(buffer, AL_BITS, &bits);
+      alGetBufferi(buffer, AL_CHANNELS, &channels);
+      alGetBufferi(buffer, AL_FREQUENCY, &freq);
+      if (CheckError())
+        return 0.0f;
+
+      return (ALfloat)((ALuint)size / channels / (bits / 8)) / (ALfloat)freq;
+    }
+
+    StreamingTrackBuffer *CreateStreamingTrack16(int num_channels, int sample_rate, int bytes_per_sample)
+    {
+      Assert(bytes_per_sample == 2, "OpenALSoundProvider: unsupported sample size: %u", bytes_per_sample);
+
+      ALenum sound_format;
+      switch (num_channels)
+      {
+        case 1: sound_format = AL_FORMAT_MONO16;    break;
+        case 2: sound_format = AL_FORMAT_STEREO16;  break;
+        default:
+          if (bool multichannel = alIsExtensionPresent("AL_EXT_MCFORMATS"))
+          {
+            switch (num_channels)
+            {
+              case 4: sound_format = alGetEnumValue("AL_FORMAT_QUAD16");  break;
+              case 6: sound_format = alGetEnumValue("AL_FORMAT_51CHN16"); break;
+              case 7: sound_format = alGetEnumValue("AL_FORMAT_61CHN16"); break;
+              case 8: sound_format = alGetEnumValue("AL_FORMAT_71CHN16"); break;
+            }
+          }
+          Error("Unsupported number of audio channels: %u", num_channels);
+      }
+
+      unsigned int al_source = -1;
+      alGenSources(1, &al_source);
+      if (CheckError())
+        return nullptr;
+
+      float sound_pos[] = {0.0f, 0.0f, 0.0f},
+            sound_vel[] = {0.0f, 0.0f, 0.0f};
+
+      alSourcei(al_source, AL_LOOPING, AL_FALSE);
+      alSourcef(al_source, AL_PITCH, 1.0f);
+      alSourcef(al_source, AL_GAIN, 1.0f);
+      alSourcefv(al_source, AL_POSITION, sound_pos);
+      alSourcefv(al_source, AL_VELOCITY, sound_vel);
+
+      auto ret = new StreamingTrackBuffer;
+      ret->source_id = al_source;
+      ret->sample_format = sound_format;
+      ret->sample_rate = sample_rate;
+      return ret;
+    }
+
+    void Stream16(StreamingTrackBuffer *buffer, int num_samples, const void *samples, bool wait = false)
+    {
+      int bytes_per_sample = 2;
+
+      unsigned int al_buffer;
+      alGenBuffers(1, &al_buffer);
+      alBufferData(al_buffer, buffer->sample_format, samples, num_samples * bytes_per_sample, buffer->sample_rate);
+      if (CheckError())
+      {
+        alDeleteBuffers(1, &al_buffer);
+        return;
+      }
+
+      int num_processed_buffers = 0;
+      alGetSourcei(buffer->source_id, AL_BUFFERS_PROCESSED, &num_processed_buffers);
+      for (int i = 0; i < num_processed_buffers; ++i)
+      {
+        unsigned int processed_buffer_id;
+        alSourceUnqueueBuffers(buffer->source_id, 1, &processed_buffer_id);
+        if (!CheckError())
+          alDeleteBuffers(1, &processed_buffer_id);
+      }
+
+      alSourceQueueBuffers(buffer->source_id, 1, &al_buffer);
+      if (CheckError())
+      {
+        alDeleteBuffers(1, &al_buffer);
+        return;
+      }
+
+      volatile int status;
+      alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
+      if (status != AL_PLAYING)
+      {
+        float listener_pos[] = {0.0f, 0.0f, 0.0f};
+        float listener_vel[] = {0.0f, 0.0f, 0.0f};
+        float listener_orientation[] = {0.0f, 0.0f, -1.0f, // direction
+                                        0.0f, 1.0f, 0.0f}; // up vector
+        alListenerfv(AL_POSITION, listener_pos);
+        alListenerfv(AL_VELOCITY, listener_vel);
+        alListenerfv(AL_ORIENTATION, listener_orientation);
+
+        alSourcePlay(buffer->source_id);
+        if (CheckError())
+          __debugbreak();
+
+        if (wait)
+        {
+          do
+          {
+            alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
+          }
+          while (status == AL_PLAYING);
+        }
+      }
+    }
+
+
+
+
+    TrackBuffer *CreateTrack16(int num_channels, int sample_rate, int bytes_per_sample, int num_samples, const void *samples)
+    {
+      Assert(bytes_per_sample == 2, "OpenALSoundProvider: unsupported sample size: %u", bytes_per_sample);
+
+      ALenum sound_format;
+      switch (num_channels)
+      {
+        case 1: sound_format = AL_FORMAT_MONO16;    break;
+        case 2: sound_format = AL_FORMAT_STEREO16;  break;
+        default:
+          if (bool multichannel = alIsExtensionPresent("AL_EXT_MCFORMATS"))
+          {
+            switch (num_channels)
+            {
+              case 4: sound_format = alGetEnumValue("AL_FORMAT_QUAD16");  break;
+              case 6: sound_format = alGetEnumValue("AL_FORMAT_51CHN16"); break;
+              case 7: sound_format = alGetEnumValue("AL_FORMAT_61CHN16"); break;
+              case 8: sound_format = alGetEnumValue("AL_FORMAT_71CHN16"); break;
+            }
+          }
+          Error("Unsupported number of audio channels: %u", num_channels);
+      }
+
+      unsigned int al_source = -1;
+      alGenSources(1, &al_source);
+      if (CheckError())
+        return nullptr;
+
+      float sound_pos[] = {0.0f, 0.0f, 0.0f},
+            sound_vel[] = {0.0f, 0.0f, 0.0f};
+
+      alSourcei(al_source, AL_LOOPING, AL_FALSE);
+      alSourcef(al_source, AL_PITCH, 1.0f);
+      alSourcef(al_source, AL_GAIN, 1.0f);
+      alSourcefv(al_source, AL_POSITION, sound_pos);
+      alSourcefv(al_source, AL_VELOCITY, sound_vel);
+
+      unsigned int al_buffer = -1;
+      alGenBuffers(1, &al_buffer);
+      if (CheckError())
+      {
+        alDeleteSources(1, &al_source);
+        return nullptr;
+      }
+
+      alBufferData(al_buffer, sound_format, samples, num_samples * bytes_per_sample, sample_rate);
+      if (CheckError())
+      {
+        alDeleteSources(1, &al_source);
+        alDeleteBuffers(1, &al_buffer);
+        return nullptr;
+      }
+
+      alSourcei(al_source, AL_BUFFER, al_buffer);
+      if (CheckError())
+      {
+        alDeleteSources(1, &al_source);
+        alDeleteBuffers(1, &al_buffer);
+        return nullptr;
+      }
+
+      auto ret = new TrackBuffer;
+      ret->source_id = al_source;
+      ret->buffer_id = al_buffer;
+      return ret;
+    }
+
+
+    void PlayTrack16(TrackBuffer *buffer, bool loop = false, bool wait = false)
+    {
+      volatile int status;
+      alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
+      if (status == AL_PLAYING)
+        Error("Already playing");
+      else
+      {
+        float listener_pos[] = {0.0f, 0.0f, 0.0f};
+        float listener_vel[] = {0.0f, 0.0f, 0.0f};
+        float listener_orientation[] = {0.0f, 0.0f, -1.0f, // direction
+                                        0.0f, 1.0f, 0.0f}; // up vector
+        alListenerfv(AL_POSITION, listener_pos);
+        alListenerfv(AL_VELOCITY, listener_vel);
+        alListenerfv(AL_ORIENTATION, listener_orientation);
+
+        alSourcei(buffer->source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);
+        alSourcePlay(buffer->source_id);
+        if (CheckError())
+          __debugbreak();
+
+        if (wait && !loop)
+        {
+          float track_length = alBufferLength(buffer->buffer_id);
+          do
+          {
+            float track_offset = 0;
+            alGetSourcef(buffer->source_id, AL_SEC_OFFSET, &track_offset);
+            log("playing: %.4f/%.4f\n", track_offset, track_length);
+
+            alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
+          }
+          while (status == AL_PLAYING);
+        }
+      }
+    }
+
+
+
+  protected:
+    ALCdevice    *device;
+    ALCcontext   *context;
+
+
+    bool CheckError()
+    {
+      ALenum code1 = alGetError();
+      if (code1 != AL_NO_ERROR)
+      {
+        DWORD w;
+        const char *message = alGetString(code1);
+        WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), message, lstrlenA(message), &w, nullptr);
+        WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), "\n", 1, &w, nullptr);
+        return true;
+      }
+
+      ALenum code2 = alcGetError(device);
+      if (code2 != ALC_NO_ERROR)
+      {
+        DWORD w;
+        const char *message = alcGetString(device, code2);
+        WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), message, lstrlenA(message), &w, nullptr);
+        WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), "\n", 1, &w, nullptr);
+        return true;
+      }
+      return false;
+    }
+};
\ No newline at end of file
--- a/OurMath.h	Thu Mar 27 23:28:54 2014 +0100
+++ b/OurMath.h	Thu Mar 27 23:30:02 2014 +0100
@@ -32,9 +32,8 @@
 int fixpoint_from_int(int lhv, int rhv);
 
 template <typename FloatType>
-inline int bankersRounding(
-  const FloatType& value
-  ) {
+inline int bankersRounding(const FloatType& value)
+{
     assert("Method unsupported for this type" && false);
     return value;
 }
--- a/Outdoor.cpp	Thu Mar 27 23:28:54 2014 +0100
+++ b/Outdoor.cpp	Thu Mar 27 23:30:02 2014 +0100
@@ -111,6 +111,7 @@
     pRenderer->DrawOutdoorSkyD3D();
     pRenderer->DrawBuildingsD3D();
     pRenderer->RenderTerrainD3D();
+    //pRenderer->DrawBezierTerrain();
   }
   /*else
   {
--- a/Render.cpp	Thu Mar 27 23:28:54 2014 +0100
+++ b/Render.cpp	Thu Mar 27 23:30:02 2014 +0100
@@ -228,7 +228,7 @@
 {
   int v6; // ecx@8
   struct Polygon *pTilePolygon; // ebx@8
-  float a3a;
+  float Light_tile_dist;
 
   //warning: the game uses CW culling by default, ccw is incosistent
   pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CCW);
@@ -263,12 +263,45 @@
       pGame->pIndoorCameraD3D->Project(&pTerrainVertices[z * 128 + x], 1, 0);
     }
   }
-//--------------------------------------------------------------------------------------------------------------------
-
-  //
-  for (unsigned int z = 0; z < 127; ++z)
-  {
-    for (unsigned int x = 0; x < 127; ++x)
+//-------(Отсечение невидимой части карты)------------------------------------------------------------------------------------------
+  float direction = pGame->pIndoorCameraD3D->sRotationY / 256;//direction of the camera(напрвление камеры)
+  //0-East(B)
+  //1-NorthEast(CB)
+  //2-North(C)
+  //3-WestNorth(CЗ)
+  //4-West(З)
+  //5-SouthWest(ЮЗ)
+  //6-South(Ю)
+  //7-SouthEast(ЮВ)
+  int Start_X, End_X, Start_Z, End_Z;
+  if ( direction >= 0 && direction < 1.0 )//East(B) - NorthEast(CB)
+  {
+    Start_X = pODMRenderParams->uMapGridCellX - 2, End_X = 127;
+    Start_Z = 0, End_Z = 127;
+  }
+  else if (direction >= 1.0 && direction < 3.0)//NorthEast(CB) - WestNorth(CЗ)
+  {
+      Start_X = 0, End_X = 127;
+      Start_Z = 0, End_Z = pODMRenderParams->uMapGridCellZ + 1;
+  }
+  else if (direction >= 3.0 && direction < 5.0)//WestNorth(CЗ) - SouthWest(ЮЗ)
+  {
+    Start_X = 0, End_X = pODMRenderParams->uMapGridCellX + 2;
+    Start_Z = 0, End_Z = 127;
+  }
+  else if ( direction >= 5.0 && direction < 7.0 )//SouthWest(ЮЗ) - //SouthEast(ЮВ)
+  {
+    Start_X = 0, End_X = 127;
+    Start_Z = pODMRenderParams->uMapGridCellZ - 2, End_Z = 127;
+  }
+  else//SouthEast(ЮВ) - East(B)
+  {
+    Start_X = pODMRenderParams->uMapGridCellX - 2, End_X = 127;
+    Start_Z = 0, End_Z = 127;
+  }
+  for (unsigned int z = Start_Z; z < End_Z; ++z)
+  {
+    for (unsigned int x = Start_X; x < End_X; ++x)
     {
       pTilePolygon = &array_77EC08[pODMRenderParams->uNumPolygons];
       pTilePolygon->flags = 0;
@@ -326,9 +359,10 @@
         norm = 0;
       else
         norm = &pTerrainNormals[norm_idx];
-      //pGame->pLightmapBuilder->StackLights_TerrainFace(norm, &a3a, array_50AC10, 4, 1);//Ritor1: slows
-      //pDecalBuilder->_49BE8A(pTilePolygon, norm, &a3a, array_50AC10, 4, 1);
-//-----------------------------------------------------------------------------------------------
+      //pGame->pLightmapBuilder->StackLights_TerrainFace(norm, &Light_tile_dist, array_50AC10, 4, 1);//Ritor1: slows
+      //pDecalBuilder->_49BE8A(pTilePolygon, norm, &Light_tile_dist, array_50AC10, 4, 1);
+      //unsigned int a5 = 4;
+//----------------------------------------------------------------------------
 
       ++pODMRenderParams->uNumPolygons;
       ++pODMRenderParams->field_44;
@@ -342,6 +376,49 @@
         memcpy(&array_50AC10[k], &array_73D150[k], sizeof(struct RenderVertexSoft));
         array_50AC10[k]._rhw = 1.0 / (array_73D150[k].vWorldViewPosition.x + 0.0000001000000011686097);
       }
+//---------Draw distance(Дальность отрисовки)-------------------------------
+      int temp =  pODMRenderParams->shading_dist_mist;
+      if ( draw_terrain_dist_mist )
+        pODMRenderParams->shading_dist_mist = 0x5000;
+      bool neer_clip = array_73D150[0].vWorldViewPosition.x < 8.0
+                    || array_73D150[1].vWorldViewPosition.x < 8.0
+                    || array_73D150[2].vWorldViewPosition.x < 8.0
+                    || array_73D150[3].vWorldViewPosition.x < 8.0;
+      bool far_clip = (double)pODMRenderParams->shading_dist_mist < array_73D150[0].vWorldViewPosition.x
+                   || (double)pODMRenderParams->shading_dist_mist < array_73D150[1].vWorldViewPosition.x
+                   || (double)pODMRenderParams->shading_dist_mist < array_73D150[2].vWorldViewPosition.x
+                   || (double)pODMRenderParams->shading_dist_mist < array_73D150[3].vWorldViewPosition.x;
+
+         /* int v33 = 0;
+          static stru154 static_sub_0048034E_stru_154;
+          pGame->pLightmapBuilder->std__vector_000004_size = 0;
+          if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 )
+          {
+            if ( neer_clip )
+              v33 = 3;
+            else
+              v33 = far_clip != 0 ? 5 : 0;
+            static_sub_0048034E_stru_154.ClassifyPolygon(norm, Light_tile_dist);
+            if ( pDecalBuilder->uNumDecals > 0 )
+              pDecalBuilder->ApplyDecals(31 - pTilePolygon->dimming_level, 4, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, *(float *)&v33, -1);
+          }
+          if ( stru_F8AD28.uNumLightsApplied > 0 )
+            pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, v33);*/
+
+      if ( !byte_4D864C || ~pGame->uFlags & 0x80 )
+      {
+        //if ( neer_clip ) //Ritor1: Даёт искажения на подъёме, возможно требуется ф-ция Безье
+        //{
+         // pTilePolygon->uNumVertices = ODM_NearClip(pTilePolygon->uNumVertices);
+         // ODM_Project(pTilePolygon->uNumVertices);
+        //}
+        if ( far_clip )
+        {
+          pTilePolygon->uNumVertices = ODM_FarClip(pTilePolygon->uNumVertices);
+          ODM_Project(pTilePolygon->uNumVertices);
+        }
+      }
+      pODMRenderParams->shading_dist_mist = temp;
 
 // check the transparency and texture (tiles) mapping (проверка прозрачности и наложение текстур (тайлов))----------------------
       bool transparent = false;
@@ -377,7 +454,6 @@
   }
 }
 
-
 //----- (004811A3) --------------------------------------------------------
 void Render::DrawBorderTiles(struct Polygon *poly)
 {
@@ -967,9 +1043,9 @@
           {
             if ( pRenderer->pRenderD3D && pRenderer->bUseColoredLights )
             {
-              v14 = decor_desc->uColoredLightRed;
-              v15 = decor_desc->uColoredLightGreen;
-              v16 = decor_desc->uColoredLightBlue;
+              v14 = 255;//decor_desc->uColoredLightRed;
+              v15 = 255;//decor_desc->uColoredLightGreen;
+              v16 = 255;//decor_desc->uColoredLightBlue;
             }
             else
             {
@@ -8466,109 +8542,160 @@
   bool current_vertices_flag; // edi@1
   bool next_vertices_flag; // [sp+Ch] [bp-24h]@6
   double t; // st6@10
-  int pNextVertices;
+  bool bFound;
+
+  bFound = false;
 
   if (!num_vertices)
     return 0;
-
-  memcpy(&array_50AC10[num_vertices], array_50AC10, sizeof(array_50AC10[0]));
-  current_vertices_flag = 0;
-  if ( array_50AC10[0].vWorldViewPosition.x >= 8.0 )
-    current_vertices_flag = 1;
+  for (uint i = 0; i < num_vertices; ++i)// есть ли пограничные вершины
+  {
+    if ( array_50AC10[i].vWorldViewPosition.x > 8.0 )
+    {
+      bFound = true;
+      break;
+    }
+  }
+  if ( !bFound )
+    return 0;
+
+  memcpy(&array_50AC10[num_vertices], &array_50AC10[0], sizeof(array_50AC10[0]));
+  current_vertices_flag = false;
+  next_vertices_flag = false;
+  if ( array_50AC10[0].vWorldViewPosition.x <= 8.0 )
+    current_vertices_flag = true;
+  //check for near clip plane(проверка по ближней границе)
+  //   
+  // v3.__________________. v0
+  //   |                  |
+  //   |                  |
+  //   |                  |
+  //  ----------------------- 8.0(near_clip - 8.0)
+  //   |                  |
+  //   .__________________.
+  //  v2                     v1
 
   int out_num_vertices = 0;
   for (int i = 0; i < num_vertices; ++i)
   {
-    next_vertices_flag = array_50AC10[i + 1].vWorldViewPosition.x >= 8.0;
-    if ( current_vertices_flag != next_vertices_flag )
-    {
-      if ( next_vertices_flag )
+    next_vertices_flag = array_50AC10[i + 1].vWorldViewPosition.x <= 8.0;//
+    if ( current_vertices_flag ^ next_vertices_flag )
+    {
+      if ( next_vertices_flag )//следующая вершина за ближней границей
       {
         //t = near_clip - v0.x / v1.x - v0.x    (формула получения точки пересечения отрезка с плоскостью)
         t = (8.0 - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i + 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x);
-        array_507D30[out_num_vertices].vWorldViewPosition.y = (array_50AC10[i + 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t + array_50AC10[i].vWorldViewPosition.y;
-        array_507D30[out_num_vertices].vWorldViewPosition.z = (array_50AC10[i + 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t + array_50AC10[i].vWorldViewPosition.z;
-        array_507D30[out_num_vertices].u = (array_50AC10[i + 1].u - array_50AC10[i].u) * t + array_50AC10[i].u;
-        array_507D30[out_num_vertices].v = (array_50AC10[i + 1].v - array_50AC10[i].v) * t + array_50AC10[i].v;
-      }
-      else
-      {
-        t = (8.0 - array_50AC10[i + 1].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i + 1].vWorldViewPosition.x);
-        array_507D30[out_num_vertices].vWorldViewPosition.y = (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i + 1].vWorldViewPosition.y) * t + array_50AC10[i + 1].vWorldViewPosition.y;
-        array_507D30[out_num_vertices].vWorldViewPosition.z = (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i + 1].vWorldViewPosition.z) * t + array_50AC10[i + 1].vWorldViewPosition.z;
-        array_507D30[out_num_vertices].u = (array_50AC10[i].u - array_50AC10[i + 1].u) * t + array_50AC10[i + 1].u;
-        array_507D30[out_num_vertices].v = (array_50AC10[i].v - array_50AC10[i + 1].v) * t + array_50AC10[i + 1].v;
-      }
-      array_507D30[out_num_vertices].vWorldViewPosition.x = 8.0;
-      array_507D30[out_num_vertices]._rhw = 1.0 / 8.0;
+        array_507D30[out_num_vertices].vWorldViewPosition.x = 8.0;
+        array_507D30[out_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i + 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t;
+        array_507D30[out_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i + 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t;
+        array_507D30[out_num_vertices].u = array_50AC10[i].u + (array_50AC10[i + 1].u - array_50AC10[i].u) * t;
+        array_507D30[out_num_vertices].v = array_50AC10[i].v + (array_50AC10[i + 1].v - array_50AC10[i].v) * t;
+        array_507D30[out_num_vertices]._rhw = 1.0 / 8.0;
+      }
+      else// текущая вершина за ближней границей
+      {
+        t = (8.0 - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i + 1].vWorldViewPosition.x);
+        array_507D30[out_num_vertices].vWorldViewPosition.x = 8.0;
+        array_507D30[out_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i + 1].vWorldViewPosition.y) * t;
+        array_507D30[out_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i + 1].vWorldViewPosition.z) * t;
+        array_507D30[out_num_vertices].u = array_50AC10[i].u + (array_50AC10[i].u - array_50AC10[i + 1].u) * t;
+        array_507D30[out_num_vertices].v = array_50AC10[i].v + (array_50AC10[i].v - array_50AC10[i + 1].v) * t;
+        array_507D30[out_num_vertices]._rhw = 1.0 / 8.0;
+      }
       //array_507D30[out_num_vertices]._rhw = 0x3E000000u;
       ++out_num_vertices;
     }
-    if ( next_vertices_flag )
-    {
-      pNextVertices = out_num_vertices++;
-      memcpy(&array_507D30[pNextVertices], &array_50AC10[i + 1], 0x30);
+    if ( !next_vertices_flag )
+    {
+      memcpy(&array_507D30[out_num_vertices], &array_50AC10[i + 1], sizeof(array_50AC10[i + 1]));
+      out_num_vertices++;
     }
     current_vertices_flag = next_vertices_flag;
   }
   return out_num_vertices >= 3 ? out_num_vertices : 0;
 }
+
 //----- (00424EE0) --------------------------------------------------------
 int ODM_FarClip(unsigned int uNumVertices)
 {
-  signed int previous_vertices_flag; // edi@1
+  bool current_vertices_flag; // [sp+Ch] [bp-28h]@6
+  bool next_vertices_flag; // edi@1
   double t; // st6@10
-  bool current_vertices_flag; // [sp+Ch] [bp-28h]@6
   signed int depth_num_vertices; // [sp+18h] [bp-1Ch]@1
-  int pNextVertices;
+  bool bFound;
   //Доп инфо "Программирование трёхмерных игр для windows" Ламот стр 910
 
-  memcpy(&array_50AC10[uNumVertices], array_50AC10, sizeof(array_50AC10[uNumVertices]));
+  bFound = false;
+
+  memcpy(&array_50AC10[uNumVertices], &array_50AC10[0], sizeof(array_50AC10[uNumVertices]));
   depth_num_vertices = 0;
-  previous_vertices_flag = 0;
-  if ( array_50AC10[0].vWorldViewPosition.x <= pODMRenderParams->shading_dist_mist )
-    previous_vertices_flag = 1;//предыдущая грань меньше границы видимости
+  current_vertices_flag = false;
+  if ( array_50AC10[0].vWorldViewPosition.x >= pODMRenderParams->shading_dist_mist )
+    current_vertices_flag = true;//настоящая вершина больше границы видимости
   if ( (signed int)uNumVertices <= 0 )
     return 0;
-  for ( uint i = 1; i <= uNumVertices; ++i )
-  {
-    current_vertices_flag = pODMRenderParams->shading_dist_mist >= array_50AC10[i].vWorldViewPosition.x;
-    if ( previous_vertices_flag != current_vertices_flag )//одна из граней за границей видимости
-    {
-      if ( current_vertices_flag )//текущая грань меньше границы видимости(предыдущая грань за пределами видимости)
-      {
-        //t = far_clip - v0.x / v1.x - v0.x    (формула получения точки пересечения отрезка с плоскостью)
-        t = (pODMRenderParams->shading_dist_mist - array_50AC10[i - 1].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i - 1].vWorldViewPosition.x);
-        array_507D30[depth_num_vertices].vWorldViewPosition.y = (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i - 1].vWorldViewPosition.y) * t + array_50AC10[i - 1].vWorldViewPosition.y;
-        array_507D30[depth_num_vertices].vWorldViewPosition.z = (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i - 1].vWorldViewPosition.z) * t + array_50AC10[i - 1].vWorldViewPosition.z;
-        array_507D30[depth_num_vertices].u = (array_50AC10[i].u - array_50AC10[i - 1].u) * t + array_50AC10[i - 1].u;
-        array_507D30[depth_num_vertices].v = (array_50AC10[i].v - array_50AC10[i - 1].v) * t + array_50AC10[i - 1].v;
-      }
-      else//предыдущая грань меньше границы видимости(текущая грань вышла за пределы видимости)
+  for (uint i = 0; i < uNumVertices; ++i)// есть ли пограничные вершины
+  {
+    if ( array_50AC10[i].vWorldViewPosition.x < pODMRenderParams->shading_dist_mist )
+    {
+      bFound = true;
+      break;
+    }
+  }
+  if ( !bFound )
+    return 0;
+  //check for far clip plane(проверка по дальней границе)
+  //   
+  // v3.__________________. v0
+  //   |                  |
+  //   |                  |
+  //   |                  |
+  //  ----------------------- 8192.0(far_clip - 0x2000)
+  //   |                  |
+  //   .__________________.
+  //  v2                     v1
+
+  for ( uint i = 0; i < uNumVertices; ++i )
+  {
+    next_vertices_flag = array_50AC10[i + 1].vWorldViewPosition.x >= pODMRenderParams->shading_dist_mist;
+    if ( current_vertices_flag ^ next_vertices_flag )//одна из граней за границей видимости
+    {
+      if ( next_vertices_flag )//следующая вершина больше границы видимости(настоящая вершина меньше границы видимости) - v3
+      {
+        //t = far_clip - v2.x / v3.x - v2.x (формула получения точки пересечения отрезка с плоскостью)
+        t = (pODMRenderParams->shading_dist_mist - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i + 1].vWorldViewPosition.x);
+        array_507D30[depth_num_vertices].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist;
+        //New_y = v2.y + (v3.y - v2.y)*t
+        array_507D30[depth_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i + 1].vWorldViewPosition.y) * t;
+        //New_z = v2.z + (v3.z - v2.z)*t
+        array_507D30[depth_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i + 1].vWorldViewPosition.z) * t;
+        array_507D30[depth_num_vertices].u = array_50AC10[i].u + (array_50AC10[i].u - array_50AC10[i + 1].u) * t;
+        array_507D30[depth_num_vertices].v = array_50AC10[i].v + (array_50AC10[i].v - array_50AC10[i + 1].v) * t;
+        array_507D30[depth_num_vertices]._rhw = 1.0 / pODMRenderParams->shading_dist_mist;
+      }
+      else//настоящая вершина больше границы видимости(следующая вершина меньше границы видимости) - v0
       {
         //t = far_clip - v1.x / v0.x - v1.x
-        t = (pODMRenderParams->shading_dist_mist - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i - 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x);
-        array_507D30[depth_num_vertices].vWorldViewPosition.y = (array_50AC10[i - 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t + array_50AC10[i].vWorldViewPosition.y;
-        array_507D30[depth_num_vertices].vWorldViewPosition.z = (array_50AC10[i - 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t + array_50AC10[i].vWorldViewPosition.z;
-        array_507D30[depth_num_vertices].u = (array_50AC10[i - 1].u - array_50AC10[i].u) * t + array_50AC10[i].u;
-        array_507D30[depth_num_vertices].v = (array_50AC10[i - 1].v - array_50AC10[i].v) * t + array_50AC10[i].v;
-      }
-      array_507D30[depth_num_vertices].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist;
-      array_507D30[depth_num_vertices]._rhw = 1.0 / pODMRenderParams->shading_dist_mist;
+        t = (pODMRenderParams->shading_dist_mist - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i + 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x);
+        array_507D30[depth_num_vertices].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist;
+        //New_y = (v0.y - v1.y)*t + v1.y
+        array_507D30[depth_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i + 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t;
+        //New_z = (v0.z - v1.z)*t + v1.z
+        array_507D30[depth_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i + 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t;
+        array_507D30[depth_num_vertices].u = array_50AC10[i].u + (array_50AC10[i + 1].u - array_50AC10[i].u) * t;
+        array_507D30[depth_num_vertices].v = array_50AC10[i].v + (array_50AC10[i + 1].v - array_50AC10[i].v) * t;
+        array_507D30[depth_num_vertices]._rhw = 1.0 / pODMRenderParams->shading_dist_mist;
+      }
       ++depth_num_vertices;
     }
-    if ( current_vertices_flag )//оба в границе видимости
-    {
-      pNextVertices = depth_num_vertices++;
-      memcpy(&array_507D30[pNextVertices], &array_50AC10[i], 0x30);
-      //array_507D30[pNextVertices]._rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001);
-      //array_507D30[pNextVertices].flt_2C = array_50AC10[i].flt_2C;
-    }
-    previous_vertices_flag = current_vertices_flag;
-  }
-  if ( depth_num_vertices < 3 )
-    return 0;
-  return depth_num_vertices;
+    if ( !next_vertices_flag )//оба в границе видимости
+    {
+      memcpy(&array_507D30[depth_num_vertices], &array_50AC10[i + 1], sizeof(array_507D30[depth_num_vertices]));
+      depth_num_vertices++;
+    }
+    current_vertices_flag = next_vertices_flag;
+  }
+  return depth_num_vertices >= 3 ? depth_num_vertices : 0;
 }
 
 //----- (0047840D) --------------------------------------------------------
--- a/Render.h	Thu Mar 27 23:28:54 2014 +0100
+++ b/Render.h	Thu Mar 27 23:30:02 2014 +0100
@@ -361,7 +361,7 @@
   void PrepareDecorationsRenderList_ODM();
   void DrawSpriteObjects_ODM();
   void TransformBillboardsAndSetPalettesODM();
-  //float DrawBezierTerrain();
+  float DrawBezierTerrain();
   void RenderTerrainD3D();
   void DrawTerrainD3D(int a1, int edx0, int a3, int unk4);
   //void DrawTerrainSW(int a1, int a2, int a3, int a4);
--- a/VideoPlayer.h	Thu Mar 27 23:28:54 2014 +0100
+++ b/VideoPlayer.h	Thu Mar 27 23:30:02 2014 +0100
@@ -220,13 +220,6 @@
 		}
 	}
 
-
-
-
-
-
-
-
 	void PlaySample(int num_channels, int sample_rate, int num_samples, void *samples)
 	{
 		//char msg[256];sprintf(msg, "chan %u rate %5u num %5u ptr %p\n", num_channels, sample_rate, num_samples, samples);
--- a/_deleted.cpp	Thu Mar 27 23:28:54 2014 +0100
+++ b/_deleted.cpp	Thu Mar 27 23:30:02 2014 +0100
@@ -2426,798 +2426,6 @@
   return result;
 }
 
-//----- (0047F5C6) --------------------------------------------------------
-float Render::DrawBezierTerrain()
-{
-  unsigned int pDirectionIndicator1; // ebx@1
-  unsigned int pDirectionIndicator2; // edi@1
-  unsigned int v2; // eax@1
-  int v3; // eax@3
-  int v4; // edi@3
-  int v5; // ebx@3
-  int v6; // esi@3
-  unsigned int v7; // eax@3
-  int v8; // eax@4
-  unsigned int v9; // eax@6
-  int v10; // eax@7
-  //int v11; // ebx@9
-  //int v12; // edi@9
-  int v13; // eax@21
-  int v14; // eax@31
-  int v15; // edi@33
-  int v16; // eax@34
-  int v17; // edx@34
-  int v18; // ebx@34
-  int v19; // eax@36
-  int v20; // eax@39
-  int v21; // ecx@43
-  //char v22; // zf@44
-  int v23; // ecx@47
-  //int v24; // edi@52
-  int v25; // eax@54
-  int v26; // ecx@54
-  int v27; // eax@56
-  int v28; // edx@60
-  int v29; // ecx@61
-  int v30; // ecx@64
-  int v31; // ecx@68
-  int v32; // eax@70
-  //int v33; // ecx@71
-  int v34; // eax@73
-  int v35; // ecx@77
-  int v36; // ecx@81
-  int v37; // ecx@86
-  int v38; // eax@88
-  int v39; // ecx@88
-  int v40; // eax@90
-  int v41; // edx@94
-  //int v42; // ecx@95
-  int v43; // ecx@98
-  int v44; // ecx@102
-  int v45; // eax@104
-  int v46; // eax@107
-  int v47; // ecx@111
-  int v48; // ecx@115
-  int v49; // edi@120
-  int v50; // eax@122
-  int v51; // ecx@122
-  int v52; // eax@124
-  int v53; // edx@128
-  int v54; // ecx@129
-  int v55; // ecx@132
-  int v56; // eax@139
-  int v57; // ecx@140
-  int v58; // eax@142
-  int v59; // ecx@146
-  //int v60; // ecx@147
-  int v61; // ecx@150
-  int v62; // ecx@155
-  int v63; // eax@157
-  int v64; // ecx@157
-  int v65; // eax@159
-  int v66; // edx@163
-  int v67; // ecx@164
-  int v68; // ecx@167
-  //int v69; // eax@173
-  int v70; // edi@178
-  //int v71; // eax@178
-  //int v72; // ecx@178
-  //int x; // ebx@180
-  //int v74; // eax@182
-  //int v75; // eax@184
-  IndoorCameraD3D *pIndoorCameraD3D_3; // ecx@184
-  int uStartZ; // ecx@184
-  int v79; // ebx@185
-  int v127; // esi@185
-  int v86; // edi@196
-  //int v87; // eax@196
-  //int v88; // ecx@196
-  //int v89; // eax@198
-  //int v90; // ecx@200
-  int v92; // ebx@203
-  //int v93; // ST08_4@204
-  int v97; // ST08_4@204
-  float result; // eax@212
-  //struct 
-  //{
-  int v106; // [sp+Ch] [bp-68h]@191
-  int v103; // [sp+10h] [bp-64h]@190
-  int v104; // [sp+12h] [bp-62h]@190
-  //} v102;
-  int v105; // [sp+1Ch] [bp-58h]@1
-  int v107; // [sp+20h] [bp-54h]@3
-  int uEndZ; // [sp+24h] [bp-50h]@3
-  int v108; // [sp+28h] [bp-4Ch]@9
-  int v109; // [sp+2Ch] [bp-48h]@9
-  int v110; // [sp+30h] [bp-44h]@9
-  int v111; // [sp+34h] [bp-40h]@3
-  int v112; // [sp+38h] [bp-3Ch]@6
-  IndoorCameraD3D *pIndoorCameraD3D_4; // [sp+3Ch] [bp-38h]@9
-  int v114; // [sp+40h] [bp-34h]@9
-  int v115; // [sp+44h] [bp-30h]@9
-  int v116; // [sp+48h] [bp-2Ch]@9
-  //int v117; // [sp+4Ch] [bp-28h]@9
-  int v118; // [sp+50h] [bp-24h]@9
-  int v119; // [sp+54h] [bp-20h]@1
-  int v120; // [sp+58h] [bp-1Ch]@1
-  int i; // [sp+5Ch] [bp-18h]@1
-  int v122; // [sp+60h] [bp-14h]@1
-  int v123; // [sp+64h] [bp-10h]@1
-  int v124; // [sp+68h] [bp-Ch]@1
-  int v125; // [sp+6Ch] [bp-8h]@9
-  int v126; // [sp+70h] [bp-4h]@9
-
-  v105 = pIndoorCamera->sRotationY / ((signed int)stru_5C6E00->uIntegerHalfPi / 2);//2
-  pDirectionIndicator1 = stru_5C6E00->uDoublePiMask & (stru_5C6E00->uIntegerDoublePi - pIndoorCamera->sRotationY);//1536
-  pDirectionIndicator2 = stru_5C6E00->uDoublePiMask & (stru_5C6E00->uIntegerPi + pDirectionIndicator1);//512
-  v124 = ((pIndoorCamera->uMapGridCellX << 16) + 3 * stru_5C6E00->Cos(stru_5C6E00->uDoublePiMask & (stru_5C6E00->uIntegerPi + pDirectionIndicator1))) >> 16;//88
-  v123 = ((pIndoorCamera->uMapGridCellZ << 16) + 3 * stru_5C6E00->Sin(pDirectionIndicator2)) >> 16;// 66
-  v120 = pODMRenderParams->outdoor_grid_band_3 + v124;//+- range X
-  v119 = pODMRenderParams->outdoor_grid_band_3 + v123;
-  v2 = pODMRenderParams->uCameraFovInDegrees + 15;//90
-  i = v124 - pODMRenderParams->outdoor_grid_band_3;
-  v122 = v123 - pODMRenderParams->outdoor_grid_band_3;
-
-  if ( v2 > 90 )
-    v2 = 90;
-  v3 = (v2 << 11) / 720;
-  v4 = stru_5C6E00->uDoublePiMask & (pDirectionIndicator1 - v3);
-  v5 = stru_5C6E00->uDoublePiMask & (v3 + pDirectionIndicator1);
-
-  v106 = stru_5C6E00->Cos(v4);
-  uEndZ = stru_5C6E00->Sin(v4);
-
-  v111 = stru_5C6E00->Cos(v5);
-  v6 = stru_5C6E00->Sin(v5);
-
-  v7 = v4 & stru_5C6E00->uPiMask;
-  if ( (v4 & stru_5C6E00->uPiMask) >= stru_5C6E00->uIntegerHalfPi )
-    v8 = -stru_5C6E00->pTanTable[stru_5C6E00->uIntegerPi - v7];
-  else
-    v8 = stru_5C6E00->pTanTable[v7];
-  v112 = abs(v8);
-
-  v9 = v5 & stru_5C6E00->uPiMask;
-  if ( (v5 & stru_5C6E00->uPiMask) >= stru_5C6E00->uIntegerHalfPi )
-    v10 = -stru_5C6E00->pTanTable[stru_5C6E00->uIntegerPi - v9];
-  else
-    v10 = stru_5C6E00->pTanTable[v9];
-  v108 = abs(v10);
-
-  //v11 = v124;
-  //v12 = v123;
-  v114 = 0;
-  v115 = 0;
-  pIndoorCameraD3D_4 = 0;
-  v125 = 0;
-  v126 = v124;
-  v118 = v123;
-
-  v110 = (v106 >= 0 ? 1: -1);//2 * (v106 >= 0) - 1;
-  v109 = (uEndZ >= 0 ? 1: -1);//2 * (v107 >= 0) - 1;
-  uEndZ = (v111 >= 0 ? 1: -1);//2 * (v111 >= 0) - 1;
-  v106 = (v6 >= 0 ? 1: -1);//2 * (v6 >= 0) - 1;
-
-  uint _i = 1;
-  uint j = 1;
-
-  terrain_76DDC8[0] = -1;
-  terrain_76DFC8[0] = -1;
-  terrain_76E1C8[0] = -1;
-  terrain_76E3C8[0] = -1;
-
-  for( uint _i = 1; _i < 128; _i++)
-  {
-    if ( v112 >= 0x10000 )
-    {
-      int v1, v2;
-      //v111 = 4294967296i64 / v112;
-      //v114 += v111;
-      //if ( v114 >= 65536 )
-      //{
-      //  v11 += v110;
-      //  v114 = (unsigned __int16)v114;
-      //}
-      //v12 += v109;
-    }
-    else
-    {
-      v124 += v110;
-      v115 += v112;
-      if ( v112 + v115 >= 65536 )
-      {
-        v123 += v109;
-        v115 = (unsigned __int16)v115;
-      }
-    }
-    if ( v124 < _i || v124 > v120 || v123 < v122 || v123 > v119 )
-      break;
-    //v13 = v116++;
-    terrain_76E3C8[_i] = v124;
-    terrain_76E1C8[_i] = v123;
-  }
-
-  for( j = 1; j < 128; j++ )
-  {
-    if ( v108 >= 65536 )
-    {
-      v111 = 4294967296i64 / v108;
-      v114 += v111;//
-      if ( v111 + v114 >= 65536 )
-      {
-        v126 += uEndZ;
-        v114 = (unsigned __int16)v114;//
-      }
-      v118 += v106;
-    }
-    else
-    {
-      v125 += v108;
-      v126 += uEndZ;
-      if ( v125 >= 65536 )
-      {
-        v118 += v106;
-        v125 = (unsigned __int16)v125;
-      }
-    }
-    //if ( v117 >= 128 )
-      //break;
-    if ( v126 < _i )
-      break;
-    if ( v126 > v120 )
-      break;
-    v14 = v118;
-    if ( v118 < v122 )
-      break;
-    if ( v118 > v119 )
-      break;
-    terrain_76DFC8[j] = v126;
-    terrain_76DDC8[j] = v14;
-  }
-  v16 = 0;
-  v126 = 0;
-  v17 = j - 1;
-  v18 = _i - 1;
-
-  switch ( v105 )
-  {
-    case 0:
-    case 7:
-    {
-      //v116 = terrain_76DFC8[v17];
-      if ( v120 > terrain_76DFC8[v17] )
-      {
-        v125 = v120;
-        memset32(terrain_76D9C8.data(), v119 + 1, 4 * (v120 - terrain_76DFC8[v17] + 1));
-        v19 = v120;
-        do
-          terrain_76DBC8[v126++] = v19--;
-        while ( v19 >= terrain_76DFC8[v17] );
-        if ( terrain_76DFC8[v17] == terrain_76DDC8[v17 + 127] )
-        {
-          do
-            v20 = terrain_76DDC8[v17-- -1];
-          while ( v20 == terrain_76DDC8[v17 -1] );
-        }
-        v16 = v126;
-        --v17;
-      }
-      if ( v17 < 0 )
-        v17 = 0;
-      v21 = terrain_76DFC8[v17];
-      while ( 1 )
-      {
-        v125 = terrain_76DFC8[v17];
-        if ( v21 < v124 )
-          break;
-        terrain_76DBC8[v16] = v21;
-        //v22 = terrain_76DDC8[v17] == 65535;
-        terrain_76D9C8[v16] = terrain_76DDC8[v17] + 1;
-        if ( terrain_76DDC8[v17] == 65535 )
-        {
-          terrain_76D9C8[v16] = v123 + 1;
-          break;
-        }
-        if ( !v17 )
-          break;
-        if ( terrain_76DFC8[v17] == terrain_76DDC8[v17 - 1] )
-        {
-          do
-            v23 = terrain_76DDC8[v17-- -1];
-          while ( v23 == terrain_76DDC8[v17 -1] );
-        }
-        --v17;
-        v21 = v125 - 1;
-        ++v16;
-      }
-      v16 = 0;
-      //v24 = terrain_76E3C8[v18];
-      v126 = 0;
-      if ( v120 > terrain_76E3C8[v18] )
-      {
-        v125 = v120;
-        memset32(terrain_76D5C8.data(), v122, 4 * (v120 - terrain_76E3C8[v18] + 1));
-        do
-        {
-          v25 = v126;
-          v26 = v125--;
-          ++v126;
-          terrain_76D7C8[v25] = v26;
-        }
-        while ( v125 >= terrain_76E3C8[v18] );
-        if ( terrain_76E3C8[v18] == terrain_76E1C8[v18 -1] )
-        {
-          do
-            v27 = terrain_76E1C8[v18-- -1];
-          while ( v27 == terrain_76E1C8[v18 -1] );
-        }
-        v16 = v126;
-        --v18;
-      }
-      if ( v18 < 0 )
-        v18 = 0;
-      v28 = terrain_76E3C8[v18];
-      while ( v28 >= v124 )
-      {
-        v29 = terrain_76E1C8[v18];
-        terrain_76D7C8[v16] = v28;
-        terrain_76D5C8[v16] = v29;
-        if ( v29 == 65535 )
-        {
-          v31 = v123;
-          terrain_76D5C8[v16] = v31;
-          break;
-        }
-        if ( !v18 )
-          break;
-        if ( terrain_76E3C8[v18] == terrain_76E1C8[v18 -1] )
-        {
-          do
-            v30 = terrain_76E1C8[v18-- -1];
-          while ( v30 == terrain_76E1C8[v18 -1] );
-        }
-        --v18;
-        --v28;
-        ++v16;
-      }
-      break;
-    }
-    case 1:
-    case 2:
-    {
-      //v116 = terrain_76DDC8[v17];
-      if ( v122 < terrain_76DDC8[v17] )
-      {
-        v106 = v122;
-        memset32(terrain_76DBC8.data(), v120 + 1, 4 * (terrain_76DDC8[v17] - v122 + 1));
-        for ( v32 = v122; v32 <= terrain_76DDC8[v17]; v32++)
-          terrain_76D9C8[v126++] = v32;
-        if ( terrain_76DDC8[v17] == terrain_76DBC8[v17 -1] )
-        {
-          do
-            v34 = terrain_76DBC8[v17-- -1];
-          while ( v34 == terrain_76DBC8[v17 -1] );
-        }
-        v16 = v126;
-        --v17;
-      }
-      if ( v17 < 0 )
-        v17 = 0;
-      v35 = terrain_76DDC8[v17];
-      v125 = terrain_76DDC8[v17];
-      while ( v35 <= v123 )
-      {
-        //v22 = terrain_76DFC8[v17] == 65535;
-        terrain_76DBC8[v16] = terrain_76DFC8[v17] + 1;
-        terrain_76D9C8[v16] = v125;
-        if ( terrain_76DFC8[v17] == 65535 )
-        {
-          terrain_76DBC8[v16] = v124 + 1;
-          break;
-        }
-        if ( !v17 )
-          break;
-        if ( terrain_76DDC8[v17] == terrain_76DBC8[v17 -1] )
-        {
-          do
-            v36 = terrain_76DBC8[v17-- -1];
-          while ( v36 == terrain_76DBC8[v17 -1] );
-        }
-        --v17;
-        ++v125;
-        v35 = v125;
-        ++v16;
-      }
-      v16 = 0;
-      v126 = 0;
-      v37 = terrain_76E1C8[v18];
-      if ( v122 < v37 )
-      {
-        v114 = v122;
-        memset32(terrain_76D7C8.data(), i, 4 * (v37 - v122 + 1));
-        do
-        {
-          v38 = v126;
-          v39 = v114;
-          ++v126;
-          ++v114;
-          terrain_76D5C8[v38] = v39;
-        }
-        while ( v114 <= terrain_76E1C8[v18] );
-        if ( terrain_76E1C8[v18] == terrain_76DFC8[v18 -1] )
-        {
-          do
-            v40 = terrain_76DFC8[v18-- -1];
-          while ( v40 == terrain_76DFC8[v18 -1] );
-        }
-        v16 = v126;
-        --v18;
-      }
-      if ( v18 < 0 )
-        v18 = 0;
-      v41 = terrain_76E1C8[v18];
-      while ( v41 <= v123 )
-      {
-        terrain_76D5C8[v16] = v41;
-        terrain_76D7C8[v16] = terrain_76E3C8[v18];
-        if ( terrain_76E3C8[v18] == 65535 )
-        {
-          terrain_76D7C8[v16] = v124;
-          break;
-        }
-        if ( !v18 )
-          break;
-        if ( terrain_76E1C8[v18] == terrain_76DFC8[v18 -1] )
-        {
-          do
-            v43 = terrain_76DFC8[v18-- -1];
-          while ( v43 == terrain_76DFC8[v18 -1] );
-        }
-        --v18;
-        ++v41;
-        ++v16;
-      }
-      break;
-    }
-    case 5:
-    case 6:
-    {
-      //v116 = terrain_76DDC8[v17];
-      if ( v119 > terrain_76DDC8[v17] )
-      {
-        v106 = v119;
-        memset32(terrain_76DBC8.data(), i, 4 * (v119 - terrain_76DDC8[v17] + 1));
-        for ( v45 = v119; v45 >= terrain_76DDC8[v17]; v45--)
-          terrain_76D9C8[v126++] = v45;
-        if ( terrain_76DDC8[v17] == terrain_76DBC8[v17 -1] )
-        {
-          do
-            v46 = terrain_76DBC8[v17-- -1];
-          while ( v46 == terrain_76DBC8[v17 -1] );
-        }
-        v16 = v126;
-        --v17;
-      }
-      if ( v17 < 0 )
-        v17 = 0;
-      v47 = terrain_76DDC8[v17];
-      v125 = terrain_76DDC8[v17];
-      while ( v47 >= v123 )
-      {
-        //v22 = terrain_76DFC8[v17] == 65535;
-        terrain_76DBC8[v16] = terrain_76DFC8[v17];
-        terrain_76D9C8[v16] = v125;
-        if ( terrain_76DFC8[v17] == 65535 )
-        {
-          terrain_76DBC8[v16] = v124;
-          break;
-        }
-        if ( !v17 )
-          break;
-        if ( terrain_76DDC8[v17] == terrain_76DBC8[v17 -1] )
-        {
-          do
-            v48 = terrain_76DBC8[v17-- -1];
-          while ( v48 == terrain_76DBC8[v17 -1] );
-        }
-        --v17;
-        --v125;
-        v47 = v125;
-        ++v16;
-      }
-      v16 = 0;
-      v49 = terrain_76E1C8[v18];
-      v126 = 0;
-      if ( v119 > v49 )
-      {
-        v125 = v119;
-        memset32(terrain_76D7C8.data(), v120 + 1, 4 * (v119 - v49 + 1));
-        do
-        {
-          v50 = v126;
-          v51 = v125--;
-          ++v126;
-          terrain_76D5C8[v50] = v51;
-        }
-        while ( v125 >= terrain_76E1C8[v18] );
-        if ( terrain_76E1C8[v18] == terrain_76DFC8[v18 -1] )
-        {
-          do
-            v52 = terrain_76DFC8[v18-- -1];
-          while ( v52 == terrain_76DFC8[v18 -1] );
-        }
-        v16 = v126;
-        --v18;
-      }
-      if ( v18 < 0 )
-        v18 = 0;
-      v53 = terrain_76E1C8[v18];
-      while ( v53 >= v123 )
-      {
-        v54 = terrain_76E3C8[v18];
-        terrain_76D5C8[v16] = v53;
-        terrain_76D7C8[v16] = v54 + 1;
-        if ( v54 == 65535 )
-        {
-          terrain_76D7C8[v16] = v124 + 1;
-          break;
-        }
-        if ( !v18 )
-          break;
-        if ( terrain_76E1C8[v18] == terrain_76DFC8[v18 -1] )
-        {
-          do
-            v55 = terrain_76DFC8[v18-- -1];
-          while ( v55 == terrain_76DFC8[v18 -1] );
-        }
-        --v18;
-        --v53;
-        ++v16;
-      }
-      break;
-    }
-    case 3:
-    case 4:
-    {
-      //v116 = terrain_76DFC8[v17];
-      if ( i < terrain_76DFC8[v17] )
-      {
-        v106 = i;
-        memset32(terrain_76D9C8.data(), v122, 4 * (terrain_76DFC8[v17] - i + 1));
-        v56 = i;
-        do
-        {
-          v57 = v126++;
-          terrain_76DBC8[v57] = v56++;
-        }
-        while ( v56 <= terrain_76DFC8[v17] );
-        if ( terrain_76DFC8[v17] == terrain_76DDC8[v17 -1] )
-        {
-          do
-            v58 = terrain_76DDC8[v17-- -1];
-          while ( v58 == terrain_76DDC8[v17 -1] );
-        }
-        v16 = v126;
-        --v17;
-      }
-      if ( v17 < 0 )
-        v17 = 0;
-      v59 = terrain_76DFC8[v17];
-      while ( 1 )
-      {
-        v125 = v59;
-        if ( v59 > v124 )
-          break;
-        terrain_76DBC8[v16] = v59;
-        //v60 = terrain_76DDC8[v17];
-        terrain_76D9C8[v16] = terrain_76DDC8[v17];
-        if ( terrain_76DDC8[v17] == 65535 )
-        {
-          terrain_76D9C8[v16] = v123;
-          break;
-        }
-        if ( !v17 )
-          break;
-        if ( terrain_76DFC8[v17] == terrain_76DDC8[v17 -1] )
-        {
-          do
-            v61 = terrain_76DDC8[v17-- -1];
-          while ( v61 == terrain_76DDC8[v17 -1] );
-        }
-        --v17;
-        v59 = v125 + 1;
-        ++v16;
-      }
-      v16 = 0;
-      v126 = 0;
-      v62 = terrain_76E3C8[v18];
-      if ( i < v62 )
-      {
-        v114 = i;
-        memset32(terrain_76D5C8.data(), v119 + 1, 4 * (v62 - i + 1));
-        do
-        {
-          v63 = v126;
-          v64 = v114;
-          ++v126;
-          ++v114;
-          terrain_76D7C8[v63] = v64;
-        }
-        while ( v114 <= terrain_76E3C8[v18] );
-        if ( terrain_76E3C8[v18] == terrain_76E1C8[v18 -1] )
-        {
-          do
-            v65 = terrain_76E1C8[v18-- -1];
-          while ( v65 == terrain_76E1C8[v18 -1] );
-        }
-        v16 = v126;
-        --v18;
-      }
-      if ( v18 < 0 )
-        v18 = 0;
-      v66 = terrain_76E3C8[v18];
-      while ( v66 <= v124 )
-      {
-        v67 = terrain_76E1C8[v18];
-        terrain_76D7C8[v16] = v66;
-        terrain_76D5C8[v16] = v67 + 1;
-        if ( terrain_76E1C8[v18] == 65535 )
-        {
-          v31 = v123 + 1;
-          terrain_76D5C8[v16] = v31;
-          break;
-        }
-        if ( !v18 )
-          break;
-        if ( terrain_76E3C8[v18] == terrain_76E1C8[v18 -1] )
-        {
-          do
-            v68 = terrain_76E1C8[v18-- -1];
-          while ( v68 == terrain_76E1C8[v18 -1] );
-        }
-        --v18;
-        ++v66;
-        ++v16;
-      }
-      break;
-    }
-    default:
-      break;
-  }
-  //v69 = v16 - 1;
-  ptr_801A08 = pVerticesSR_806210;
-  ptr_801A04 = pVerticesSR_801A10;
-  //v126 = v69;
-
-  if ( v105 && v105 != 7 && v105 != 3 && v105 != 4 )//блок
-  {
-    for ( i = v16 - 1; i >= 1; --i )
-    {
-      //v70 = i;
-      //v71 = terrain_76D7C8[i];//88
-      //v72 = terrain_76DBC8[i];//0
-      if ( terrain_76D7C8[i] < terrain_76DBC8[i] )//swap
-      {
-        terrain_76DBC8[i] = terrain_76D7C8[i];
-        terrain_76D7C8[i] = terrain_76DBC8[i];
-      }
-      //x = terrain_76DBC8[i];//0
-      v111 = 0;
-      if ( terrain_76DBC8[i] <= 0 )
-        terrain_76DBC8[i] = -terrain_76DBC8[i];
-      //v74 = terrain_76D7C8[i];
-      if ( terrain_76D7C8[i] <= 0 )
-        terrain_76D7C8[i] = -terrain_76D7C8[i];
-      uEndZ = terrain_76D7C8[i] + 2;
-      //pIndoorCameraD3D_3 = pGame->pIndoorCameraD3D;
-      //uEndZ = v75;
-      //pIndoorCameraD3D_4 = pIndoorCameraD3D_3;
-      uStartZ = terrain_76DBC8[i] - 2;
-      if ( terrain_76DBC8[i] - 2 < uEndZ )
-      {
-        v127 = 0;
-        //v79 = (v73 - 66) << 9;
-        //v116 = v77;
-        //pHeight = v79;
-        v111 = uEndZ - uStartZ;
-        for (int z = uStartZ; z < uEndZ; ++z)
-        {
-          ptr_801A08[v127].vWorldPosition.x = (-64 + terrain_76DBC8[i]) * 512;//pTerrainVertices[z * 128 + x].vWorldPosition.x = (-64 + (signed)x) * 512;
-          ptr_801A08[v127].vWorldPosition.y = (64 - terrain_76D9C8[i]) * 512;
-          ptr_801A08[v127].vWorldPosition.z = pOutdoor->GetHeightOnTerrain( z, terrain_76D9C8[i]);
-
-          ptr_801A04[v127].vWorldPosition.x = (-64 + terrain_76DBC8[i]) * 512;
-          ptr_801A04[v127].vWorldPosition.y = (63 - terrain_76D9C8[i]) * 512;
-          ptr_801A04[v127].vWorldPosition.z = pOutdoor->GetHeightOnTerrain( z, terrain_76D9C8[i] + 1);
-
-          if ( !byte_4D864C || !(pGame->uFlags & 0x80) )
-          {
-            pIndoorCameraD3D_4->ViewTransform(&ptr_801A08[v127], 1);
-            pIndoorCameraD3D_4->ViewTransform(&ptr_801A04[v127], 1);
-
-            pIndoorCameraD3D_4->Project(&ptr_801A08[v127], 1, 0);
-            pIndoorCameraD3D_4->Project(&ptr_801A04[v127], 1, 0);
-          }
-          //v79 += 512;
-          v127 ++;
-          //++v116;
-          //pHeight = v79;
-       }
-        //while ( v116 < v107 );
-      }
-      v103 = abs((int)pIndoorCamera->uMapGridCellZ - terrain_76D9C8[i]);
-      v104 = abs((int)pIndoorCamera->uMapGridCellX - terrain_76DBC8[i]);
-      if ( pRenderer->pRenderD3D )//Ritor1: do comment to test
-        Render::DrawTerrainD3D(v111, 0, v103, v104);
-        //Render::RenderTerrainD3D();
-      else
-        Render::DrawTerrainSW(v111, 0, v103, v104);
-    }
-  }
-  else
-  {
-    for ( i = v16 - 1; i >= 1; --i )
-    {
-      //v86 = i;
-      //v87 = terrain_76D5C8[i];
-      //v88 = terrain_76D9C8[i];
-      if ( terrain_76D5C8[i] < terrain_76D9C8[i] )
-      {
-        terrain_76D9C8[i] = terrain_76D5C8[i];
-        terrain_76D5C8[i] = terrain_76D9C8[i];
-      }
-      //v89 = terrain_76D9C8[i];
-      v111 = 0;
-      if ( terrain_76D9C8[i] <= 0 )
-        terrain_76D9C8[i] = -terrain_76D9C8[i];
-      //v90 = terrain_76D5C8[i];
-      if ( terrain_76D5C8[i] <= 0 )
-        terrain_76D5C8[i] = -terrain_76D5C8[i];
-      pIndoorCameraD3D_4 = pGame->pIndoorCameraD3D;
-      v107 = terrain_76D5C8[i] + 2;
-      if ( terrain_76D9C8[i] - 2 < terrain_76D5C8[i] + 2 )
-      {
-        v86 = 0;
-        //v116 = terrain_76D9C8[i] - 2;
-        v92 = (66 - terrain_76D9C8[i]) << 9;
-        //pHeight = (66 - terrain_76D9C8[i]) << 9;
-        v111 = terrain_76D5C8[i] + 2 - (terrain_76D9C8[i] - 2);
-        //do
-        for ( v116 = terrain_76D9C8[i] - 2; v116 < v107; ++v116 )
-        {
-          ptr_801A08[v86].vWorldPosition.x = (terrain_76DBC8[v86] - 64) << 9;
-          ptr_801A08[v86].vWorldPosition.y = v92;
-          ptr_801A08[v86].vWorldPosition.z = pOutdoor->GetHeightOnTerrain(terrain_76DBC8[v86], v116);
-
-          ptr_801A04[v86].vWorldPosition.x = (terrain_76DBC8[v86] - 63) << 9;
-          ptr_801A04[v86].vWorldPosition.y = v92;
-          ptr_801A04[v86].vWorldPosition.z = pOutdoor->GetHeightOnTerrain(terrain_76DBC8[v86] + 1, v116);
-          if ( !byte_4D864C || !(pGame->uFlags & 0x80) )
-          {
-           pIndoorCameraD3D_4->ViewTransform((RenderVertexSoft *)(char *)ptr_801A08 + v86, 1);
-           pIndoorCameraD3D_4->ViewTransform((RenderVertexSoft *)(char *)ptr_801A04 + v86, 1);
-           pIndoorCameraD3D_4->Project((RenderVertexSoft *)(char *)ptr_801A08 + v86, 1, 0);
-           pIndoorCameraD3D_4->Project((RenderVertexSoft *)(char *)ptr_801A04 + v86, 1, 0);
-          }
-          v92 -= 512;
-          v86 += 48;
-          //++v116;
-          //pHeight = v92;
-        }
-        //while ( v116 < v107 );
-      }
-      v103 = abs((int)pIndoorCamera->uMapGridCellX - terrain_76DBC8[v86]);
-	  v104 = abs((int)pIndoorCamera->uMapGridCellZ - terrain_76D9C8[v86]);
-	  if ( pRenderer->pRenderD3D )
-        Render::DrawTerrainD3D(v111, 1, v103, v104);
-      else
-        Render::DrawTerrainSW(v111, 1, v103, v104);
-    }
-  }
-  result = v126;
-  pODMRenderParams->field_40 = v126;
-  return result;
-}
 //----- (00482E07) --------------------------------------------------------
 signed int __fastcall sr_sub_482E07(Span *ecx0, unsigned __int16 *pRenderTarget)
 {
@@ -8529,589 +7737,7 @@
   return result;
 }
 
-//----- (0048034E) --------------------------------------------------------
-void Render::DrawTerrainD3D(int a1, int a2, int a3, int unk4)
-{
-  //int v3; // esi@1
-  int v4; // edi@1
-  int v5; // ebx@2
-  int v6; // eax@2
-  int v7; // eax@3
-  RenderVertexSoft *v8; // edi@3
-  RenderVertexSoft *v9; // ebx@4
-  RenderVertexSoft *v10; // ecx@4
-  float v11; // eax@6
-  double v12; // ST5C_8@6
-  double v13; // ST2C_8@6
-  int v14; // eax@6
-  double v15; // st7@6
-  struct Polygon *pTile; // ebx@12
-  unsigned __int16 v17; // ax@12
-  int v18; // eax@13
-  signed int v22; // eax@13
-  Vec3_float_ *norm; // eax@15
-  //double v24; // st6@17
-  double v25; // ST54_8@17
-  unsigned __int8 v26; // sf@17
-  unsigned __int8 v27; // of@17
-  double v28; // st5@19
-  double v29; // st5@19
-  double v30; // st5@19
-  double v31; // st5@19
-  struct struct8 *v32; // esi@21
-  double v3a; // st7@32
-  int v33; // edi@38
-  unsigned int v34; // ecx@47
-  char v35; // zf@47
-  unsigned int v36; // eax@50
-  int v37; // eax@54
-  //Polygon *v38; // ecx@55
-  unsigned int v39; // eax@59
-  struct Polygon *v40; // ebx@62
-  unsigned __int16 pTileBitmapsID; // ax@62
-  int v42; // eax@63
-  LightmapBuilder *v43; // ecx@63
-  int v44; // eax@63
-  int v45; // eax@63
-  int v46; // eax@63
-  signed int v47; // eax@63
-  Vec3_float_ *v48; // eax@65
-  double v49; // st6@67
-  double v50; // ST4C_8@67
-  double v51; // st5@71
-  double v52; // st5@71
-  double v53; // st5@71
-  double v54; // st7@84
-  unsigned int v55; // ecx@98
-  unsigned int v56; // eax@101
-  int v57; // eax@105
-  unsigned int v58; // eax@109
-  struct Polygon *v59; // esi@112
-  unsigned __int16 v60; // ax@112
-  int v61; // eax@113
-  signed int v62; // eax@113
-  Vec3_float_ *v63; // eax@114
-  double v64; // st6@116
-  double v65; // ST3C_8@116
-  double v66; // st5@120
-  double v67; // st5@120
-  double v68; // st5@120
-  double v69; // st7@133
-  int v70; // edi@138
-  struct Polygon *v71; // esi@147
-  unsigned int v72; // ecx@147
-  unsigned int v73; // eax@150
-  int v74; // eax@154
-  unsigned int v75; // eax@158
-  //unsigned int v76; // [sp-10h] [bp-E0h]@61
-  int v77; // [sp-Ch] [bp-DCh]@61
-  IDirect3DTexture2 *v78; // [sp-8h] [bp-D8h]@61
-  //int v79; // [sp-4h] [bp-D4h]@61
-  bool v80; // [sp+0h] [bp-D0h]@59
-  bool v81; // [sp+0h] [bp-D0h]@109
-  int v82; // [sp+54h] [bp-7Ch]@1
-  int v83; // [sp+60h] [bp-70h]@1
-  int v84; // [sp+6Ch] [bp-64h]@1
-  int v85; // [sp+70h] [bp-60h]@63
-  float a4; // [sp+74h] [bp-5Ch]@73
-  float v87; // [sp+78h] [bp-58h]@122
-  int v88; // [sp+7Ch] [bp-54h]@1
-  int v89; // [sp+80h] [bp-50h]@6
-  int v93; // [sp+90h] [bp-40h]@2
-  int X; // [sp+94h] [bp-3Ch]@1
-  float v95; // [sp+98h] [bp-38h]@21
-  LightmapBuilder *v96; // [sp+9Ch] [bp-34h]@73
-  int v97; // [sp+A0h] [bp-30h]@6
-  int sX; // [sp+A4h] [bp-2Ch]@6
-  unsigned int uNumVertices; // [sp+A8h] [bp-28h]@73
-  int v100; // [sp+ACh] [bp-24h]@122
-  int sY; // [sp+B0h] [bp-20h]@6
-  RenderVertexSoft *v102; // [sp+B4h] [bp-1Ch]@3
-  unsigned int a5; // [sp+B8h] [bp-18h]@21
-  RenderVertexSoft *v101; // [sp+BCh] [bp-14h]@6
-  Vec3_float_ *v99; // [sp+C0h] [bp-10h]@17
-  RenderVertexSoft *pVertices; // [sp+C4h] [bp-Ch]@6
-  RenderVertexSoft *pVertices2; // [sp+C8h] [bp-8h]@6
-  char v108; // [sp+CFh] [bp-1h]@36
-  float thisd; // [sp+D8h] [bp+8h]@6
-  float thise; // [sp+D8h] [bp+8h]@6
-  float thisf; // [sp+D8h] [bp+8h]@17
-  IndoorCameraD3D *thisa; // [sp+D8h] [bp+8h]@23
-  float thisg; // [sp+D8h] [bp+8h]@67
-  IndoorCameraD3D *thisb; // [sp+D8h] [bp+8h]@75
-  float thish; // [sp+D8h] [bp+8h]@116
-  IndoorCameraD3D *thisc; // [sp+D8h] [bp+8h]@124
-  char this_3; // [sp+DBh] [bp+Bh]@30
-  char this_3a; // [sp+DBh] [bp+Bh]@82
-  char this_3b; // [sp+DBh] [bp+Bh]@131
-
-  __debugbreak();
-  static stru154 static_sub_0048034E_stru_154;
-  static stru154 stru_76D5A8;
-  //v3 = a1;
-  v82 = a2;
-  v83 = a3;
-  X = abs(unk4);
-  v4 = 0;
-  v88 = 0;
-  v84 = a1 - 1;
-  if ( a1 - 1 > 0 )
-  {
-    while ( 1 )
-    {
-      v5 = abs(X);//v5 = 13108
-      v6 = abs(v83);//v6 = 13108
-      --X;
-      //__debugbreak(); // uncoment & refactor following large if
-      v93 = (int)&terrain_76E5C8[(v5 << 7) + v6];
-      if ( !v93->field_0 || ((v7 = 48 * v4, v8 = &pVerticesSR_806210[v4], a2 = v8, !v82) ? (v9 = (RenderVertexSoft *)((char *)&pVerticesSR_801A10 + v7),
-                                                                       v10 = &pVerticesSR_806210[1] + v7) : (v9 = &pVerticesSR_806210[1] + v7, v10 = (RenderVertexSoft *)((char *)&pVerticesSR_801A10 + v7)),
-             ((a8 = v9,
-               pVertices = &pVerticesSR_801A10[1] + v7,
-               v11 = v8->vWorldPosition.x,
-               v101 = v10,
-               v12 = v11 + 6.755399441055744e15,
-               sX = LODWORD(v12),
-               v13 = v8->vWorldPosition.y + 6.755399441055744e15,
-               sY = LODWORD(v13),
-               thisd = (v10->vWorldPosition.x + v8->vWorldPosition.x) * 0.5,
-               v14 = WorldPosToGridCellX(floorf(thisd + 0.5f)),//maybe current camera position X
-               v15 = v9->vWorldPosition.y + v8->vWorldPosition.y,
-               v89 = v14,
-               thise = v15 * 0.5,
-               _this = (LightmapBuilder *)WorldPosToGridCellZ(floorf(thisd + 0.5f)),//maybe current camera position Z
-               WorldPosToGridCellX(sX),
-               WorldPosToGridCellZ(sY),
-               !byte_4D864C)
-           || !(pGame->uFlags & 0x80))
-          && !_481EFA_clip_terrain_poly(v8, v9, v101, pVertices, 1)) )
-      if ( !&terrain_76E5C8[(v5 << 7) + v6] )
-        goto LABEL_162
-      v8 = &pVerticesSR_806210[v4];
-      //pVertices2 = &pVerticesSR_801A10[v4 + 1];
-      //v102 = v8;
-      if (!v82)
-      {
-        pVertices = &pVerticesSR_801A10[v4];
-        v101 = &pVerticesSR_806210[v4 + 1];
-      }
-      else
-      {
-        pVertices = &pVerticesSR_801A10[v4 + 1];
-        v101 = &pVerticesSR_806210[v4];
-      }
-      sX = floorf(v8->vWorldPosition.x + 0.5f);
-      sY = floorf(v8->vWorldPosition.z + 0.5f);
-      v89 = WorldPosToGridCellX(floorf((v101->vWorldPosition.x + v8->vWorldPosition.x) / 2 + 0.5f));
-      v97 = WorldPosToGridCellZ(floorf((pVertices->vWorldPosition.z + v8->vWorldPosition.z) / 2 + 0.5f));
-      /*WorldPosToGridCellX(sX);
-      WorldPosToGridCellZ(sY);
-      if ((!byte_4D864C || !(pGame->uFlags & 0x80)) && !_481EFA_clip_terrain_poly(v8, pVertices, v101, pVertices2, 1))
-        if ( v8->vWorldPosition.y != pVertices->vWorldPosition.y || pVertices->vWorldPosition.y != pVertices2->vWorldPosition.y 
-             || pVertices2->vWorldPosition.y != v101->vWorldPosition.y )
-          break;
-        pTile = &array_77EC08[pODMRenderParams->uNumPolygons];
-        pTile->uTileBitmapID = pOutdoor->GetTileTexture(sX, sY);
-        if ( pTile->uTileBitmapID != -1 )
-        {
-          pTile->flags = 0x8010 |pOutdoor->GetSomeOtherTileInfo(sX, sY);
-          pTile->field_32 = 0;
-          pTile->field_59 = 1;
-          pTile->terrain_grid_x = (char)v97;
-          __debugbreak(); // warning C4700: uninitialized local variable 'v93' used
-          pTile->field_34 = *(_WORD *)(v93 + 2);
-          pTile->terrain_grid_z = v89;
-          v22 = pTerrainNormalIndices[2 * (v97 + 128 * v89) + 1];
-          if ( v22 < 0 || v22 > uNumTerrainNormals - 1 )
-            norm = 0;
-          else
-            norm = &pTerrainNormals[v22];
-          thisf = 20.0 - ( -(((float)pOutdoor->vSunlight.x / 65536.0) * norm->x) -
-                            (((float)pOutdoor->vSunlight.y / 65536.0) * norm->y) -
-                            (((float)pOutdoor->vSunlight.z / 65536.0) * norm->z)) * 20.0;
-          //v25 = thisf + 6.7553994e15;
-          //v27 = pODMRenderParams->uNumPolygons > 1999;
-          //v26 = pODMRenderParams->uNumPolygons - 1999 < 0;
-          pTile->dimming_level = floorf(thisf + 0.5f);
-          if ( pODMRenderParams->uNumPolygons >= 1999 )
-            return;
-          ++pODMRenderParams->uNumPolygons;
-          //if ( !_481FC9_terrain(v8, pVertices, v101, v16) )//Ritor1: It's temporary
-          //goto LABEL_126;
-          //{
-            //--pODMRenderParams->uNumPolygons;
-            //goto LABEL_162;
-          //}
-          __debugbreak(); // warning C4700: uninitialized local variable 'v102' used
-          memcpy(&array_50AC10[0], v102, 0x30u);
-          array_50AC10[0]._rhw = 1.0 / (v102->vWorldViewPosition.x + 0.0000001000000011686097);
-          array_50AC10[0].u = 0.0;
-          array_50AC10[0].v = 0.0;
-          memcpy(&array_50AC10[1], pVertices, sizeof(array_50AC10[1]));
-          array_50AC10[1]._rhw = 1.0 / (pVertices->vWorldViewPosition.x + 0.0000001000000011686097);
-          array_50AC10[1].u = 0.0;
-          array_50AC10[1].v = 1.0;
-          __debugbreak(); // warning C4700: uninitialized local variable 'pVertices2' used
-          memcpy(&array_50AC10[2], pVertices2, sizeof(array_50AC10[2]));
-          array_50AC10[2]._rhw = 1.0 / (pVertices2->vWorldViewPosition.x + 0.0000001000000011686097);
-          array_50AC10[2].u = 1.0;
-          array_50AC10[2].v = 1.0;
-          memcpy(&array_50AC10[3], v101, sizeof(array_50AC10[3]));
-          array_50AC10[3]._rhw = 1.0 / (v101->vWorldViewPosition.x + 0.0000001000000011686097);
-          array_50AC10[3].u = 1.0;
-          array_50AC10[3].v = 0.0;
-          if ( !(_76D5C0_static_init_flag & 1) )
-          {
-            _76D5C0_static_init_flag |= 1u;
-            stru154(stru_76D5A8);
-            atexit(loc_481199);
-          }
-          v32 = (struct8 *)array_50AC10;
-          v97 = (int)pGame->pLightmapBuilder;
-          pGame->pLightmapBuilder->StackLights_TerrainFace(norm, &v95, array_50AC10, 4, 1);
-          pDecalBuilder->_49BE8A(pTile, norm, &v95, array_50AC10, 4, 1);
-          a5 = 4;
-          if ( byte_4D864C && pGame->uFlags & 0x80 )
-          {
-            thisa = pGame->pIndoorCameraD3D;
-            if ( pGame->pIndoorCameraD3D->_4371C3(array_50AC10, &a5, 0) == 1 && !a5 )
-              goto LABEL_162;
-            thisa->ViewTransform(array_50AC10, a5);
-            thisa->Project(array_50AC10, a5, 0);
-          }
-          this_3 = v102->vWorldViewPosition.x < 8.0 || pVertices->vWorldViewPosition.x < 8.0
-              || v101->vWorldViewPosition.x < 8.0 || pVertices2->vWorldViewPosition.x < 8.0;
-          v3a = (double)pODMRenderParams->shading_dist_mist;
-          v108 = v3a < v102->vWorldViewPosition.x || v3a < pVertices->vWorldViewPosition.x
-              || v3a < v101->vWorldViewPosition.x || v3a < pVertices2->vWorldViewPosition.x;
-          v33 = 0;
-          pGame->pLightmapBuilder->std__vector_000004_size = 0;
-          if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 )
-          {
-            if ( this_3 )
-              v33 = 3;
-            else
-              v33 = v108 != 0 ? 5 : 0;
-            static_sub_0048034E_stru_154.ClassifyPolygon(norm, v95);
-            if ( pDecalBuilder->uNumDecals > 0 )
-              pDecalBuilder->ApplyDecals(31 - pTile->dimming_level, 4, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, *(float *)&v33, -1);
-          }
-          if ( stru_F8AD28.uNumLightsApplied > 0 )
-            pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, v33);
-          v34 = a5;
-          //v35 = byte_4D864C == 0;
-          pTile->uNumVertices = a5;
-          if ( !byte_4D864C || ~pGame->uFlags & 0x80 )
-          {
-            if ( this_3 )
-            {
-              v36 = ODM_NearClip(v34);
-              pTile->uNumVertices = v36;
-              ODMRenderParams::Project(v36);
-            }
-            if ( v108 )
-            {
-              v36 = sr_424EE0_MakeFanFromTriangle(v34);
-              pTile->uNumVertices = v36;
-              ODMRenderParams::Project(v36);
-            }
-          }
-          //v37 = *(int *)&v16->flags;
-          if ( ~pTile->flags & 1 )
-          {
-            if ( pTile->flags & 2 && pTile->uTileBitmapID == pRenderer->hd_water_tile_id )
-            {
-              v80 = false;
-              v39 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame];
-            }
-            else
-            {
-              v39 = pTile->uTileBitmapID;
-              v80 = true;
-            }
-            //v79 = 0;
-            //v78 = pBitmaps_LOD->pHardwareTextures[v39];
-            pTile->pTexture = (Texture *)&pBitmaps_LOD->pHardwareTextures[v39];// Ritor1: It's temporary
-            v77 = (int)pTile;
-            //v76 = v16->uNumVertices;
-//LABEL_161:
-            pRenderer->DrawTerrainPolygon(pTile->uNumVertices, pTile, pBitmaps_LOD->pHardwareTextures[v39], false, v80);
-            goto LABEL_162;
-          }
-LABEL_56:
-          pTile->DrawBorderTiles();
-        }
-LABEL_162:
-        v4 = v88 + 1;
-        if ( ++v88 >= v84 )
-          return;
-      }
-      v40 = &array_77EC08[pODMRenderParams->uNumPolygons];
-      v40->uTileBitmapID = pOutdoor->GetTileTexture(sX, sY);
-      if ( v40->uTileBitmapID == -1 )
-        goto LABEL_162;
-      v42 = pOutdoor->GetSomeOtherTileInfo(sX, sY);
-      BYTE1(v42) |= 0x80u;
-      v43 = pGame->pLightmapBuilder;
-      *(int *)&v40->flags = v42;
-      v44 = v93;
-      v40->field_59 = 1;
-      v40->terrain_grid_x = (char)v43;
-      v40->field_34 = *(_WORD *)(v44 + 2);
-      v45 = v89;
-      v40->terrain_grid_z = v89;
-      v46 = 4 * ((char)v43 + (v45 << 7));
-      v85 = v46;
-      v47 = *(unsigned __int16 *)((char *)pTerrainNormalIndices + v46 + 2);//    v47 = pTerrainNormalIndices[v46 + 1];
-      if ( v47 < 0 || v47 > (signed int)(uNumTerrainNormals - 1) )
-        v48 = 0;
-      else
-        v48 = &pTerrainNormals[v47];
-      v49 = v92 * v48->y;
-      //v99 = v48;
-      thisg = 20.0 - (-v49 - v91 * v48->z - v90 * v48->x) * 20.0;
-      v50 = thisg + 6.755399441055744e15;
-      v40->dimming_level = LOBYTE(v50);
-      if ( LOBYTE(v50) < 0 )
-        v40->dimming_level = 0;
-      if ( pODMRenderParams->uNumPolygons >= 1999 )
-        return;
-      ++pODMRenderParams->uNumPolygons;
-      if ( !_481FC9_terrain(pVertices, pVertices2, v8, v40) ) // Ritor1: It's temporary
-        //goto LABEL_77;
-        {
-          --pODMRenderParams->uNumPolygons;
-          goto LABEL_112;
-        }
-      memcpy(&array_50AC10[0], v102, 0x30u);
-      array_50AC10[0]._rhw = 1.0 / (v102->vWorldViewPosition.x + 0.0000001000000011686097);
-      array_50AC10[0].u = 0.0;
-      array_50AC10[0].v = 0.0;
-      memcpy(&array_50AC10[1], pVertices, sizeof(array_50AC10[1]));
-      array_50AC10[1]._rhw = 1.0 / pVertices->vWorldViewPosition.x + 0.0000001000000011686097;
-      array_50AC10[1].u = 0.0;
-      array_50AC10[1].v = 1.0;
-      memcpy(&array_50AC10[2], pVertices2, sizeof(array_50AC10[2]));
-      array_50AC10[2]._rhw = 1.0 / pVertices2->vWorldViewPosition.x + 0.0000001000000011686097;
-      array_50AC10[2].u = 1.0;
-      array_50AC10[2].v = 1.0;
-      static stru154 static_sub_0048034E_stru_76D590;
-      static bool __init_flag2 = false;
-      if (!__init_flag2)
-      {
-        __init_flag2 = true;
-        stru154::stru154(&static_sub_0048034E_stru_76D590);
-      }
-      if ( !(_76D5C0_static_init_flag & 2) )
-      {
-        _76D5C0_static_init_flag |= 2;
-        Polygon(stru_76D590);
-        atexit(loc_48118F);
-      }
-      v96 = pGame->pLightmapBuilder;
-      pGame->pLightmapBuilder->StackLights_TerrainFace(v48, (float *)&a4, array_50AC10, 3, 0);
-      pDecalBuilder->_49BE8A(v40, v48, &a4, array_50AC10, 3, 0);
-      uNumVertices = 3;
-      if ( byte_4D864C && pGame->uFlags & 0x80 )
-      {
-        thisb = pGame->pIndoorCameraD3D;
-        if ( pGame->pIndoorCameraD3D->_4371C3(array_50AC10, &uNumVertices, 0) == 1 && !uNumVertices )
-        {
-//LABEL_77:
-          --pODMRenderParams->uNumPolygons;
-          goto LABEL_112;
-        }
-        thisb->ViewTransform(array_50AC10, uNumVertices);
-        thisb->Project(array_50AC10, uNumVertices, 0);
-      }
-      this_3a = v102->vWorldViewPosition.x < 8.0 || pVertices->vWorldViewPosition.x < 8.0 || pVertices2->vWorldViewPosition.x < 8.0;
-      v54 = (double)pODMRenderParams->shading_dist_mist;
-      v108 = v54 < v102->vWorldViewPosition.x || v54 < pVertices->vWorldViewPosition.x || v54 < pVertices2->vWorldViewPosition.x;
-      pVertices = 0;
-      v96->std__vector_000004_size = 0;
-      if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 )
-      {
-        if ( this_3a )
-          pVertices = (RenderVertexSoft *)3;
-        else
-          pVertices = (RenderVertexSoft *)(v108 != 0 ? 5 : 0);
-        //a8 = (RenderVertexSoft *)(this_3a ? 3 : v108 != 0 ? 5 : 0);
-        static_sub_0048034E_stru_76D590.ClassifyPolygon(v48, *(float *)&a4);
-        if ( pDecalBuilder->uNumDecals > 0 )
-          pDecalBuilder->ApplyDecals(31 - v40->dimming_level, 4, &static_sub_0048034E_stru_76D590, uNumVertices, array_50AC10, 0, (char)pVertices, -1);
-      }
-      if ( stru_F8AD28.uNumLightsApplied > 0 )
-        v96->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_76D590, uNumVertices, array_50AC10, 0, (char)pVertices);
-      v55 = uNumVertices;
-      //v35 = byte_4D864C == 0;
-      v40->uNumVertices = uNumVertices;
-      if ( !_76D5C0_static_init_flag || !(pGame->uFlags & 0x80) )
-      {
-        if ( this_3a )
-        {
-          v56 = ODM_NearClip(v55);
-        }
-        else
-        {
-          if ( !v108 )
-            goto LABEL_105;
-          v56 = sr_424EE0_MakeFanFromTriangle(v55);
-        }
-        v40->uNumVertices = v56;
-        ODMRenderParams::Project(v56);
-      }
-LABEL_105:
-      v57 = *(int *)&v40->flags;
-      if ( BYTE1(v57) & 1 )
-      {
-        v40->DrawBorderTiles();
-      }
-      else
-      {
-        if ( v57 & 2 && v40->uTileBitmapID == pRenderer->hd_water_tile_id )
-        {
-          v81 = false;
-          v58 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame];
-        }
-        else
-        {
-          v58 = v40->uTileBitmapID;
-          v81 = true;
-        }
-        pRenderer->DrawTerrainPolygon(v40->uNumVertices, v40, pBitmaps_LOD->pHardwareTextures[v58], 0, v81);
-      }
-LABEL_112:
-      v59 = &array_77EC08[pODMRenderParams->uNumPolygons];
-      //a8 = (RenderVertexSoft *)&array_77EC08[pODMRenderParams->uNumPolygons];
-      v59->uTileBitmapID = pOutdoor->GetTileTexture(sX, sY);
-      if ( v59->uTileBitmapID  == -1 )
-        goto LABEL_162;
-      *(int *)&v59->flags = pOutdoor->GetSomeOtherTileInfo(sX, sY);
-      v61 = v93;
-      v59->field_59 = 1;
-      v59->field_34 = *(_WORD *)(v61 + 2);
-      v59->terrain_grid_z = v89;
-      v59->terrain_grid_x = v97;
-      v62 = *(unsigned __int16 *)((char *)pTerrainNormalIndices + v85);
-      if ( v62 > (signed int)(uNumTerrainNormals - 1) )
-        v63 = 0;
-      else
-        v63 = &pTerrainNormals[v62];
-      v64 = v92 * v63->y;
-      //v99 = v63;
-      thish = 20.0 - (-v64 - v91 * v63->y - v90 * v63->x) * 20.0;
-      v59->dimming_level = floorf(thish + 0.5f);
-      if ( v59->dimming_level < 0 )
-        v59->dimming_level = 0;
-      if ( pODMRenderParams->uNumPolygons >= 1999 )
-        return;
-      ++pODMRenderParams->uNumPolygons;
-      if ( !_481FC9_terrain(v101, v102, pVertices2, v59) )
-      {
-//LABEL_126:
-        --pODMRenderParams->uNumPolygons;
-        goto LABEL_162;
-      }
-      memcpy(&array_50AC10[0], v102, 0x30u);
-      array_50AC10[0]._rhw = 1.0 / (v102->vWorldViewPosition.x + 0.0000001000000011686097);
-      array_50AC10[0].u = 0.0;
-      array_50AC10[0].v = 0.0;
-      memcpy(&array_50AC10[1], pVertices2, sizeof(array_50AC10[1]));
-      array_50AC10[1]._rhw = 1.0 / pVertices2->vWorldViewPosition.x + 0.0000001000000011686097;
-      array_50AC10[1].u = 1.0;
-      array_50AC10[1].v = 1.0;
-      memcpy(&array_50AC10[2], v101, sizeof(array_50AC10[2]));
-      array_50AC10[2]._rhw = 1.0 / v101->vWorldViewPosition.x + 0.0000001000000011686097;
-      array_50AC10[2].u = 1.0;
-      array_50AC10[2].v = 0.0;
-      static stru154 static_sub_0048034E_stru_76D578;
-      static bool __init_flag1 = false;
-      if (!__init_flag1)
-      {
-        __init_flag1 = true;
-        stru154::stru154(&static_sub_0048034E_stru_76D578);
-      }
-      v96 = pGame->pLightmapBuilder;
-      pGame->pLightmapBuilder->StackLights_TerrainFace(v63, &v87, array_50AC10, 3, 1);
-      pDecalBuilder->_49BE8A(v40, v63, &v87, array_50AC10, 3, 1);
-      v100 = 3;
-      if ( byte_4D864C && pGame->uFlags & 0x80 )
-      {
-        thisc = pGame->pIndoorCameraD3D;
-        if ( pGame->pIndoorCameraD3D->_4371C3(array_50AC10, (unsigned int *)&v100, 0) == 1 && !v100 )
-          //goto LABEL_126;
-        {
-          --pODMRenderParams->uNumPolygons;
-          goto LABEL_162;
-        }
-        thisc->ViewTransform(array_50AC10, v100);
-        thisc->Project(array_50AC10, v100, 0);
-      }
-      this_3b = v102->vWorldViewPosition.x < 8.0 || pVertices2->vWorldViewPosition.x < 8.0
-           || v101->vWorldViewPosition.x < 8.0;
-      v69 = (double)pODMRenderParams->shading_dist_mist;
-      v108 = v69 < v102->vWorldViewPosition.x || v69 < pVertices2->vWorldViewPosition.x || v69 < v101->vWorldViewPosition.x;
-      v70 = 0;
-      v96->std__vector_000004_size = 0;
-      if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 )
-      {
-        if ( this_3b )
-          v70 = 3;
-        else
-          v70 = v108 != 0 ? 5 : 0;
-        static_sub_0048034E_stru_76D578.ClassifyPolygon(v63, v87);
-        if ( pDecalBuilder->uNumDecals > 0 )
-          pDecalBuilder->ApplyDecals(31 - v40->dimming_level, 4, &static_sub_0048034E_stru_76D578, v100, array_50AC10, 0, v70, -1);
-      }
-      if ( stru_F8AD28.uNumLightsApplied > 0 )
-        v96->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_76D578, v100, array_50AC10, 0, v70);
-      v71 = v59;
-      v72 = v100;
-      //v35 = byte_4D864C == 0;
-      v59->uNumVertices = v100;//???
-      if ( !byte_4D864C && pGame->uFlags & 0x80 )
-        goto LABEL_154;
-      if ( this_3b )
-      {
-        v73 = ODM_NearClip(v72);
-      }
-      else
-      {
-        if ( !v108 )
-        {
-LABEL_154:
-          v74 = v71->flags;
-          if ( !(BYTE1(v74) & 1) )
-          {
-            if ( v74 & 2 && v71->uTileBitmapID == pRenderer->hd_water_tile_id )
-            {
-              v80 = false;
-              v75 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame];
-            }
-            else
-            {
-              v75 = v71->uTileBitmapID;
-              v80 = true;
-            }
-            //v79 = 0;
-            v78 = pBitmaps_LOD->pHardwareTextures[v75];
-            v71->pTexture = (Texture *)&pBitmaps_LOD->pHardwareTextures[v75];// Ritor1: It's temporary
-            //v77 = (int)v71;
-            //v76 = v71->uNumVertices;
-            //goto LABEL_161;
-            pRenderer->DrawTerrainPolygon(v71->uNumVertices, (Polygon *)v71, v78, 0, v80);
-            goto LABEL_162;
-          }
-          v38 = (Polygon *)v71;
-          goto LABEL_56;
-        }
-        v73 = sr_424EE0_MakeFanFromTriangle(v72);
-      }
-      v71->uNumVertices = v73;
-      ODMRenderParams::Project(v73);
-      goto LABEL_154;
-    }
-  }
+
 //----- (00424579) --------------------------------------------------------
 int __fastcall sr_424579(int uFaceID, stru320 *a2)
 {
@@ -14644,5 +13270,1378 @@
   }
   return result;
 }
-
+//----- (0047F5C6) --------------------------------------------------------
+float Render::DrawBezierTerrain()
+{
+  unsigned int pDirectionIndicator1; // ebx@1
+  unsigned int pDirectionIndicator2; // edi@1
+  unsigned int v2; // eax@1
+  int v3; // eax@3
+  int v4; // edi@3
+  int v5; // ebx@3
+  int v6; // esi@3
+  unsigned int v7; // eax@3
+  int v8; // eax@4
+  unsigned int v9; // eax@6
+  int v10; // eax@7
+  //int v11; // ebx@9
+  //int v12; // edi@9
+  int v13; // eax@21
+  int v14; // eax@31
+  int v15; // edi@33
+  int v16; // eax@34
+  int v17; // edx@34
+  int v18; // ebx@34
+  int v19; // eax@36
+  int v20; // eax@39
+  int v21; // ecx@43
+  //char v22; // zf@44
+  int v23; // ecx@47
+  //int v24; // edi@52
+  int v25; // eax@54
+  int v26; // ecx@54
+  int v27; // eax@56
+  int v28; // edx@60
+  int v29; // ecx@61
+  int v30; // ecx@64
+  int v31; // ecx@68
+  int v32; // eax@70
+  //int v33; // ecx@71
+  int v34; // eax@73
+  int v35; // ecx@77
+  int v36; // ecx@81
+  int v37; // ecx@86
+  int v38; // eax@88
+  int v39; // ecx@88
+  int v40; // eax@90
+  int v41; // edx@94
+  //int v42; // ecx@95
+  int v43; // ecx@98
+  int v44; // ecx@102
+  int v45; // eax@104
+  int v46; // eax@107
+  int v47; // ecx@111
+  int v48; // ecx@115
+  int v49; // edi@120
+  int v50; // eax@122
+  int v51; // ecx@122
+  int v52; // eax@124
+  int v53; // edx@128
+  int v54; // ecx@129
+  int v55; // ecx@132
+  int v56; // eax@139
+  int v57; // ecx@140
+  int v58; // eax@142
+  int v59; // ecx@146
+  //int v60; // ecx@147
+  int v61; // ecx@150
+  int v62; // ecx@155
+  int v63; // eax@157
+  int v64; // ecx@157
+  int v65; // eax@159
+  int v66; // edx@163
+  int v67; // ecx@164
+  int v68; // ecx@167
+  //int v69; // eax@173
+  int v70; // edi@178
+  //int v71; // eax@178
+  //int v72; // ecx@178
+  //int x; // ebx@180
+  //int v74; // eax@182
+  //int v75; // eax@184
+  IndoorCameraD3D *pIndoorCameraD3D_3; // ecx@184
+  int uStartZ; // ecx@184
+  int v79; // ebx@185
+  int v127; // esi@185
+  int v86; // edi@196
+  //int v87; // eax@196
+  //int v88; // ecx@196
+  //int v89; // eax@198
+  //int v90; // ecx@200
+  int v92; // ebx@203
+  //int v93; // ST08_4@204
+  int v97; // ST08_4@204
+  float result; // eax@212
+  //struct 
+  //{
+  int v106; // [sp+Ch] [bp-68h]@191
+  int v103; // [sp+10h] [bp-64h]@190
+  int v104; // [sp+12h] [bp-62h]@190
+  //} v102;
+  int v105; // [sp+1Ch] [bp-58h]@1
+  int v107; // [sp+20h] [bp-54h]@3
+  int uEndZ; // [sp+24h] [bp-50h]@3
+  int v108; // [sp+28h] [bp-4Ch]@9
+  int v109; // [sp+2Ch] [bp-48h]@9
+  int v110; // [sp+30h] [bp-44h]@9
+  int v111; // [sp+34h] [bp-40h]@3
+  int v112; // [sp+38h] [bp-3Ch]@6
+  IndoorCameraD3D *pIndoorCameraD3D_4; // [sp+3Ch] [bp-38h]@9
+  int v114; // [sp+40h] [bp-34h]@9
+  int v115; // [sp+44h] [bp-30h]@9
+  int v116; // [sp+48h] [bp-2Ch]@9
+  //int v117; // [sp+4Ch] [bp-28h]@9
+  int v118; // [sp+50h] [bp-24h]@9
+  int v119; // [sp+54h] [bp-20h]@1
+  int v120; // [sp+58h] [bp-1Ch]@1
+  int i; // [sp+5Ch] [bp-18h]@1
+  int v122; // [sp+60h] [bp-14h]@1
+  int v123; // [sp+64h] [bp-10h]@1
+  int v124; // [sp+68h] [bp-Ch]@1
+  int v125; // [sp+6Ch] [bp-8h]@9
+  int v126; // [sp+70h] [bp-4h]@9
+
+  v105 = pGame->pIndoorCameraD3D->sRotationY / ((signed int)stru_5C6E00->uIntegerHalfPi / 2);//2
+  pDirectionIndicator1 = stru_5C6E00->uDoublePiMask & (stru_5C6E00->uIntegerDoublePi - pGame->pIndoorCameraD3D->sRotationY);//1536
+  pDirectionIndicator2 = stru_5C6E00->uDoublePiMask & (stru_5C6E00->uIntegerPi + pDirectionIndicator1);//512
+  v124 = ((pIndoorCamera->uMapGridCellX << 16) + 3 * stru_5C6E00->Cos(stru_5C6E00->uDoublePiMask & (stru_5C6E00->uIntegerPi + pDirectionIndicator1))) >> 16;//88
+  v123 = ((pIndoorCamera->uMapGridCellZ << 16) + 3 * stru_5C6E00->Sin(pDirectionIndicator2)) >> 16;// 66
+  v120 = pODMRenderParams->outdoor_grid_band_3 + v124;//+- range X
+  v119 = pODMRenderParams->outdoor_grid_band_3 + v123;
+  v2 = pODMRenderParams->uCameraFovInDegrees + 15;//90
+  i = v124 - pODMRenderParams->outdoor_grid_band_3;
+  v122 = v123 - pODMRenderParams->outdoor_grid_band_3;
+
+  if ( v2 > 90 )
+    v2 = 90;
+  //v3 = (v2 << 11) / 720;
+  v4 = stru_5C6E00->uDoublePiMask & (pDirectionIndicator1 - ((v2 << 11) / 720));
+  v5 = stru_5C6E00->uDoublePiMask & (((v2 << 11) / 720) + pDirectionIndicator1);
+
+  v106 = stru_5C6E00->Cos(v4);
+  uEndZ = stru_5C6E00->Sin(v4);
+
+  v111 = stru_5C6E00->Cos(v5);
+  v6 = stru_5C6E00->Sin(v5);
+
+  v7 = v4 & stru_5C6E00->uPiMask;
+  if ( (v4 & stru_5C6E00->uPiMask) >= stru_5C6E00->uIntegerHalfPi )
+    v8 = -stru_5C6E00->pTanTable[stru_5C6E00->uIntegerPi - v7];
+  else
+    v8 = stru_5C6E00->pTanTable[v7];
+  v112 = abs(v8);
+
+  v9 = v5 & stru_5C6E00->uPiMask;
+  if ( (v5 & stru_5C6E00->uPiMask) >= stru_5C6E00->uIntegerHalfPi )
+    v10 = -stru_5C6E00->pTanTable[stru_5C6E00->uIntegerPi - v9];
+  else
+    v10 = stru_5C6E00->pTanTable[v9];
+  v108 = abs(v10);
+
+  //v11 = v124;
+  //v12 = v123;
+  v114 = 0;
+  v115 = 0;
+  pIndoorCameraD3D_4 = 0;
+  v125 = 0;
+  v126 = v124;
+  v118 = v123;
+
+  v110 = (v106 >= 0 ? 1: -1);//2 * (v106 >= 0) - 1;
+  v109 = (uEndZ >= 0 ? 1: -1);//2 * (v107 >= 0) - 1;
+  uEndZ = (v111 >= 0 ? 1: -1);//2 * (v111 >= 0) - 1;
+  v106 = (v6 >= 0 ? 1: -1);//2 * (v6 >= 0) - 1;
+
+  uint _i = 1;
+  uint j = 1;
+
+  terrain_76DDC8[0] = -1;
+  terrain_76DFC8[0] = -1;
+  terrain_76E1C8[0] = -1;
+  terrain_76E3C8[0] = -1;
+
+  for( uint _i = 1; _i < 128; _i++)
+  {
+    if ( v112 >= 0x10000 )
+    {
+      int v1, v2;
+      //v111 = 4294967296i64 / v112;
+      //v114 += v111;
+      //if ( v114 >= 65536 )
+      //{
+      //  v11 += v110;
+      //  v114 = (unsigned __int16)v114;
+      //}
+      //v12 += v109;
+    }
+    else
+    {
+      v124 += v110;
+      v115 += v112;
+      if ( v112 + v115 >= 65536 )
+      {
+        v123 += v109;
+        v115 = (unsigned __int16)v115;
+      }
+    }
+    if ( v124 < _i || v124 > v120 || v123 < v122 || v123 > v119 )
+      break;
+    //v13 = v116++;
+    terrain_76E3C8[_i] = v124;
+    terrain_76E1C8[_i] = v123;
+  }
+
+  for( j = 1; j < 128; j++ )
+  {
+    if ( v108 >= 65536 )
+    {
+      v111 = 4294967296i64 / v108;
+      v114 += v111;//
+      if ( v111 + v114 >= 65536 )
+      {
+        v126 += uEndZ;
+        v114 = (unsigned __int16)v114;//
+      }
+      v118 += v106;
+    }
+    else
+    {
+      v125 += v108;
+      v126 += uEndZ;
+      if ( v125 >= 65536 )
+      {
+        v118 += v106;
+        v125 = (unsigned __int16)v125;
+      }
+    }
+    //if ( v117 >= 128 )
+      //break;
+    if ( v126 < _i )
+      break;
+    if ( v126 > v120 )
+      break;
+    v14 = v118;
+    if ( v118 < v122 )
+      break;
+    if ( v118 > v119 )
+      break;
+    terrain_76DFC8[j] = v126;
+    terrain_76DDC8[j] = v14;
+  }
+  v16 = 0;
+  v126 = 0;
+  v17 = j - 1;
+  v18 = _i - 1;
+
+  switch ( v105 )//напрвление камеры
+  {
+    case 0:
+    case 7:
+    {
+      //v116 = terrain_76DFC8[v17];
+      if ( v120 > terrain_76DFC8[v17] )
+      {
+        v125 = v120;
+        memset32(terrain_76D9C8.data(), v119 + 1, 4 * (v120 - terrain_76DFC8[v17] + 1));
+        v19 = v120;
+        do
+          terrain_76DBC8[v126++] = v19--;
+        while ( v19 >= terrain_76DFC8[v17] );
+        if ( terrain_76DFC8[v17] == terrain_76DDC8[v17 + 127] )
+        {
+          do
+            v20 = terrain_76DDC8[v17-- -1];
+          while ( v20 == terrain_76DDC8[v17 -1] );
+        }
+        v16 = v126;
+        --v17;
+      }
+      if ( v17 < 0 )
+        v17 = 0;
+      
+      //while ( 1 )
+	  for ( v21 = terrain_76DFC8[v17]; v21 < v124; v21 = terrain_76DFC8[v17] - 1; )
+      {
+        //v125 = terrain_76DFC8[v17];
+        terrain_76DBC8[v16] = v21;
+        //v22 = terrain_76DDC8[v17] == 65535;
+        terrain_76D9C8[v16] = terrain_76DDC8[v17] + 1;
+        if ( terrain_76DDC8[v17] == 65535 )
+        {
+          terrain_76D9C8[v16] = v123 + 1;
+          break;
+        }
+        if ( !v17 )
+          break;
+        if ( terrain_76DFC8[v17] == terrain_76DDC8[v17 - 1] )
+        {
+          do
+            v23 = terrain_76DDC8[v17-- -1];
+          while ( v23 == terrain_76DDC8[v17 -1] );
+        }
+        --v17;
+        ++v16;
+      }
+      v16 = 0;
+      //v24 = terrain_76E3C8[v18];
+      v126 = 0;
+      if ( v120 > terrain_76E3C8[v18] )
+      {
+        v125 = v120;
+        memset32(terrain_76D5C8.data(), v122, 4 * (v120 - terrain_76E3C8[v18] + 1));
+        do
+        {
+          v25 = v126;
+          v26 = v125--;
+          ++v126;
+          terrain_76D7C8[v25] = v26;
+        }
+        while ( v125 >= terrain_76E3C8[v18] );
+        if ( terrain_76E3C8[v18] == terrain_76E1C8[v18 -1] )
+        {
+          do
+            v27 = terrain_76E1C8[v18-- -1];
+          while ( v27 == terrain_76E1C8[v18 -1] );
+        }
+        v16 = v126;
+        --v18;
+      }
+      if ( v18 < 0 )
+        v18 = 0;
+      v28 = terrain_76E3C8[v18];
+      while ( v28 >= v124 )
+      {
+        v29 = terrain_76E1C8[v18];
+        terrain_76D7C8[v16] = v28;
+        terrain_76D5C8[v16] = v29;
+        if ( v29 == 65535 )
+        {
+          v31 = v123;
+          terrain_76D5C8[v16] = v31;
+          break;
+        }
+        if ( !v18 )
+          break;
+        if ( terrain_76E3C8[v18] == terrain_76E1C8[v18 -1] )
+        {
+          do
+            v30 = terrain_76E1C8[v18-- -1];
+          while ( v30 == terrain_76E1C8[v18 -1] );
+        }
+        --v18;
+        --v28;
+        ++v16;
+      }
+      break;
+    }
+    case 1:
+    case 2:
+    {
+      //v116 = terrain_76DDC8[v17];
+      if ( v122 < terrain_76DDC8[v17] )
+      {
+        v106 = v122;
+        memset32(terrain_76DBC8.data(), v120 + 1, 4 * (terrain_76DDC8[v17] - v122 + 1));
+        for ( v32 = v122; v32 <= terrain_76DDC8[v17]; v32++)
+          terrain_76D9C8[v126++] = v32;
+        if ( terrain_76DDC8[v17] == terrain_76DBC8[v17 -1] )
+        {
+          do
+            v34 = terrain_76DBC8[v17-- -1];
+          while ( v34 == terrain_76DBC8[v17 -1] );
+        }
+        v16 = v126;
+        --v17;
+      }
+      if ( v17 < 0 )
+        v17 = 0;
+      v35 = terrain_76DDC8[v17];
+      v125 = terrain_76DDC8[v17];
+      while ( v35 <= v123 )
+      {
+        //v22 = terrain_76DFC8[v17] == 65535;
+        terrain_76DBC8[v16] = terrain_76DFC8[v17] + 1;
+        terrain_76D9C8[v16] = v125;
+        if ( terrain_76DFC8[v17] == 65535 )
+        {
+          terrain_76DBC8[v16] = v124 + 1;
+          break;
+        }
+        if ( !v17 )
+          break;
+        if ( terrain_76DDC8[v17] == terrain_76DBC8[v17 -1] )
+        {
+          do
+            v36 = terrain_76DBC8[v17-- -1];
+          while ( v36 == terrain_76DBC8[v17 -1] );
+        }
+        --v17;
+        ++v125;
+        v35 = v125;
+        ++v16;
+      }
+      v16 = 0;
+      v126 = 0;
+      v37 = terrain_76E1C8[v18];
+      if ( v122 < v37 )
+      {
+        v114 = v122;
+        memset32(terrain_76D7C8.data(), i, 4 * (v37 - v122 + 1));
+        do
+        {
+          v38 = v126;
+          v39 = v114;
+          ++v126;
+          ++v114;
+          terrain_76D5C8[v38] = v39;
+        }
+        while ( v114 <= terrain_76E1C8[v18] );
+        if ( terrain_76E1C8[v18] == terrain_76DFC8[v18 -1] )
+        {
+          do
+            v40 = terrain_76DFC8[v18-- -1];
+          while ( v40 == terrain_76DFC8[v18 -1] );
+        }
+        v16 = v126;
+        --v18;
+      }
+      if ( v18 < 0 )
+        v18 = 0;
+      v41 = terrain_76E1C8[v18];
+      while ( v41 <= v123 )
+      {
+        terrain_76D5C8[v16] = v41;
+        terrain_76D7C8[v16] = terrain_76E3C8[v18];
+        if ( terrain_76E3C8[v18] == 65535 )
+        {
+          terrain_76D7C8[v16] = v124;
+          break;
+        }
+        if ( !v18 )
+          break;
+        if ( terrain_76E1C8[v18] == terrain_76DFC8[v18 -1] )
+        {
+          do
+            v43 = terrain_76DFC8[v18-- -1];
+          while ( v43 == terrain_76DFC8[v18 -1] );
+        }
+        --v18;
+        ++v41;
+        ++v16;
+      }
+      break;
+    }
+    case 5:
+    case 6:
+    {
+      //v116 = terrain_76DDC8[v17];
+      if ( v119 > terrain_76DDC8[v17] )
+      {
+        v106 = v119;
+        memset32(terrain_76DBC8.data(), i, 4 * (v119 - terrain_76DDC8[v17] + 1));
+        for ( v45 = v119; v45 >= terrain_76DDC8[v17]; v45--)
+          terrain_76D9C8[v126++] = v45;
+        if ( terrain_76DDC8[v17] == terrain_76DBC8[v17 -1] )
+        {
+          do
+            v46 = terrain_76DBC8[v17-- -1];
+          while ( v46 == terrain_76DBC8[v17 -1] );
+        }
+        v16 = v126;
+        --v17;
+      }
+      if ( v17 < 0 )
+        v17 = 0;
+      v47 = terrain_76DDC8[v17];
+      v125 = terrain_76DDC8[v17];
+      while ( v47 >= v123 )
+      {
+        //v22 = terrain_76DFC8[v17] == 65535;
+        terrain_76DBC8[v16] = terrain_76DFC8[v17];
+        terrain_76D9C8[v16] = terrain_76DDC8[v17];
+        if ( terrain_76DFC8[v17] == 65535 )
+        {
+          terrain_76DBC8[v16] = v124;
+          break;
+        }
+        if ( !v17 )
+          break;
+        if ( terrain_76DDC8[v17] == terrain_76DBC8[v17 -1] )
+        {
+          do
+            v48 = terrain_76DBC8[v17-- -1];
+          while ( v48 == terrain_76DBC8[v17 -1] );
+        }
+        --v17;
+        --v125;
+        v47 = v125;
+        ++v16;
+      }
+      v16 = 0;
+      v49 = terrain_76E1C8[v18];
+      v126 = 0;
+      if ( v119 > v49 )
+      {
+        v125 = v119;
+        memset32(terrain_76D7C8.data(), v120 + 1, 4 * (v119 - v49 + 1));
+        do
+        {
+          v50 = v126;
+          v51 = v125--;
+          ++v126;
+          terrain_76D5C8[v50] = v51;
+        }
+        while ( v125 >= terrain_76E1C8[v18] );
+        if ( terrain_76E1C8[v18] == terrain_76DFC8[v18 -1] )
+        {
+          do
+            v52 = terrain_76DFC8[v18-- -1];
+          while ( v52 == terrain_76DFC8[v18 -1] );
+        }
+        v16 = v126;
+        --v18;
+      }
+      if ( v18 < 0 )
+        v18 = 0;
+      v53 = terrain_76E1C8[v18];
+      while ( v53 >= v123 )
+      {
+        v54 = terrain_76E3C8[v18];
+        terrain_76D5C8[v16] = v53;
+        terrain_76D7C8[v16] = v54 + 1;
+        if ( v54 == 65535 )
+        {
+          terrain_76D7C8[v16] = v124 + 1;
+          break;
+        }
+        if ( !v18 )
+          break;
+        if ( terrain_76E1C8[v18] == terrain_76DFC8[v18 -1] )
+        {
+          do
+            v55 = terrain_76DFC8[v18-- -1];
+          while ( v55 == terrain_76DFC8[v18 -1] );
+        }
+        --v18;
+        --v53;
+        ++v16;
+      }
+      break;
+    }
+    case 3:
+    case 4:
+    {
+      //v116 = terrain_76DFC8[v17];
+      if ( i < terrain_76DFC8[v17] )
+      {
+        v106 = i;
+        memset32(terrain_76D9C8.data(), v122, 4 * (terrain_76DFC8[v17] - i + 1));
+        v56 = i;
+        do
+        {
+          v57 = v126++;
+          terrain_76DBC8[v57] = v56++;
+        }
+        while ( v56 <= terrain_76DFC8[v17] );
+        if ( terrain_76DFC8[v17] == terrain_76DDC8[v17 -1] )
+        {
+          do
+            v58 = terrain_76DDC8[v17-- -1];
+          while ( v58 == terrain_76DDC8[v17 -1] );
+        }
+        v16 = v126;
+        --v17;
+      }
+      if ( v17 < 0 )
+        v17 = 0;
+      v59 = terrain_76DFC8[v17];
+      while ( 1 )
+      {
+        v125 = terrain_76DFC8[v17];
+        if ( terrain_76DFC8[v17] > v124 )
+          break;
+        terrain_76DBC8[v16] = terrain_76DFC8[v17];
+        //v60 = terrain_76DDC8[v17];
+        terrain_76D9C8[v16] = terrain_76DDC8[v17];
+        if ( terrain_76DDC8[v17] == 65535 )
+        {
+          terrain_76D9C8[v16] = v123;
+          break;
+        }
+        if ( !v17 )
+          break;
+        if ( terrain_76DFC8[v17] == terrain_76DDC8[v17 -1] )
+        {
+          do
+            v61 = terrain_76DDC8[v17-- -1];
+          while ( v61 == terrain_76DDC8[v17 -1] );
+        }
+        --v17;
+        v59 = v125 + 1;
+        ++v16;
+      }
+      v16 = 0;
+      v126 = 0;
+      v62 = terrain_76E3C8[v18];
+      if ( i < v62 )
+      {
+        v114 = i;
+        memset32(terrain_76D5C8.data(), v119 + 1, 4 * (v62 - i + 1));
+        do
+        {
+          v63 = v126;
+          v64 = v114;
+          ++v126;
+          ++v114;
+          terrain_76D7C8[v63] = v64;
+        }
+        while ( v114 <= terrain_76E3C8[v18] );
+        if ( terrain_76E3C8[v18] == terrain_76E1C8[v18 -1] )
+        {
+          do
+            v65 = terrain_76E1C8[v18-- -1];
+          while ( v65 == terrain_76E1C8[v18 -1] );
+        }
+        v16 = v126;
+        --v18;
+      }
+      if ( v18 < 0 )
+        v18 = 0;
+      v66 = terrain_76E3C8[v18];
+      while ( v66 <= v124 )
+      {
+        v67 = terrain_76E1C8[v18];
+        terrain_76D7C8[v16] = v66;
+        terrain_76D5C8[v16] = terrain_76E1C8[v18] + 1;
+        if ( terrain_76E1C8[v18] == 65535 )
+        {
+          v31 = v123 + 1;
+          terrain_76D5C8[v16] = v31;
+          break;
+        }
+        if ( !v18 )
+          break;
+        if ( terrain_76E3C8[v18] == terrain_76E1C8[v18 -1] )
+        {
+          do
+            v68 = terrain_76E1C8[v18-- -1];
+          while ( v68 == terrain_76E1C8[v18 -1] );
+        }
+        --v18;
+        ++v66;
+        ++v16;
+      }
+      break;
+    }
+    default:
+      break;
+  }
+  //v69 = v16 - 1;
+  ptr_801A08 = pVerticesSR_806210;
+  ptr_801A04 = pVerticesSR_801A10;
+  //v126 = v69;
+
+  if ( v105 && v105 != 7 && v105 != 3 && v105 != 4 )//блок, ориентация камеры 1(СВ), 2(С), 5(ЮЗ), 6(Ю)
+  {
+    for ( i = v16 - 1; i >= 1; --i )
+    {
+      //v70 = i;
+      //v71 = terrain_76D7C8[i];//88
+      //v72 = terrain_76DBC8[i];//0
+      if ( terrain_76D7C8[i] < terrain_76DBC8[i] )//swap
+      {
+        terrain_76DBC8[i] = terrain_76D7C8[i];
+        terrain_76D7C8[i] = terrain_76DBC8[i];
+      }
+      //x = terrain_76DBC8[i];//0
+      v111 = 0;
+      if ( terrain_76DBC8[i] <= 0 )
+        terrain_76DBC8[i] = -terrain_76DBC8[i];
+      //v74 = terrain_76D7C8[i];
+      if ( terrain_76D7C8[i] <= 0 )
+        terrain_76D7C8[i] = -terrain_76D7C8[i];
+      uEndZ = terrain_76D7C8[i] + 2;
+      //pIndoorCameraD3D_3 = pGame->pIndoorCameraD3D;
+      //uEndZ = v75;
+      //pIndoorCameraD3D_4 = pIndoorCameraD3D_3;
+      uStartZ = terrain_76DBC8[i] - 2;
+      if ( terrain_76DBC8[i] - 2 < uEndZ )
+      {
+        v127 = 0;
+        //v79 = (v73 - 66) << 9;
+        //v116 = v77;
+        //pHeight = v79;
+        v111 = uEndZ - uStartZ;
+        for (int z = uStartZ; z < uEndZ; ++z)
+        {
+          ptr_801A08[v127].vWorldPosition.x = (-64 + terrain_76DBC8[i]) * 512;//pTerrainVertices[z * 128 + x].vWorldPosition.x = (-64 + (signed)x) * 512;
+          ptr_801A08[v127].vWorldPosition.y = (64 - terrain_76D9C8[i]) * 512;
+          ptr_801A08[v127].vWorldPosition.z = pOutdoor->GetHeightOnTerrain( z, terrain_76D9C8[i]);
+
+          ptr_801A04[v127].vWorldPosition.x = (-64 + terrain_76DBC8[i]) * 512;
+          ptr_801A04[v127].vWorldPosition.y = (63 - terrain_76D9C8[i]) * 512;
+          ptr_801A04[v127].vWorldPosition.z = pOutdoor->GetHeightOnTerrain( z, terrain_76D9C8[i] + 1);
+
+          if ( !byte_4D864C || !(pGame->uFlags & 0x80) )
+          {
+            pIndoorCameraD3D_4->ViewTransform(&ptr_801A08[v127], 1);
+            pIndoorCameraD3D_4->ViewTransform(&ptr_801A04[v127], 1);
+
+            pIndoorCameraD3D_4->Project(&ptr_801A08[v127], 1, 0);
+            pIndoorCameraD3D_4->Project(&ptr_801A04[v127], 1, 0);
+          }
+          //v79 += 512;
+          v127 ++;
+          //++v116;
+          //pHeight = v79;
+       }
+        //while ( v116 < v107 );
+      }
+      v103 = abs((int)pIndoorCamera->uMapGridCellZ - terrain_76D9C8[i]);
+      v104 = abs((int)pIndoorCamera->uMapGridCellX - terrain_76DBC8[i]);
+      if ( pRenderer->pRenderD3D )//Ritor1: do comment to test
+        Render::DrawTerrainD3D(v111, 0, v103, v104);
+        //Render::RenderTerrainD3D();
+      //else
+        //Render::DrawTerrainSW(v111, 0, v103, v104);
+    }
+  }
+  else//ориентация камеры 0(В), 3(СЗ), 4(З), 7(ЮВ)
+  {
+    for ( i = v16 - 1; i >= 1; --i )
+    {
+      //v86 = i;
+      //v87 = terrain_76D5C8[i];
+      //v88 = terrain_76D9C8[i];
+      if ( terrain_76D5C8[i] < terrain_76D9C8[i] )
+      {
+        terrain_76D9C8[i] = terrain_76D5C8[i];
+        terrain_76D5C8[i] = terrain_76D9C8[i];
+      }
+      //v89 = terrain_76D9C8[i];
+      v111 = 0;
+      if ( terrain_76D9C8[i] <= 0 )
+        terrain_76D9C8[i] = -terrain_76D9C8[i];
+      //v90 = terrain_76D5C8[i];
+      if ( terrain_76D5C8[i] <= 0 )
+        terrain_76D5C8[i] = -terrain_76D5C8[i];
+      pIndoorCameraD3D_4 = pGame->pIndoorCameraD3D;
+      v107 = terrain_76D5C8[i] + 2;
+      if ( terrain_76D9C8[i] - 2 < terrain_76D5C8[i] + 2 )
+      {
+        v86 = 0;
+        //v116 = terrain_76D9C8[i] - 2;
+        v92 = (66 - terrain_76D9C8[i]) << 9;
+        //pHeight = (66 - terrain_76D9C8[i]) << 9;
+        v111 = terrain_76D5C8[i] + 2 - (terrain_76D9C8[i] - 2);
+        //do
+        for ( v116 = terrain_76D9C8[i] - 2; v116 < v107; ++v116 )
+        {
+          ptr_801A08[v86].vWorldPosition.x = (terrain_76DBC8[v86] - 64) << 9;
+          ptr_801A08[v86].vWorldPosition.y = v92;
+          ptr_801A08[v86].vWorldPosition.z = pOutdoor->GetHeightOnTerrain(terrain_76DBC8[v86], v116);
+
+          ptr_801A04[v86].vWorldPosition.x = (terrain_76DBC8[v86] - 63) << 9;
+          ptr_801A04[v86].vWorldPosition.y = v92;
+          ptr_801A04[v86].vWorldPosition.z = pOutdoor->GetHeightOnTerrain(terrain_76DBC8[v86] + 1, v116);
+          if ( !byte_4D864C || !(pGame->uFlags & 0x80) )
+          {
+           pIndoorCameraD3D_4->ViewTransform((RenderVertexSoft *)(char *)ptr_801A08 + v86, 1);
+           pIndoorCameraD3D_4->ViewTransform((RenderVertexSoft *)(char *)ptr_801A04 + v86, 1);
+           pIndoorCameraD3D_4->Project((RenderVertexSoft *)(char *)ptr_801A08 + v86, 1, 0);
+           pIndoorCameraD3D_4->Project((RenderVertexSoft *)(char *)ptr_801A04 + v86, 1, 0);
+          }
+          v92 -= 512;
+          v86 += 48;
+          //++v116;
+          //pHeight = v92;
+        }
+        //while ( v116 < v107 );
+      }
+      v103 = abs((int)pIndoorCamera->uMapGridCellX - terrain_76DBC8[v86]);
+	  v104 = abs((int)pIndoorCamera->uMapGridCellZ - terrain_76D9C8[v86]);
+	  if ( pRenderer->pRenderD3D )
+        Render::DrawTerrainD3D(v111, 1, v103, v104);
+      //else
+        //Render::DrawTerrainSW(v111, 1, v103, v104);
+    }
+  }
+  result = v126;
+  pODMRenderParams->field_40 = v126;
+  return result;
+}
+
+//----- (0048034E) --------------------------------------------------------
+void Render::DrawTerrainD3D(int a1, int a2, int a3, int unk4)
+{
+  //int v3; // esi@1
+  int v4; // edi@1
+  int v5; // ebx@2
+  int v6; // eax@2
+  int v7; // eax@3
+  RenderVertexSoft *v8; // edi@3
+  RenderVertexSoft *v9; // ebx@4
+  RenderVertexSoft *v10; // ecx@4
+  float v11; // eax@6
+  double v12; // ST5C_8@6
+  double v13; // ST2C_8@6
+  int v14; // eax@6
+  double v15; // st7@6
+  struct Polygon *pTile; // ebx@12
+  unsigned __int16 v17; // ax@12
+  int v18; // eax@13
+  signed int v22; // eax@13
+  Vec3_float_ *norm; // eax@15
+  //double v24; // st6@17
+  double v25; // ST54_8@17
+  unsigned __int8 v26; // sf@17
+  unsigned __int8 v27; // of@17
+  double v28; // st5@19
+  double v29; // st5@19
+  double v30; // st5@19
+  double v31; // st5@19
+  struct struct8 *v32; // esi@21
+  double v3a; // st7@32
+  int v33; // edi@38
+  unsigned int v34; // ecx@47
+  char v35; // zf@47
+  unsigned int v36; // eax@50
+  int v37; // eax@54
+  //Polygon *v38; // ecx@55
+  unsigned int v39; // eax@59
+  struct Polygon *v40; // ebx@62
+  unsigned __int16 pTileBitmapsID; // ax@62
+  int v42; // eax@63
+  LightmapBuilder *v43; // ecx@63
+  int v44; // eax@63
+  int v45; // eax@63
+  int v46; // eax@63
+  signed int v47; // eax@63
+  Vec3_float_ *v48; // eax@65
+  double v49; // st6@67
+  double v50; // ST4C_8@67
+  double v51; // st5@71
+  double v52; // st5@71
+  double v53; // st5@71
+  double v54; // st7@84
+  unsigned int v55; // ecx@98
+  unsigned int v56; // eax@101
+  int v57; // eax@105
+  unsigned int v58; // eax@109
+  struct Polygon *v59; // esi@112
+  unsigned __int16 v60; // ax@112
+  int v61; // eax@113
+  signed int v62; // eax@113
+  Vec3_float_ *v63; // eax@114
+  double v64; // st6@116
+  double v65; // ST3C_8@116
+  double v66; // st5@120
+  double v67; // st5@120
+  double v68; // st5@120
+  double v69; // st7@133
+  int v70; // edi@138
+  struct Polygon *v71; // esi@147
+  unsigned int v72; // ecx@147
+  unsigned int v73; // eax@150
+  int v74; // eax@154
+  unsigned int v75; // eax@158
+  //unsigned int v76; // [sp-10h] [bp-E0h]@61
+  int v77; // [sp-Ch] [bp-DCh]@61
+  IDirect3DTexture2 *v78; // [sp-8h] [bp-D8h]@61
+  //int v79; // [sp-4h] [bp-D4h]@61
+  bool v80; // [sp+0h] [bp-D0h]@59
+  bool v81; // [sp+0h] [bp-D0h]@109
+  int v82; // [sp+54h] [bp-7Ch]@1
+  int v83; // [sp+60h] [bp-70h]@1
+  int v84; // [sp+6Ch] [bp-64h]@1
+  int v85; // [sp+70h] [bp-60h]@63
+  float a4; // [sp+74h] [bp-5Ch]@73
+  float v87; // [sp+78h] [bp-58h]@122
+  int v88; // [sp+7Ch] [bp-54h]@1
+  int v89; // [sp+80h] [bp-50h]@6
+  int v93; // [sp+90h] [bp-40h]@2
+  int X; // [sp+94h] [bp-3Ch]@1
+  float v95; // [sp+98h] [bp-38h]@21
+  LightmapBuilder *v96; // [sp+9Ch] [bp-34h]@73
+  int v97; // [sp+A0h] [bp-30h]@6
+  int sX; // [sp+A4h] [bp-2Ch]@6
+  unsigned int uNumVertices; // [sp+A8h] [bp-28h]@73
+  int v100; // [sp+ACh] [bp-24h]@122
+  int sY; // [sp+B0h] [bp-20h]@6
+  RenderVertexSoft *v102; // [sp+B4h] [bp-1Ch]@3
+  unsigned int a5; // [sp+B8h] [bp-18h]@21
+  RenderVertexSoft *v101; // [sp+BCh] [bp-14h]@6
+  Vec3_float_ *v99; // [sp+C0h] [bp-10h]@17
+  RenderVertexSoft *pVertices; // [sp+C4h] [bp-Ch]@6
+  RenderVertexSoft *pVertices2; // [sp+C8h] [bp-8h]@6
+  char v108; // [sp+CFh] [bp-1h]@36
+  float thisd; // [sp+D8h] [bp+8h]@6
+  float thise; // [sp+D8h] [bp+8h]@6
+  float thisf; // [sp+D8h] [bp+8h]@17
+  IndoorCameraD3D *thisa; // [sp+D8h] [bp+8h]@23
+  float thisg; // [sp+D8h] [bp+8h]@67
+  IndoorCameraD3D *thisb; // [sp+D8h] [bp+8h]@75
+  float thish; // [sp+D8h] [bp+8h]@116
+  IndoorCameraD3D *thisc; // [sp+D8h] [bp+8h]@124
+  char this_3; // [sp+DBh] [bp+Bh]@30
+  char this_3a; // [sp+DBh] [bp+Bh]@82
+  char this_3b; // [sp+DBh] [bp+Bh]@131
+
+  __debugbreak();
+  static stru154 static_sub_0048034E_stru_154;
+  static stru154 stru_76D5A8;
+  //v3 = a1;
+  v82 = a2;
+  v83 = a3;
+  X = abs(unk4);
+  v4 = 0;
+  v88 = 0;
+  v84 = a1 - 1;
+  if ( a1 - 1 > 0 )
+  {
+    while ( 1 )
+    {
+      v5 = abs(X);//v5 = 13108
+      v6 = abs(v83);//v6 = 13108
+      --X;
+      //__debugbreak(); // uncoment & refactor following large if
+      v93 = (int)&terrain_76E5C8[(v5 << 7) + v6];
+      if ( !v93->field_0 || ((v7 = 48 * v4, v8 = &pVerticesSR_806210[v4], a2 = v8, !v82) ? (v9 = (RenderVertexSoft *)((char *)&pVerticesSR_801A10 + v7),
+                                                                       v10 = &pVerticesSR_806210[1] + v7) : (v9 = &pVerticesSR_806210[1] + v7, v10 = (RenderVertexSoft *)((char *)&pVerticesSR_801A10 + v7)),
+             ((a8 = v9,
+               pVertices = &pVerticesSR_801A10[1] + v7,
+               v11 = v8->vWorldPosition.x,
+               v101 = v10,
+               v12 = v11 + 6.755399441055744e15,
+               sX = LODWORD(v12),
+               v13 = v8->vWorldPosition.y + 6.755399441055744e15,
+               sY = LODWORD(v13),
+               thisd = (v10->vWorldPosition.x + v8->vWorldPosition.x) * 0.5,
+               v14 = WorldPosToGridCellX(floorf(thisd + 0.5f)),//maybe current camera position X
+               v15 = v9->vWorldPosition.y + v8->vWorldPosition.y,
+               v89 = v14,
+               thise = v15 * 0.5,
+               _this = (LightmapBuilder *)WorldPosToGridCellZ(floorf(thisd + 0.5f)),//maybe current camera position Z
+               WorldPosToGridCellX(sX),
+               WorldPosToGridCellZ(sY),
+               !byte_4D864C)
+           || !(pGame->uFlags & 0x80))
+          && !_481EFA_clip_terrain_poly(v8, v9, v101, pVertices, 1)) )
+      if ( !&terrain_76E5C8[(v5 << 7) + v6] )
+        goto LABEL_162
+      v8 = &pVerticesSR_806210[v4];
+      //pVertices2 = &pVerticesSR_801A10[v4 + 1];
+      //v102 = v8;
+      if (!v82)
+      {
+        pVertices = &pVerticesSR_801A10[v4];
+        v101 = &pVerticesSR_806210[v4 + 1];
+      }
+      else
+      {
+        pVertices = &pVerticesSR_801A10[v4 + 1];
+        v101 = &pVerticesSR_806210[v4];
+      }
+      sX = floorf(v8->vWorldPosition.x + 0.5f);
+      sY = floorf(v8->vWorldPosition.z + 0.5f);
+      v89 = WorldPosToGridCellX(floorf((v101->vWorldPosition.x + v8->vWorldPosition.x) / 2 + 0.5f));
+      v97 = WorldPosToGridCellZ(floorf((pVertices->vWorldPosition.z + v8->vWorldPosition.z) / 2 + 0.5f));
+      WorldPosToGridCellX(sX);
+      WorldPosToGridCellZ(sY);
+      if ((!byte_4D864C || !(pGame->uFlags & 0x80)) && !_481EFA_clip_terrain_poly(v8, pVertices, v101, pVertices2, 1))
+        if ( v8->vWorldPosition.y != pVertices->vWorldPosition.y || pVertices->vWorldPosition.y != pVertices2->vWorldPosition.y 
+             || pVertices2->vWorldPosition.y != v101->vWorldPosition.y )
+          break;
+        pTile = &array_77EC08[pODMRenderParams->uNumPolygons];
+        pTile->uTileBitmapID = pOutdoor->GetTileTexture(sX, sY);
+        if ( pTile->uTileBitmapID != -1 )
+        {
+          pTile->flags = 0x8010 |pOutdoor->GetSomeOtherTileInfo(sX, sY);
+          pTile->field_32 = 0;
+          pTile->field_59 = 1;
+          pTile->terrain_grid_x = (char)v97;
+          __debugbreak(); // warning C4700: uninitialized local variable 'v93' used
+          pTile->field_34 = *(_WORD *)(v93 + 2);
+          pTile->terrain_grid_z = v89;
+          v22 = pTerrainNormalIndices[2 * (v97 + 128 * v89) + 1];
+          if ( v22 < 0 || v22 > uNumTerrainNormals - 1 )
+            norm = 0;
+          else
+            norm = &pTerrainNormals[v22];
+          thisf = 20.0 - ( -(((float)pOutdoor->vSunlight.x / 65536.0) * norm->x) -
+                            (((float)pOutdoor->vSunlight.y / 65536.0) * norm->y) -
+                            (((float)pOutdoor->vSunlight.z / 65536.0) * norm->z)) * 20.0;
+          //v25 = thisf + 6.7553994e15;
+          //v27 = pODMRenderParams->uNumPolygons > 1999;
+          //v26 = pODMRenderParams->uNumPolygons - 1999 < 0;
+          pTile->dimming_level = floorf(thisf + 0.5f);
+          if ( pODMRenderParams->uNumPolygons >= 1999 )
+            return;
+          ++pODMRenderParams->uNumPolygons;
+          //if ( !_481FC9_terrain(v8, pVertices, v101, v16) )//Ritor1: It's temporary
+          //goto LABEL_126;
+          //{
+            //--pODMRenderParams->uNumPolygons;
+            //goto LABEL_162;
+          //}
+          __debugbreak(); // warning C4700: uninitialized local variable 'v102' used
+          memcpy(&array_50AC10[0], v102, 0x30u);
+          array_50AC10[0]._rhw = 1.0 / (v102->vWorldViewPosition.x + 0.0000001000000011686097);
+          array_50AC10[0].u = 0.0;
+          array_50AC10[0].v = 0.0;
+          memcpy(&array_50AC10[1], pVertices, sizeof(array_50AC10[1]));
+          array_50AC10[1]._rhw = 1.0 / (pVertices->vWorldViewPosition.x + 0.0000001000000011686097);
+          array_50AC10[1].u = 0.0;
+          array_50AC10[1].v = 1.0;
+          __debugbreak(); // warning C4700: uninitialized local variable 'pVertices2' used
+          memcpy(&array_50AC10[2], pVertices2, sizeof(array_50AC10[2]));
+          array_50AC10[2]._rhw = 1.0 / (pVertices2->vWorldViewPosition.x + 0.0000001000000011686097);
+          array_50AC10[2].u = 1.0;
+          array_50AC10[2].v = 1.0;
+          memcpy(&array_50AC10[3], v101, sizeof(array_50AC10[3]));
+          array_50AC10[3]._rhw = 1.0 / (v101->vWorldViewPosition.x + 0.0000001000000011686097);
+          array_50AC10[3].u = 1.0;
+          array_50AC10[3].v = 0.0;
+          if ( !(_76D5C0_static_init_flag & 1) )
+          {
+            _76D5C0_static_init_flag |= 1u;
+            stru154(stru_76D5A8);
+            atexit(loc_481199);
+          }
+          v32 = (struct8 *)array_50AC10;
+          v97 = (int)pGame->pLightmapBuilder;
+          pGame->pLightmapBuilder->StackLights_TerrainFace(norm, &v95, array_50AC10, 4, 1);
+          pDecalBuilder->_49BE8A(pTile, norm, &v95, array_50AC10, 4, 1);
+          a5 = 4;
+          if ( byte_4D864C && pGame->uFlags & 0x80 )
+          {
+            thisa = pGame->pIndoorCameraD3D;
+            if ( pGame->pIndoorCameraD3D->_4371C3(array_50AC10, &a5, 0) == 1 && !a5 )
+              goto LABEL_162;
+            thisa->ViewTransform(array_50AC10, a5);
+            thisa->Project(array_50AC10, a5, 0);
+          }
+          this_3 = v102->vWorldViewPosition.x < 8.0 || pVertices->vWorldViewPosition.x < 8.0
+              || v101->vWorldViewPosition.x < 8.0 || pVertices2->vWorldViewPosition.x < 8.0;
+          v3a = (double)pODMRenderParams->shading_dist_mist;
+          v108 = v3a < v102->vWorldViewPosition.x || v3a < pVertices->vWorldViewPosition.x
+              || v3a < v101->vWorldViewPosition.x || v3a < pVertices2->vWorldViewPosition.x;
+          v33 = 0;
+          pGame->pLightmapBuilder->std__vector_000004_size = 0;
+          if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 )
+          {
+            if ( this_3 )
+              v33 = 3;
+            else
+              v33 = v108 != 0 ? 5 : 0;
+            static_sub_0048034E_stru_154.ClassifyPolygon(norm, v95);
+            if ( pDecalBuilder->uNumDecals > 0 )
+              pDecalBuilder->ApplyDecals(31 - pTile->dimming_level, 4, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, *(float *)&v33, -1);
+          }
+          if ( stru_F8AD28.uNumLightsApplied > 0 )
+            pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, v33);
+          v34 = a5;
+          //v35 = byte_4D864C == 0;
+          pTile->uNumVertices = a5;
+          if ( !byte_4D864C || ~pGame->uFlags & 0x80 )
+          {
+            if ( this_3 )
+            {
+              v36 = ODM_NearClip(v34);
+              pTile->uNumVertices = v36;
+              ODMRenderParams::Project(v36);
+            }
+            if ( v108 )
+            {
+              v36 = ODM_FarClip(v34);
+              pTile->uNumVertices = v36;
+              ODMRenderParams::Project(v36);
+            }
+          }
+          //v37 = *(int *)&v16->flags;
+          if ( ~pTile->flags & 1 )
+          {
+            if ( pTile->flags & 2 && pTile->uTileBitmapID == pRenderer->hd_water_tile_id )
+            {
+              v80 = false;
+              v39 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame];
+            }
+            else
+            {
+              v39 = pTile->uTileBitmapID;
+              v80 = true;
+            }
+            //v79 = 0;
+            //v78 = pBitmaps_LOD->pHardwareTextures[v39];
+            pTile->pTexture = (Texture *)&pBitmaps_LOD->pHardwareTextures[v39];// Ritor1: It's temporary
+            v77 = (int)pTile;
+            //v76 = v16->uNumVertices;
+//LABEL_161:
+            pRenderer->DrawTerrainPolygon(pTile->uNumVertices, pTile, pBitmaps_LOD->pHardwareTextures[v39], false, v80);
+            goto LABEL_162;
+          }
+LABEL_56:
+          pTile->DrawBorderTiles();
+        }
+LABEL_162:
+        v4 = v88 + 1;
+        if ( ++v88 >= v84 )
+          return;
+      }
+      v40 = &array_77EC08[pODMRenderParams->uNumPolygons];
+      v40->uTileBitmapID = pOutdoor->GetTileTexture(sX, sY);
+      if ( v40->uTileBitmapID == -1 )
+        goto LABEL_162;
+      v42 = pOutdoor->GetSomeOtherTileInfo(sX, sY);
+      BYTE1(v42) |= 0x80u;
+      v43 = pGame->pLightmapBuilder;
+      *(int *)&v40->flags = v42;
+      v44 = v93;
+      v40->field_59 = 1;
+      v40->terrain_grid_x = (char)v43;
+      v40->field_34 = *(_WORD *)(v44 + 2);
+      v45 = v89;
+      v40->terrain_grid_z = v89;
+      v46 = 4 * ((char)v43 + (v45 << 7));
+      v85 = v46;
+      v47 = *(unsigned __int16 *)((char *)pTerrainNormalIndices + v46 + 2);//    v47 = pTerrainNormalIndices[v46 + 1];
+      if ( v47 < 0 || v47 > (signed int)(uNumTerrainNormals - 1) )
+        v48 = 0;
+      else
+        v48 = &pTerrainNormals[v47];
+      v49 = v92 * v48->y;
+      //v99 = v48;
+      thisg = 20.0 - (-v49 - v91 * v48->z - v90 * v48->x) * 20.0;
+      v50 = thisg + 6.755399441055744e15;
+      v40->dimming_level = LOBYTE(v50);
+      if ( LOBYTE(v50) < 0 )
+        v40->dimming_level = 0;
+      if ( pODMRenderParams->uNumPolygons >= 1999 )
+        return;
+      ++pODMRenderParams->uNumPolygons;
+      if ( !_481FC9_terrain(pVertices, pVertices2, v8, v40) ) // Ritor1: It's temporary
+        //goto LABEL_77;
+        {
+          --pODMRenderParams->uNumPolygons;
+          goto LABEL_112;
+        }
+      memcpy(&array_50AC10[0], v102, 0x30u);
+      array_50AC10[0]._rhw = 1.0 / (v102->vWorldViewPosition.x + 0.0000001000000011686097);
+      array_50AC10[0].u = 0.0;
+      array_50AC10[0].v = 0.0;
+      memcpy(&array_50AC10[1], pVertices, sizeof(array_50AC10[1]));
+      array_50AC10[1]._rhw = 1.0 / pVertices->vWorldViewPosition.x + 0.0000001000000011686097;
+      array_50AC10[1].u = 0.0;
+      array_50AC10[1].v = 1.0;
+      memcpy(&array_50AC10[2], pVertices2, sizeof(array_50AC10[2]));
+      array_50AC10[2]._rhw = 1.0 / pVertices2->vWorldViewPosition.x + 0.0000001000000011686097;
+      array_50AC10[2].u = 1.0;
+      array_50AC10[2].v = 1.0;
+      static stru154 static_sub_0048034E_stru_76D590;
+      static bool __init_flag2 = false;
+      if (!__init_flag2)
+      {
+        __init_flag2 = true;
+        stru154::stru154(&static_sub_0048034E_stru_76D590);
+      }
+      if ( !(_76D5C0_static_init_flag & 2) )
+      {
+        _76D5C0_static_init_flag |= 2;
+        Polygon(stru_76D590);
+        atexit(loc_48118F);
+      }
+      v96 = pGame->pLightmapBuilder;
+      pGame->pLightmapBuilder->StackLights_TerrainFace(v48, (float *)&a4, array_50AC10, 3, 0);
+      pDecalBuilder->_49BE8A(v40, v48, &a4, array_50AC10, 3, 0);
+      uNumVertices = 3;
+      if ( byte_4D864C && pGame->uFlags & 0x80 )
+      {
+        thisb = pGame->pIndoorCameraD3D;
+        if ( pGame->pIndoorCameraD3D->_4371C3(array_50AC10, &uNumVertices, 0) == 1 && !uNumVertices )
+        {
+//LABEL_77:
+          --pODMRenderParams->uNumPolygons;
+          goto LABEL_112;
+        }
+        thisb->ViewTransform(array_50AC10, uNumVertices);
+        thisb->Project(array_50AC10, uNumVertices, 0);
+      }
+      this_3a = v102->vWorldViewPosition.x < 8.0 || pVertices->vWorldViewPosition.x < 8.0 || pVertices2->vWorldViewPosition.x < 8.0;
+      v54 = (double)pODMRenderParams->shading_dist_mist;
+      v108 = v54 < v102->vWorldViewPosition.x || v54 < pVertices->vWorldViewPosition.x || v54 < pVertices2->vWorldViewPosition.x;
+      pVertices = 0;
+      v96->std__vector_000004_size = 0;
+      if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 )
+      {
+        if ( this_3a )
+          pVertices = (RenderVertexSoft *)3;
+        else
+          pVertices = (RenderVertexSoft *)(v108 != 0 ? 5 : 0);
+        //a8 = (RenderVertexSoft *)(this_3a ? 3 : v108 != 0 ? 5 : 0);
+        static_sub_0048034E_stru_76D590.ClassifyPolygon(v48, *(float *)&a4);
+        if ( pDecalBuilder->uNumDecals > 0 )
+          pDecalBuilder->ApplyDecals(31 - v40->dimming_level, 4, &static_sub_0048034E_stru_76D590, uNumVertices, array_50AC10, 0, (char)pVertices, -1);
+      }
+      if ( stru_F8AD28.uNumLightsApplied > 0 )
+        v96->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_76D590, uNumVertices, array_50AC10, 0, (char)pVertices);
+      v55 = uNumVertices;
+      //v35 = byte_4D864C == 0;
+      v40->uNumVertices = uNumVertices;
+      if ( !_76D5C0_static_init_flag || !(pGame->uFlags & 0x80) )
+      {
+        if ( this_3a )
+        {
+          v56 = ODM_NearClip(v55);
+        }
+        else
+        {
+          if ( !v108 )
+            goto LABEL_105;
+          v56 = sr_424EE0_MakeFanFromTriangle(v55);
+        }
+        v40->uNumVertices = v56;
+        ODMRenderParams::Project(v56);
+      }
+LABEL_105:
+      v57 = *(int *)&v40->flags;
+      if ( BYTE1(v57) & 1 )
+      {
+        v40->DrawBorderTiles();
+      }
+      else
+      {
+        if ( v57 & 2 && v40->uTileBitmapID == pRenderer->hd_water_tile_id )
+        {
+          v81 = false;
+          v58 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame];
+        }
+        else
+        {
+          v58 = v40->uTileBitmapID;
+          v81 = true;
+        }
+        pRenderer->DrawTerrainPolygon(v40->uNumVertices, v40, pBitmaps_LOD->pHardwareTextures[v58], 0, v81);
+      }
+LABEL_112:
+      v59 = &array_77EC08[pODMRenderParams->uNumPolygons];
+      //a8 = (RenderVertexSoft *)&array_77EC08[pODMRenderParams->uNumPolygons];
+      v59->uTileBitmapID = pOutdoor->GetTileTexture(sX, sY);
+      if ( v59->uTileBitmapID  == -1 )
+        goto LABEL_162;
+      *(int *)&v59->flags = pOutdoor->GetSomeOtherTileInfo(sX, sY);
+      v61 = v93;
+      v59->field_59 = 1;
+      v59->field_34 = *(_WORD *)(v61 + 2);
+      v59->terrain_grid_z = v89;
+      v59->terrain_grid_x = v97;
+      v62 = *(unsigned __int16 *)((char *)pTerrainNormalIndices + v85);
+      if ( v62 > (signed int)(uNumTerrainNormals - 1) )
+        v63 = 0;
+      else
+        v63 = &pTerrainNormals[v62];
+      v64 = v92 * v63->y;
+      //v99 = v63;
+      thish = 20.0 - (-v64 - v91 * v63->y - v90 * v63->x) * 20.0;
+      v59->dimming_level = floorf(thish + 0.5f);
+      if ( v59->dimming_level < 0 )
+        v59->dimming_level = 0;
+      if ( pODMRenderParams->uNumPolygons >= 1999 )
+        return;
+      ++pODMRenderParams->uNumPolygons;
+      if ( !_481FC9_terrain(v101, v102, pVertices2, v59) )
+      {
+//LABEL_126:
+        --pODMRenderParams->uNumPolygons;
+        goto LABEL_162;
+      }
+      memcpy(&array_50AC10[0], v102, 0x30u);
+      array_50AC10[0]._rhw = 1.0 / (v102->vWorldViewPosition.x + 0.0000001000000011686097);
+      array_50AC10[0].u = 0.0;
+      array_50AC10[0].v = 0.0;
+      memcpy(&array_50AC10[1], pVertices2, sizeof(array_50AC10[1]));
+      array_50AC10[1]._rhw = 1.0 / pVertices2->vWorldViewPosition.x + 0.0000001000000011686097;
+      array_50AC10[1].u = 1.0;
+      array_50AC10[1].v = 1.0;
+      memcpy(&array_50AC10[2], v101, sizeof(array_50AC10[2]));
+      array_50AC10[2]._rhw = 1.0 / v101->vWorldViewPosition.x + 0.0000001000000011686097;
+      array_50AC10[2].u = 1.0;
+      array_50AC10[2].v = 0.0;
+      static stru154 static_sub_0048034E_stru_76D578;
+      static bool __init_flag1 = false;
+      if (!__init_flag1)
+      {
+        __init_flag1 = true;
+        stru154::stru154(&static_sub_0048034E_stru_76D578);
+      }
+      v96 = pGame->pLightmapBuilder;
+      pGame->pLightmapBuilder->StackLights_TerrainFace(v63, &v87, array_50AC10, 3, 1);
+      pDecalBuilder->_49BE8A(v40, v63, &v87, array_50AC10, 3, 1);
+      v100 = 3;
+      if ( byte_4D864C && pGame->uFlags & 0x80 )
+      {
+        thisc = pGame->pIndoorCameraD3D;
+        if ( pGame->pIndoorCameraD3D->_4371C3(array_50AC10, (unsigned int *)&v100, 0) == 1 && !v100 )
+          //goto LABEL_126;
+        {
+          --pODMRenderParams->uNumPolygons;
+          goto LABEL_162;
+        }
+        thisc->ViewTransform(array_50AC10, v100);
+        thisc->Project(array_50AC10, v100, 0);
+      }
+      this_3b = v102->vWorldViewPosition.x < 8.0 || pVertices2->vWorldViewPosition.x < 8.0
+           || v101->vWorldViewPosition.x < 8.0;
+      v69 = (double)pODMRenderParams->shading_dist_mist;
+      v108 = v69 < v102->vWorldViewPosition.x || v69 < pVertices2->vWorldViewPosition.x || v69 < v101->vWorldViewPosition.x;
+      v70 = 0;
+      v96->std__vector_000004_size = 0;
+      if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 )
+      {
+        if ( this_3b )
+          v70 = 3;
+        else
+          v70 = v108 != 0 ? 5 : 0;
+        static_sub_0048034E_stru_76D578.ClassifyPolygon(v63, v87);
+        if ( pDecalBuilder->uNumDecals > 0 )
+          pDecalBuilder->ApplyDecals(31 - v40->dimming_level, 4, &static_sub_0048034E_stru_76D578, v100, array_50AC10, 0, v70, -1);
+      }
+      if ( stru_F8AD28.uNumLightsApplied > 0 )
+        v96->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_76D578, v100, array_50AC10, 0, v70);
+      v71 = v59;
+      v72 = v100;
+      //v35 = byte_4D864C == 0;
+      v59->uNumVertices = v100;//???
+      if ( !byte_4D864C && pGame->uFlags & 0x80 )
+        goto LABEL_154;
+      if ( this_3b )
+      {
+        v73 = ODM_NearClip(v72);
+      }
+      else
+      {
+        if ( !v108 )
+        {
+LABEL_154:
+          v74 = v71->flags;
+          if ( !(BYTE1(v74) & 1) )
+          {
+            if ( v74 & 2 && v71->uTileBitmapID == pRenderer->hd_water_tile_id )
+            {
+              v80 = false;
+              v75 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame];
+            }
+            else
+            {
+              v75 = v71->uTileBitmapID;
+              v80 = true;
+            }
+            //v79 = 0;
+            v78 = pBitmaps_LOD->pHardwareTextures[v75];
+            v71->pTexture = (Texture *)&pBitmaps_LOD->pHardwareTextures[v75];// Ritor1: It's temporary
+            //v77 = (int)v71;
+            //v76 = v71->uNumVertices;
+            //goto LABEL_161;
+            pRenderer->DrawTerrainPolygon(v71->uNumVertices, (Polygon *)v71, v78, 0, v80);
+            goto LABEL_162;
+          }
+          v38 = (Polygon *)v71;
+          goto LABEL_56;
+        }
+        v73 = sr_424EE0_MakeFanFromTriangle(v72);
+      }
+      v71->uNumVertices = v73;
+      ODMRenderParams::Project(v73);
+      goto LABEL_154;
+    }
+  }
 */
\ No newline at end of file
--- a/mm7_2.cpp	Thu Mar 27 23:28:54 2014 +0100
+++ b/mm7_2.cpp	Thu Mar 27 23:30:02 2014 +0100
@@ -881,7 +881,7 @@
   int v160; // [sp+3Ch] [bp-4Ch]@13
   unsigned __int16 *v175; // [sp+4Ch] [bp-3Ch]@13
   unsigned __int16 *v193; // [sp+5Ch] [bp-2Ch]@7
-  signed int v231; // [sp+78h] [bp-10h]@7
+  //signed int v231; // [sp+78h] [bp-10h]@7
   __int64 v240; // [sp+7Ch] [bp-Ch]@12
   unsigned int v251; // [sp+80h] [bp-8h]@218
   unsigned int v252; // [sp+84h] [bp-4h]@218
@@ -922,18 +922,20 @@
     return result;
   
   //do
-  for ( v231 = 0; v231 < dstHeight; v231++ )
+  for ( int height = 0; height < dstHeight; height++ )
   {
-    for (int counter = 0; counter < dstWidth; counter++)
+    for (int width = 0; width < dstWidth; width++)
     {
-      a6s = (double)counter / (double)dstWidth * (double)srcWidth;
+      a6s = (double)width / (double)dstWidth * (double)srcWidth;
       widthRatio = bankersRounding(a6s);
-      a6t = (double)(counter + 1) / (double)dstWidth * (double)srcWidth;
+      a6t = (double)(width + 1) / (double)dstWidth * (double)srcWidth;
       widthRatioPlusOne = bankersRounding(a6t);
-      v17 = (double)v231 / (double)dstHeight * (double)srcHeight;
+
+      v17 = (double)height / (double)dstHeight * (double)srcHeight;
       heightRatio = bankersRounding(v17);
-      v18 = (double)(v231 + 1) / (double)dstHeight * (double)srcHeight;
+      v18 = (double)(height + 1) / (double)dstHeight * (double)srcHeight;
       heightRatioPlusOne = bankersRounding(v18);
+
       v251 = 0;
       v19 = (heightRatioPlusOne - heightRatio) * (widthRatioPlusOne - widthRatio);
       v252 = 0;
@@ -943,15 +945,15 @@
       v175 = (unsigned short*)((char *)pSrc + field_0_bits * (widthRatio + srcPitch * heightRatio));
       for (int heightDiff = 0; heightDiff < heightRatioPlusOne - heightRatio; heightDiff++)
       {
-        int ratioDiff = widthRatioPlusOne - widthRatio;
-        for(int i = 0; i < ratioDiff; i++)
+        //int ratioDiff = widthRatioPlusOne - widthRatio;
+        for(int ratioDiff = 0; ratioDiff < widthRatioPlusOne - widthRatio; ratioDiff++)
         {
           if(field0value == 32)
-            v21 = _450FB1(((int*)v175)[i]);
+            v21 = _450FB1(((int*)v175)[ratioDiff]);
           else if(field0value == 16)
-            v21 = _450FB1(((_WORD*)v175)[i]);
+            v21 = _450FB1(((_WORD*)v175)[ratioDiff]);
           else if (field0value == 8)
-            v21 = _450FB1(((unsigned __int8*)v175)[i]);
+            v21 = _450FB1(((unsigned __int8*)v175)[ratioDiff]);
           v240 += ((unsigned int)v21 >> 24);
           a6b += BYTE2(v21);
           v252 += BYTE1(v21);
@@ -960,10 +962,11 @@
         if (field0value == 32)
           v175 += 2 * srcPitch;
         else if (field0value == 16)
-          v175 += srcPitch;   
+          v175 += srcPitch;
         else if (field0value == 8)
           v175 = (unsigned short*)((char *)v175 + 2 * srcPitch);
       }
+
       v22 = (unsigned int)v240 / ((heightRatioPlusOne - heightRatio) * (widthRatioPlusOne - widthRatio));
       if ( v19 )
       {
@@ -979,7 +982,7 @@
     }
     v193 = (unsigned __int16 *)((char *)v193 + field_20_bits * (dstPitch - dstWidth));
     //++v231;
-    result = v231;
+    result = height;
   }
   //while(v231 < dstHeight);
   return result;
--- a/mm7_data.h	Thu Mar 27 23:28:54 2014 +0100
+++ b/mm7_data.h	Thu Mar 27 23:30:02 2014 +0100
@@ -785,3 +785,4 @@
 extern bool draw_portals_loops;
 extern bool new_speed;
 extern bool bSnow;
+extern bool draw_terrain_dist_mist;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stuff.h	Thu Mar 27 23:30:02 2014 +0100
@@ -0,0 +1,46 @@
+#pragma once
+#include <windows.h>
+#include <stdio.h>
+
+
+
+inline void Assert(bool condition, const char *format, ...)
+{
+  if (condition)
+    return;
+  
+  va_list va;
+  va_start(va, format);
+    char msg[4096];
+    vsprintf(msg, format, va);
+    MessageBoxA(nullptr, msg, "Assert", 0);
+  va_end(va);
+
+  __debugbreak();
+}
+
+inline void Error(const char *format, ...)
+{
+  va_list va;
+  va_start(va, format);
+    char msg[4096];
+    vsprintf(msg, format, va);
+    MessageBoxA(nullptr, msg, "Error", 0);
+  va_end(va);
+
+  __debugbreak();
+}
+
+
+
+inline void log(char *format, ...)
+{
+  va_list va;
+  va_start(va, format);
+  char msg[256];
+  vsprintf(msg, format, va);
+  va_end(va);
+  DWORD w;
+
+  WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), msg, strlen(msg), &w, 0);
+}
\ No newline at end of file