diff Indoor.cpp @ 1306:13b7be8b06a0

Слияние
author Ritor1
date Sun, 23 Jun 2013 14:27:57 +0600
parents dcc52e17b517 5450af4f57ef
children ad903bb5b702
line wrap: on
line diff
--- a/Indoor.cpp	Sun Jun 23 14:27:32 2013 +0600
+++ b/Indoor.cpp	Sun Jun 23 14:27:57 2013 +0600
@@ -37,10 +37,13 @@
 
 #include "mm7_data.h"
 #include "MM7.h"
-
-
-
-
+#include "Sprites.h"
+#include "Game.h"
+#include "stru6.h"
+#include "ParticleEngine.h"
+#include "Outdoor_stuff.h"
+#include "texts.h"
+#include "GUIWindow.h"
 
 
 
@@ -1335,7 +1338,7 @@
         nodes[num_nodes].uViewportZ = pBLVRenderParams->uViewportZ;
         nodes[num_nodes].uViewportY = pBLVRenderParams->uViewportY;
         nodes[num_nodes].uViewportW = pBLVRenderParams->uViewportW;
-        nodes[num_nodes].field_C._43F9E1(pBLVRenderParams->uViewportX, pBLVRenderParams->uViewportY,
+        nodes[num_nodes].field_C.GetViewportData(pBLVRenderParams->uViewportX, pBLVRenderParams->uViewportY,
                                          pBLVRenderParams->uViewportZ, pBLVRenderParams->uViewportW);
         AddBspNodeToRenderList(++num_nodes - 1);
         return;
@@ -1491,7 +1494,7 @@
         v3->nodes[v3->num_nodes].uViewportZ = LOWORD(pBLVRenderParams->uViewportZ);
         v3->nodes[v3->num_nodes].uViewportY = LOWORD(pBLVRenderParams->uViewportY);
         v3->nodes[v3->num_nodes].uViewportW = LOWORD(pBLVRenderParams->uViewportW);
-        v3->nodes[v3->num_nodes++].field_C._43F9E1(
+        v3->nodes[v3->num_nodes++].field_C.GetViewportData(
           SLOWORD(pBLVRenderParams->uViewportX),
           pBLVRenderParams->uViewportY,
           SLOWORD(pBLVRenderParams->uViewportZ),
@@ -4639,7 +4642,2198 @@
     }
   }
 }
-
+//----- (0046CEC3) --------------------------------------------------------
+int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID)
+{
+  int v13; // ecx@13
+  signed int v14; // ebx@14
+  int v15; // eax@16
+  //int v16; // edx@19
+  //int v17; // ST18_4@19
+  //signed int v18; // edx@19
+  //signed __int64 v19; // qtt@19
+  int v21; // eax@27
+  //int v22; // ecx@29
+  signed int v28; // eax@45
+  int v29; // ebx@47
+  int v30; // edx@49
+  //int v31; // ST10_4@49
+  //signed int v32; // edx@49
+  signed __int64 v33; // qtt@49
+  //signed int v34; // eax@54
+  //signed int v35; // esi@56
+  //int result; // eax@57
+  int v38; // edx@62
+  //int v44; // [sp+20h] [bp-20h]@10
+  bool v47; // [sp+24h] [bp-1Ch]@43
+  bool v48; // [sp+28h] [bp-18h]@10
+  bool v49; // [sp+28h] [bp-18h]@41
+  bool v50; // [sp+2Ch] [bp-14h]@12
+  signed int v53; // [sp+30h] [bp-10h]@10
+  signed int v54; // [sp+30h] [bp-10h]@41
+  signed int v55; // [sp+34h] [bp-Ch]@1
+
+  //LOG_DECOMPILATION_WARNING();
+
+  static int blv_floor_id[50]; // 00721200
+  static int blv_floor_level[50]; // 007212C8
+
+  static __int16 word_721390_ys[104]; // idb
+  static __int16 word_721460_xs[104]; // idb
+
+  auto pSector = &pIndoor->pSectors[uSectorID];
+  v55 = 0;
+  for (uint i = 0; i < pSector->uNumFloors; ++i)
+  {
+    auto pFloor = &pIndoor->pFaces[pSector->pFloors[i]];
+    if (pFloor->Clickable())
+      continue;
+
+    assert(pFloor->uNumVertices);
+    if (x <= pFloor->pBounding.x2 && x >= pFloor->pBounding.x1 &&
+        y <= pFloor->pBounding.y2 && y >= pFloor->pBounding.y1)
+    {
+      for (uint j = 0; j < pFloor->uNumVertices; ++j)
+      {
+        word_721460_xs[2 * j] =     pFloor->pXInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j]].x;
+        word_721460_xs[2 * j + 1] = pFloor->pXInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j + 1]].x;
+        word_721390_ys[2 * j] =     pFloor->pYInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j]].y;
+        word_721390_ys[2 * j + 1] = pFloor->pYInterceptDisplacements[j] + pIndoor->pVertices[pFloor->pVertexIDs[j + 1]].y;
+      }
+      word_721460_xs[2 * pFloor->uNumVertices] = word_721460_xs[0];
+      word_721390_ys[2 * pFloor->uNumVertices] = word_721390_ys[0];
+
+      v50 = word_721390_ys[0] >= y;
+      v53 = 0;
+
+      for (uint j = 0; j < 2 * pFloor->uNumVertices; ++j)
+      {
+        if (v53 >= 2)
+          break;
+
+        v48 = v50;
+        v50 = word_721390_ys[j + 1] >= y;
+
+          v13 = i;
+          if (v48 == v50)
+            continue;
+
+            v14 = word_721460_xs[j + 1] >= x ? 0 : 2;
+            v15 = v14 | (word_721460_xs[j] < x);
+
+          if (v15 == 3)
+            continue;
+          else if (!v15)
+            ++v53;
+          else
+          {
+            auto a_div_b = fixpoint_div(y - word_721390_ys[j], word_721390_ys[j + 1] - word_721390_ys[j]);
+            auto res = fixpoint_sub0((signed int)word_721460_xs[j + 1] - (signed int)word_721460_xs[j], a_div_b);
+
+            if (res + word_721460_xs[j] >= x)
+                ++v53;
+          }
+      }
+
+
+        if ( v53 == 1 )
+        {
+          if ( v55 >= 50 )
+            break;
+          if ( pFloor->uPolygonType == POLYGON_Floor || pFloor->uPolygonType == POLYGON_Ceiling )
+          {
+            v21 = pIndoor->pVertices[pFloor->pVertexIDs[0]].z;
+          }
+          else
+          {
+            v21 = fixpoint_sub0(pFloor->zCalc1, x) + fixpoint_sub0(pFloor->zCalc2, y) + (short)(pFloor->zCalc3 >> 16);
+          }
+          blv_floor_level[v55] = v21;
+          blv_floor_id[v55] = pSector->pFloors[i];
+          v55++;
+        }
+    }
+  }
+
+
+  if ( pSector->field_0 & 8 )
+  {
+    for (uint i = 0; i < pSector->uNumPortals; ++i)
+    {
+      auto portal = &pIndoor->pFaces[pSector->pPortals[i]];
+      if (portal->uPolygonType != POLYGON_Floor)
+        continue;
+
+      if (!portal->uNumVertices)
+        continue;
+
+      if (x <= portal->pBounding.x2 && x >= portal->pBounding.x1 &&
+          y <= portal->pBounding.y2 && y >= portal->pBounding.y1 )
+      {
+        for (uint j = 0; j < portal->uNumVertices; ++j)
+        {
+          word_721460_xs[2 * j] =     portal->pXInterceptDisplacements[j] + pIndoor->pVertices[portal->pVertexIDs[j]].x;
+          word_721460_xs[2 * j + 1] = portal->pXInterceptDisplacements[j + 1] + pIndoor->pVertices[portal->pVertexIDs[j + 1]].x;
+          word_721390_ys[2 * j] =     portal->pYInterceptDisplacements[j] + pIndoor->pVertices[portal->pVertexIDs[j]].y;
+          word_721390_ys[2 * j + 1] = portal->pYInterceptDisplacements[j + 1] + pIndoor->pVertices[portal->pVertexIDs[j + 1]].y;
+        }
+        word_721460_xs[2 * portal->uNumVertices] = word_721460_xs[0];
+        word_721390_ys[2 * portal->uNumVertices] = word_721390_ys[0];
+        v54 = 0;
+        v47 = word_721390_ys[0] >= y;
+
+          for (uint j = 0; j < 2 * portal->uNumVertices; ++j)
+          {
+            v49 = v47;
+            if ( v54 >= 2 )
+              break;
+            v47 = word_721390_ys[j + 1] >= y;
+            if ( v49 != v47 )
+            {
+              v28 = word_721460_xs[j + 1] >= x ? 0 : 2;
+              v29 = v28 | (word_721460_xs[j] < x);
+              if ( v29 != 3 )
+              {
+                if ( !v29 )
+                  ++v54;
+                else
+                {
+                  auto a_div_b = fixpoint_div(y - word_721390_ys[j], word_721390_ys[j + 1] - word_721390_ys[j]);
+                  auto res = fixpoint_sub0(word_721460_xs[j + 1] - word_721460_xs[j], a_div_b);
+                  if (res + word_721460_xs[j] >= x)
+                    ++v54;
+                }
+              }
+            }
+          }
+          if ( v54 == 1 )
+          {
+            if ( v55 >= 50 )
+              break;
+            blv_floor_level[v55] = -29000;
+            blv_floor_id[v55] = pSector->pPortals[i];
+            v55++;
+          }
+      }
+    }
+  }
+  if ( v55 == 1 )
+  {
+    *pFaceID = blv_floor_id[0];
+    return blv_floor_level[0];
+  }
+  if ( !v55 )
+    return -30000;
+  *pFaceID = blv_floor_id[0];
+  //result = blv_floor_level[0];
+
+    /*for ( v35 = 1; v35 < v55; ++v35 )
+    {
+      if ( blv_floor_level[0] <= z + 5 )
+      {
+        if ( blv_floor_level[v35] >= blv_floor_level[0] || blv_floor_level[v35] > z + 5 )
+          continue;
+        blv_floor_level[0] = blv_floor_level[v35];
+        *pFaceID = blv_floor_id[v35];
+        continue;
+      }
+      if ( blv_floor_level[v35] < blv_floor_level[0] )
+      {
+        blv_floor_level[0] = blv_floor_level[v35];
+        *pFaceID = blv_floor_id[v35];
+      }
+    }*/
+
+    
+  int result = blv_floor_level[0];
+  for (uint i = 1; i < v55; ++i)
+  {
+      v38 = blv_floor_level[i];
+      if ( result <= z + 5 )
+      {
+        if ( v38 > result && v38 <= z + 5 )
+        {
+          result = blv_floor_level[i];
+          *pFaceID = blv_floor_id[i];
+        }
+      }
+      else if ( v38 < result )
+      {
+        result = blv_floor_level[i];
+        *pFaceID = blv_floor_id[i];
+      }
+  }
+
+  return result;
+}
+//----- (004016FA) --------------------------------------------------------
+int __cdecl MakeActorAIList_BLV()
+{
+  Actor *v0; // esi@2
+  int v1; // eax@4
+  int v2; // ebx@4
+  unsigned int v3; // ecx@4
+  int v4; // edx@5
+  int v5; // edx@7
+  unsigned int v6; // edx@9
+  unsigned int v7; // ST24_4@10
+  int v8; // eax@10
+  int v9; // edi@10
+  int v10; // ebx@14
+  char v11; // zf@16
+  int v12; // eax@22
+  int v13; // edx@24
+  int v14; // ecx@25
+  int v15; // ebx@26
+  unsigned int *v16; // ecx@27
+  unsigned int v17; // esi@27
+  int v18; // ecx@31
+  signed int v19; // edi@31
+  Actor *v20; // esi@32
+  bool v21; // eax@33
+  int v22; // eax@34
+  signed int v23; // ebx@36
+  Actor *v24; // esi@37
+  signed int v25; // eax@40
+  int v26; // eax@43
+  int v27; // ebx@45
+  int j; // edi@45
+  unsigned int v29; // eax@46
+  int v30; // eax@48
+  int v31; // ecx@51
+  int v32; // eax@51
+  signed int v33; // eax@53
+  __int64 v34; // qax@55
+  char *v35; // ecx@56
+  int v37; // [sp+Ch] [bp-18h]@1
+  int v38; // [sp+10h] [bp-14h]@4
+  int v39; // [sp+14h] [bp-10h]@4
+  int v40; // [sp+18h] [bp-Ch]@10
+  int v41; // [sp+18h] [bp-Ch]@29
+  int i; // [sp+18h] [bp-Ch]@31
+  signed int v43; // [sp+1Ch] [bp-8h]@1
+  signed int v44; // [sp+1Ch] [bp-8h]@25
+  int v45; // [sp+20h] [bp-4h]@1
+
+//  __debugbreak(); // refactor for blv ai
+  pParty->uFlags &= 0xFFFFFFCFu;
+  v37 = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
+  v45 = 0;
+  v43 = 0;
+  if ( (signed int)uNumActors > 0 )
+  {
+    v0 = pActors.data();//[0].uAttributes;
+    do
+    {
+      BYTE1(v0->uAttributes) &= 0xFBu;
+      if ( ! v0->CanAct() )
+        goto LABEL_60;
+	  v39 = abs(pParty->vPosition.z - v0->vPosition.z);
+	  v38 = abs(pParty->vPosition.y - v0->vPosition.y);
+	  v1 = abs(pParty->vPosition.x - v0->vPosition.x);
+      v2 = v38;
+      v3 = v39;
+      if ( v1 < v38 )
+      {
+        v4 = v1;
+        v1 = v38;
+        v2 = v4;
+      }
+      if ( v1 < v39 )
+      {
+        v5 = v1;
+        v1 = v39;
+        v3 = v5;
+      }
+      if ( v2 < (signed int)v3 )
+      {
+        v6 = v3;
+        v3 = v2;
+        v2 = v6;
+      }
+      v7 = ((unsigned int)(11 * v2) >> 5) + (v3 >> 2) + v1;
+      v8 = v0->uActorRadius;
+      v9 = v7 - v8;
+      v40 = v7 - v8;
+      if ( v40 < 0 )
+      {
+        v9 = 0;
+        v40 = 0;
+      }
+      if ( v9 < 10240 )
+      {
+        v10 = v0->uAttributes & 0xFEFFFFFF;
+        v0->uAttributes = v10;
+        if ( v10 & 0x80000 || v0->GetActorsRelation(0) )
+        {
+          v11 = (pParty->uFlags & 0x10) == 0;
+          v0->uAttributes = v10 | 0x1000000;
+          if ( v11 && (double)v40 < 307.2 )
+            pParty->uFlags |= 0x10u;
+          if ( !(pParty->uFlags & 0x20) && v9 < 5120 )
+            pParty->uFlags |= 0x20u;
+        }
+        v12 = v45++;
+        ai_near_actors_distances[v12] = v9;
+        ai_near_actors_ids[v12] = v43;
+      }
+      else
+      {
+LABEL_60:
+        BYTE1(v0->uAttributes) &= 0xBFu;
+      }
+      ++v43;
+      ++v0;
+    }
+    while ( v43 < (signed int)uNumActors );
+  }
+  v13 = 0;
+  if ( v45 > 0 )
+  {
+    v14 = 1;
+    v44 = 1;
+    do
+    {
+      while ( 1 )
+      {
+        v41 = v14;
+        if ( v14 >= v45 )
+          break;
+        v15 = ai_near_actors_distances[v13];
+        if ( v15 > ai_near_actors_distances[v14] )
+        {
+          v16 = &ai_near_actors_ids[v14];
+          v17 = ai_near_actors_ids[v13];
+          ai_near_actors_ids[v13] = *v16;
+          *v16 = v17;
+          v14 = v41;
+          ai_near_actors_distances[v13] = ai_near_actors_distances[v41];
+          ai_near_actors_distances[v41] = v15;
+        }
+        ++v14;
+      }
+      ++v13;
+      v14 = v44 + 1;
+      v44 = v14;
+    }
+    while ( v14 - 1 < v45 );
+  }
+  v18 = 0;
+  v19 = 0;
+  for ( i = 0; v18 < v45; i = v18 )
+  {
+    v20 = &pActors[ai_near_actors_ids[v18]];
+    if ( v20->uAttributes & 0x8000
+      || (v21 = sub_4070EF_prolly_collide_objects(PID(OBJECT_Actor,ai_near_actors_ids[v18]), 4u), v18 = i, v21) )
+    {
+      v22 = ai_near_actors_ids[v18];
+      v20->uAttributes |= 0x8000u;
+      ai_array_4F6638_actor_ids[v19] = v22;
+      ai_array_4F5E68[v19++] = ai_near_actors_distances[v18];
+      if ( v19 >= 30 )
+        break;
+    }
+    ++v18;
+  }
+  v23 = 0;
+  ai_arrays_size = v19;
+  if ( (signed int)uNumActors > 0 )
+  {
+    v24 = pActors.data();//[0].uAttributes;
+    do
+    {
+      if ( v24->CanAct() && v24->uSectorID == v37 )
+      {
+        v25 = 0;
+        if ( v19 <= 0 )
+        {
+LABEL_43:
+          v26 = ai_arrays_size;
+          BYTE1(v24->uAttributes) |= 0x40u;
+          ++ai_arrays_size;
+          ai_array_4F6638_actor_ids[v26] = v23;
+        }
+        else
+        {
+          while ( ai_array_4F6638_actor_ids[v25] != v23 )
+          {
+            ++v25;
+            if ( v25 >= v19 )
+              goto LABEL_43;
+          }
+        }
+      }
+      ++v23;
+      ++v24;
+    }
+    while ( v23 < (signed int)uNumActors );
+  }
+  v27 = ai_arrays_size;
+  for ( j = 0; j < v45; ++j )
+  {
+    v29 = ai_near_actors_ids[j];
+    if ( pActors[v29].uAttributes & 0xC000 && pActors[v29].CanAct() )
+    {
+      v30 = 0;
+      if ( v27 <= 0 )
+      {
+LABEL_51:
+        v31 = ai_arrays_size;
+        v32 = ai_near_actors_ids[j];
+        ++ai_arrays_size;
+        ai_array_4F6638_actor_ids[v31] = v32;
+      }
+      else
+      {
+        while ( ai_array_4F6638_actor_ids[v30] != ai_near_actors_ids[j] )
+        {
+          ++v30;
+          if ( v30 >= v27 )
+            goto LABEL_51;
+        }
+      }
+    }
+  }
+  v33 = ai_arrays_size;
+  if ( ai_arrays_size > 30 )
+  {
+    v33 = 30;
+    ai_arrays_size = 30;
+  }
+  memcpy(ai_near_actors_ids.data(), ai_array_4F6638_actor_ids.data(), 4 * v33);
+  memcpy(ai_near_actors_distances.data(), ai_array_4F5E68.data(), 4 * ai_arrays_size);
+  v34 = (unsigned int)ai_arrays_size;
+  if ( ai_arrays_size > 0 )
+  {
+    do
+    {
+      v35 = (char *)&pActors[ai_near_actors_ids[HIDWORD(v34)]].uAttributes;
+      v35[1] |= 4u;
+      ++HIDWORD(v34);
+    }
+    while ( SHIDWORD(v34) < (signed int)v34 );
+  }
+  return v34;
+}
+//----- (0043FDED) --------------------------------------------------------
+void PrepareActorRenderList_BLV()
+{
+  RenderBillboard *v0; // esi@0
+  unsigned __int16 v3; // ax@3
+  unsigned int v4; // eax@5
+  unsigned __int16 v5; // cx@5
+  int v6; // esi@5
+  unsigned int v7; // eax@7
+  int v8; // eax@10
+  SpriteFrame *v9; // eax@16
+  SpriteFrame *v10; // ebx@18
+  //int *v11; // eax@18
+  int v12; // ecx@28
+  //IndoorCameraD3D **v14; // eax@36
+  double v15; // st7@36
+  float v16; // eax@36
+  //double v17; // ST30_8@36
+  signed __int64 v18; // qtt@36
+  int v19; // ST5C_4@36
+  signed __int64 v20; // qtt@37
+  int v21; // ST5C_4@37
+  signed __int16 v22; // cx@39
+  int v23; // ST50_4@40
+  signed int v24; // ecx@40
+  int v25; // edx@44
+  __int16 v26; // ax@44
+  //MonsterDesc *v27; // edx@44
+  //int v28; // ecx@44
+  unsigned __int8 v29; // zf@44
+  unsigned __int8 v30; // sf@44
+  unsigned int v31; // [sp-8h] [bp-5Ch]@15
+  int v32; // [sp+1Ch] [bp-38h]@5
+  int a3; // [sp+20h] [bp-34h]@5
+  int a2; // [sp+24h] [bp-30h]@5
+  int a1a; // [sp+28h] [bp-2Ch]@5
+  __int16 a5; // [sp+2Ch] [bp-28h]@5
+  int a5a; // [sp+2Ch] [bp-28h]@36
+  int a5b; // [sp+2Ch] [bp-28h]@40
+  __int16 v41; // [sp+3Ch] [bp-18h]@18
+  int a6; // [sp+40h] [bp-14h]@34
+  int v43; // [sp+44h] [bp-10h]@34
+  int z; // [sp+48h] [bp-Ch]@32
+  signed int y; // [sp+4Ch] [bp-8h]@32
+  int x; // [sp+50h] [bp-4h]@32
+
+  for (uint i = 0; i < uNumActors; ++i)
+  {
+    auto p = &pActors[i];
+
+    if (p->uAIState == Removed ||
+        p->uAIState == Disabled)
+      continue;
+
+    a5 = p->uSectorID;
+    a2 = p->vPosition.y;
+    a1a = p->vPosition.x;
+    a3 = p->vPosition.z;
+    v4 = stru_5C6E00->Atan2(a1a - pBLVRenderParams->vPartyPos.x, a2 - pBLVRenderParams->vPartyPos.y);
+    LOWORD(v0) = p->uYawAngle;
+    v5 = p->uCurrentActionAnimation;
+    v6 = ((signed int)((char *)v0 + ((signed int)stru_5C6E00->uIntegerPi >> 3) - v4 + stru_5C6E00->uIntegerPi) >> 8) & 7;
+    v32 = v6;
+    if ( pParty->bTurnBasedModeOn )
+    {
+      if ( v5 == 1 )
+      {
+        v7 = pMiscTimer->uTotalGameTimeElapsed;
+        goto LABEL_10;
+      }
+    }
+    else
+    {
+      if ( v5 == 1 )
+      {
+        v7 = pBLVRenderParams->field_0_timer_;
+LABEL_10:
+        v8 = i * 32 + v7;
+        goto LABEL_12;
+      }
+    }
+    v8 = p->uCurrentActionTime;
+LABEL_12:
+    if (p->pActorBuffs[5].uExpireTime > 0i64 || p->pActorBuffs[6].uExpireTime > 0i64 )
+      v8 = 0;
+    v31 = p->pSpriteIDs[v5];
+    if (p->uAIState == Resurrected)
+      v9 = pSpriteFrameTable->GetFrameBy_x(v31, v8);
+    else
+      v9 = pSpriteFrameTable->GetFrame(v31, v8);
+    v41 = 0;
+    v10 = v9;
+    //v11 = (int *)v9->uFlags;
+    if (v9->uFlags & 2)
+      v41 = 2;
+    if (v9->uFlags & 0x40000)
+      v41 |= 0x40u;
+    if (v9->uFlags & 0x20000)
+      LOBYTE(v41) = v41 | 0x80;
+    v0 = (RenderBillboard *)(256 << v6);
+    if ( (unsigned int)v0 & v9->uFlags)
+      v41 |= 4u;
+    if ( v10->uGlowRadius )
+    {
+      //LOBYTE(v11) = byte_4E94D3;
+      pMobileLightsStack->AddLight(
+        a1a,
+        a2,
+        a3,
+        a5,
+        v10->uGlowRadius,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        byte_4E94D3);
+    }
+    v12 = 0;
+    if ( pBspRenderer->uNumVisibleNotEmptySectors <= 0 )
+      continue;
+    while (pBspRenderer->pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[v12] != p->uSectorID)
+    {
+      ++v12;
+      if ( v12 >= pBspRenderer->uNumVisibleNotEmptySectors )
+        goto _continue;
+    }
+    if ( !pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(a1a, a2, a3, &x, &y, &z, 1)
+      || (v0 = (RenderBillboard *)abs(x), (signed int)v0 < abs(y)) )
+      continue;
+    pGame->pIndoorCameraD3D->Project(x, y, z, &v43, &a6);
+    v0 = &pBillboardRenderList[uNumBillboardsToDraw];
+    if (uNumBillboardsToDraw >= 500)
+      break;
+    ++uNumBillboardsToDraw;
+    ++uNumSpritesDrawnThisFrame;
+    p->uAttributes |= 8u;
+    v29 = pRenderer->pRenderD3D == 0;
+    v0->uHwSpriteID = v10->pHwSpriteIDs[v32];
+    v0->uPalette = v10->uPaletteIndex;
+    v0->uIndoorSectorID = a5;
+    if ( v29 )
+    {
+      LODWORD(v20) = pBLVRenderParams->field_40 << 16;
+      HIDWORD(v20) = pBLVRenderParams->field_40 >> 16;
+      v21 = v20 / x;
+      v0->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v10->scale * v20 / x) >> 16;
+      a5a = (unsigned __int64)(v10->scale * (signed __int64)v21) >> 16;
+    }
+    else
+    {
+      //v14 = &pGame->pIndoorCameraD3D;
+      v0->fov_x = pGame->pIndoorCameraD3D->fov_x;
+      v15 = pGame->pIndoorCameraD3D->fov_y;
+      v16 = v0->fov_x;
+      v0->fov_y = v15;
+      //v17 = v16 + 6.7553994e15;
+      LODWORD(v18) = 0;
+      HIDWORD(v18) = floorf(v16 + 0.5f);
+      v19 = v18 / x;
+      v0->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v10->scale * v18 / x) >> 16;
+      a5a = (unsigned __int64)(v10->scale * (signed __int64)v19) >> 16;
+    }
+    v0->_screenspace_y_scaler_packedfloat = a5a;
+    if ( (signed __int64)p->pActorBuffs[3].uExpireTime <= 0 )
+    {
+      if ( (signed __int64)p->pActorBuffs[10].uExpireTime > 0 )
+      {
+        a5b = (unsigned __int64)(pGame->pStru6Instance->_4A806F(p) * (signed __int64)v0->_screenspace_y_scaler_packedfloat) >> 16;
+        goto LABEL_43;
+      }
+    }
+    else
+    {
+      v22 = p->pActorBuffs[3].uPower;
+      if ( v22 )
+      {
+        v23 = (unsigned __int64)(65536 / (unsigned __int16)v22 * (signed __int64)v0->_screenspace_x_scaler_packedfloat) >> 16;
+        v24 = p->pActorBuffs[3].uPower;
+        v0->_screenspace_x_scaler_packedfloat = v23;
+        a5b = (unsigned __int64)(65536 / v24 * (signed __int64)v0->_screenspace_y_scaler_packedfloat) >> 16;
+LABEL_43:
+        v0->_screenspace_y_scaler_packedfloat = a5b;
+        goto LABEL_44;
+      }
+    }
+LABEL_44:
+    HIWORD(v25) = HIWORD(x);
+    v0->world_x = a1a;
+    v0->world_y = a2;
+    v0->world_z = a3;
+    v0->uScreenSpaceX = v43;
+    v0->uScreenSpaceY = a6;
+    LOWORD(v25) = 0;
+    LOBYTE(v26) = v41;
+
+    //v0->sZValue = v25 + (PID(OBJECT_Actor,i));
+    v0->actual_z = HIWORD(x);
+    v0->object_pid = PID(OBJECT_Actor,i);
+
+    v29 = HIDWORD(p->pActorBuffs[5].uExpireTime) == 0;
+    v30 = HIDWORD(p->pActorBuffs[5].uExpireTime) < 0;
+    v0->field_1E = v41;
+    v0->pSpriteFrame = v10;
+    v0->uTintColor = pMonsterList->pMonsters[p->pMonsterInfo.uID - 1].uTintColor;
+    if ( !v30 && (!(v30 | v29) || LODWORD(p->pActorBuffs[5].uExpireTime)) )
+    {
+      HIBYTE(v26) = HIBYTE(v41) | 1;
+      v0->field_1E = v26;
+    }
+    
+_continue:
+    ;
+  }
+}
+//----- (0044028F) --------------------------------------------------------
+void PrepareItemsRenderList_BLV()
+{
+  ObjectDesc *v1; // ebx@4
+  __int16 v2; // ax@5
+  RenderBillboard *v3; // esi@12
+  SpriteFrame *v4; // eax@12
+  SpriteFrame *v5; // ebx@12
+  unsigned int v6; // eax@12
+  int v7; // ecx@12
+  int v8; // edx@12
+  int v9; // ecx@12
+  unsigned __int16 v10; // ax@12
+  int *v11; // eax@20
+  //char v12; // zf@26
+  __int64 v18; // ST5C_4@27
+  signed __int64 v19; // qtt@28
+  int v20; // ST5C_4@28
+  //int v21; // edx@29
+  __int16 v22; // ax@29
+  //int v23; // eax@29
+  SpriteFrame *v24; // [sp+1Ch] [bp-40h]@12
+  //__int16 a5; // [sp+28h] [bp-34h]@12
+  int a6; // [sp+2Ch] [bp-30h]@12
+  int a2; // [sp+30h] [bp-2Ch]@12
+  int a1; // [sp+34h] [bp-28h]@12
+  int v30; // [sp+38h] [bp-24h]@12
+  int v31; // [sp+38h] [bp-24h]@27
+  int a3; // [sp+40h] [bp-1Ch]@12
+  signed __int16 v34; // [sp+44h] [bp-18h]@14
+  int v35; // [sp+48h] [bp-14h]@25
+  int v36; // [sp+4Ch] [bp-10h]@25
+  signed int z; // [sp+50h] [bp-Ch]@24
+  signed int y; // [sp+54h] [bp-8h]@24
+  signed int x; // [sp+58h] [bp-4h]@24
+
+  for (uint i = 0; i < uNumSpriteObjects; ++i)
+  {
+    auto p = &pSpriteObjects[i];
+    if (p->uObjectDescID)
+    {
+      v1 = &pObjectList->pObjects[p->uObjectDescID];
+        if ( !(v1->uFlags & 1) )
+         {
+          if ( ((v2 = p->uType, v2 < 1000) || v2 >= 10000)
+            && (v2 < 500 || v2 >= 600)
+            && (v2 < 811 || v2 >= 815)
+            || pGame->pStru6Instance->_4A81CA(p))
+          {
+            //a5 = p->uSectorID;
+            a1 = p->vPosition.x;
+            a2 = p->vPosition.y;
+            a3 = p->vPosition.z;
+            v3 = &pBillboardRenderList[uNumBillboardsToDraw];
+            v4 = pSpriteFrameTable->GetFrame(v1->uSpriteID, p->uSpriteFrameID);
+            v5 = v4;
+            v24 = v4;
+            v30 = v4->uFlags;
+            a6 = v4->uGlowRadius * p->field_22_glow_radius_multiplier;
+            v6 = stru_5C6E00->Atan2(p->vPosition.x - pBLVRenderParams->vPartyPos.x,
+                                    p->vPosition.y - pBLVRenderParams->vPartyPos.y);
+            LOWORD(v7) = p->uFacing;
+            v8 = v30;
+            v9 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + v7 - v6) >> 8) & 7;
+            v10 = v5->pHwSpriteIDs[v9];
+            v3->uHwSpriteID = v10;
+            if ( v30 & 0x20 )
+            {
+              v8 = v30;
+              a3 -= (signed int)((unsigned __int64)(v5->scale * (signed __int64)pSprites_LOD->pSpriteHeaders[(signed __int16)v10].uHeight) >> 16) >> 1;
+            }
+            v34 = 0;
+            if ( v8 & 2 )
+              v34 = 2;
+            if ( v8 & 0x40000 )
+              v34 |= 0x40u;
+            if ( v8 & 0x20000 )
+              LOBYTE(v34) = v34 | 0x80;
+            v11 = (int *)(256 << v9);
+            if ( (256 << v9) & v8 )
+              v34 |= 4u;
+            if ( a6 )
+            {
+              LOBYTE(v11) = byte_4E94D3;
+              pMobileLightsStack->AddLight(
+                a1,
+                a2,
+                a3,
+                p->uSectorID,
+                a6,
+                v1->uParticleTrailColorR,
+                v1->uParticleTrailColorG,
+                v1->uParticleTrailColorB,
+                byte_4E94D3);
+            }
+            if ( pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(
+                   a1,
+                   a2,
+                   a3,
+                   &x,
+                   &y,
+                   &z,
+                   1) )
+            {
+              pGame->pIndoorCameraD3D->Project(x, y, z, &v36, &v35);
+
+              assert(uNumBillboardsToDraw < 500);
+              //if ( (signed int)uNumBillboardsToDraw >= 500 )
+              //  return;
+              ++uNumBillboardsToDraw;
+              ++uNumSpritesDrawnThisFrame;
+              p->uAttributes |= 1u;
+              //v12 = pRenderer->pRenderD3D == 0;
+              v3->uPalette = v24->uPaletteIndex;
+              v3->uIndoorSectorID = p->uSectorID;
+              if ( pRenderer->pRenderD3D )
+              {
+                v3->fov_x = pGame->pIndoorCameraD3D->fov_x;
+                v3->fov_y = pGame->pIndoorCameraD3D->fov_y;
+                LODWORD(v18) = 0;
+                HIDWORD(v18) = (int)floorf(v3->fov_x + 0.5f);
+                v18 = v18 / x;
+                v3->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v24->scale * v18) >> 16;
+                v31 = (unsigned __int64)(v24->scale * v18) >> 16;
+              }
+              else
+              {
+                LODWORD(v19) = pBLVRenderParams->field_40 << 16;
+                HIDWORD(v19) = pBLVRenderParams->field_40 >> 16;
+                v20 = v19 / x;
+                v3->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v24->scale * v19 / x) >> 16;
+                v31 = (unsigned __int64)(v24->scale * (signed __int64)v20) >> 16;
+              }
+              //HIWORD(v21) = HIWORD(x);
+              //LOWORD(v21) = 0;
+              v3->_screenspace_y_scaler_packedfloat = v31;
+              v3->field_1E = v34;
+              v3->world_x = a1;
+              v3->world_y = a2;
+              v3->world_z = a3;
+              v3->uScreenSpaceX = v36;
+              v22 = v35;
+              v3->uTintColor = 0;
+              v3->uScreenSpaceY = v22;
+              //v23 = 8 * i;
+              //LOBYTE(v23) = PID(OBJECT_Item,i);
+              v3->pSpriteFrame = v24;
+              //v12 = (p->uAttributes & 0x20) == 0;
+              //v3->sZValue = v21 + v23;
+              v3->actual_z = HIWORD(x);
+              v3->object_pid = PID(OBJECT_Item,i);
+              if (p->uAttributes & 0x20)
+              {
+                if ( !pRenderer->pRenderD3D )
+                  v3->sZValue = 0;
+              }
+            }
+          }
+        }
+      }
+  }
+}
+
+//----- (00440639) --------------------------------------------------------
+void AddBspNodeToRenderList(unsigned int node_id)
+{
+  BLVSector *pSector; // esi@1
+
+  pSector = &pIndoor->pSectors[pBspRenderer->nodes[node_id].uSectorID];
+  if ( pRenderer->pRenderD3D )
+  {
+    for (uint i = 0; i < pSector->uNumNonBSPFaces; ++i)
+      //Log::Warning(L"Non-BSP face: %X", v3->pFaceIDs[v2]);
+      pBspRenderer->AddFaceToRenderList_d3d(node_id, pSector->pFaceIDs[i]);
+  }
+  else
+  {
+    for (uint i = 0; i < pSector->uNumNonBSPFaces; ++i)
+      pBspRenderer->AddFaceToRenderList_sw(node_id, pSector->pFaceIDs[i]);
+  }
+  if ( pSector->field_0 & 0x10 )
+    sub_4406BC(node_id, pSector->uFirstBSPNode);
+}
+
+//----- (004406BC) --------------------------------------------------------
+void __fastcall sub_4406BC(unsigned int node_id, unsigned int uFirstNode)
+{
+  BLVSector *pSector; // esi@2
+  BSPNode *pNode; // edi@2
+  BLVFace *pFace; // eax@2
+  int v5; // ecx@2
+  __int16 v6; // ax@6
+  int v7; // ebp@10
+  int v8; // ebx@10
+  __int16 v9; // di@18
+  //int v10; // [sp+10h] [bp-Ch]@1
+  //bool v11; // [sp+14h] [bp-8h]@5
+  BspRenderer_stru0 *node; // [sp+18h] [bp-4h]@1
+
+  //Log::Warning(L"sub_4406BC(%u, %u)", a1, uFirstNode);
+
+  //v10 = a1;
+  node = &pBspRenderer->nodes[node_id];
+  while ( 1 )
+  {
+    pSector = &pIndoor->pSectors[node->uSectorID];
+    pNode = &pIndoor->pNodes[uFirstNode];
+    pFace = &pIndoor->pFaces[pSector->pFaceIDs[pNode->uCoplanarOffset]];
+    v5 = pFace->pFacePlane_old.dist + pBLVRenderParams->vPartyPos.x * pFace->pFacePlane_old.vNormal.x
+       + pBLVRenderParams->vPartyPos.y * pFace->pFacePlane_old.vNormal.y + pBLVRenderParams->vPartyPos.z * pFace->pFacePlane_old.vNormal.z;//plane equation
+    if (pFace->Portal() && pFace->uSectorID != node->uSectorID )
+      v5 = -v5;
+    //v11 = v5 > 0;
+    if ( v5 <= 0 )
+      v6 = pNode->uFront;
+    else
+      v6 = pNode->uBack;
+    if ( v6 != -1 )
+      sub_4406BC(node_id, v6);
+    v7 = pNode->uCoplanarOffset;
+    v8 = v7 + pNode->uCoplanarSize;
+
+    //Log::Warning(L"Node %u: %X to %X (%hX)", uFirstNode, v7, v8, v2->pFaceIDs[v7]);
+    
+    if ( pRenderer->pRenderD3D )
+    {
+      while ( v7 < v8 )
+        pBspRenderer->AddFaceToRenderList_d3d(node_id, pSector->pFaceIDs[v7++]);
+    }
+    else
+    {
+      while ( v7 < v8 )
+        pBspRenderer->AddFaceToRenderList_sw(node_id, pSector->pFaceIDs[v7++]);
+    }
+    v9 = v5 > 0 ? pNode->uFront : pNode->uBack;
+    if ( v9 == -1 )
+      break;
+    uFirstNode = v9;
+  }
+}
+//----- (0043FA33) --------------------------------------------------------
+void __fastcall PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID)
+{
+  LevelDecoration *v2; // esi@1
+  DecorationDesc *v3; // ebx@2
+  __int16 v4; // ax@2
+  double v5; // st7@3
+  int v6; // eax@5
+  int v7; // edx@5
+  unsigned int v8; // edi@5
+  int v9; // edi@5
+  int v10; // eax@7
+  SpriteFrame *v11; // eax@7
+  SpriteFrame *v12; // esi@7
+  int v13; // eax@7
+  int v14; // ebx@16
+  RenderBillboard *v15; // ecx@17
+  char v16; // zf@18
+  IndoorCameraD3D **v17; // eax@19
+  double v18; // st7@19
+  //float v19; // eax@19
+  signed __int64 v20; // qtt@19
+  signed __int64 v21; // qtt@20
+  //int v22; // edx@21
+  //int v23; // eax@21
+  Particle_sw local_0; // [sp+Ch] [bp-A0h]@3
+  //double v25; // [sp+74h] [bp-38h]@19
+  //unsigned int v26; // [sp+7Ch] [bp-30h]@1
+  int a2; // [sp+80h] [bp-2Ch]@5
+  int a3; // [sp+84h] [bp-28h]@5
+  int a1; // [sp+88h] [bp-24h]@5
+  int v30; // [sp+8Ch] [bp-20h]@7
+  //float v31; // [sp+90h] [bp-1Ch]@1
+  int a5; // [sp+94h] [bp-18h]@17
+  int z; // [sp+98h] [bp-14h]@15
+  int a6; // [sp+9Ch] [bp-10h]@17
+  int y; // [sp+A0h] [bp-Ch]@15
+  int x; // [sp+A4h] [bp-8h]@15
+  int v37; // [sp+A8h] [bp-4h]@5
+
+  //v26 = uDecorationID;
+  //LODWORD(v31) = uSectorID;
+  v2 = &pLevelDecorations[uDecorationID];
+  if (v2->field_2 & 0x20)
+    return;
+
+    v3 = &pDecorationList->pDecorations[v2->uDecorationDescID];
+    v4 = v3->uFlags;
+    if (v3->uFlags & DECORATION_EMITS_FIRE)
+    {
+      memset(&local_0, 0, 0x68u);               // fire,  like at the Pit's tavern
+      v5 = (double)v2->vPosition.x;
+      local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8;
+      local_0.uDiffuse = 0xFF3C1E;
+      local_0.x = v5;
+      local_0.y = (double)v2->vPosition.y;
+      local_0.z = (double)v2->vPosition.z;
+      local_0.flt_10 = 0.0;
+      local_0.flt_14 = 0.0;
+      local_0.flt_18 = 0.0;
+      local_0.flt_28 = 1.0;
+      local_0.timeToLive = (rand() & 0x80) + 128;
+      local_0.uTextureID = pBitmaps_LOD->LoadTexture("effpar01");
+      pGame->pParticleEngine->AddParticle(&local_0);
+      return;
+    }
+
+
+      if (v4 & DECORATION_DONT_DRAW)
+        return;
+
+        v6 = v2->vPosition.x;
+        v7 = v2->vPosition.z;
+        a2 = v2->vPosition.y;
+        a1 = v6;
+        a3 = v7;
+        v8 = v2->field_10_y_rot
+           + ((signed int)stru_5C6E00->uIntegerPi >> 3)
+           - stru_5C6E00->Atan2(v6 - pBLVRenderParams->vPartyPos.x, a2 - pBLVRenderParams->vPartyPos.y);
+        v37 = pBLVRenderParams->field_0_timer_;
+        v9 = ((signed int)(stru_5C6E00->uIntegerPi + v8) >> 8) & 7;
+        if (pParty->bTurnBasedModeOn)
+          v37 = pMiscTimer->uTotalGameTimeElapsed;
+        v10 = abs(v2->vPosition.x + v2->vPosition.y);
+        v11 = pSpriteFrameTable->GetFrame(v3->uSpriteID, v37 + v10);
+        v30 = 0;
+        v12 = v11;
+        v13 = v11->uFlags;
+        if ( v13 & 2 )
+          v30 = 2;
+        if ( v13 & 0x40000 )
+          v30 |= 0x40u;
+        if ( v13 & 0x20000 )
+          LOBYTE(v30) = v30 | 0x80;
+        if ( (256 << v9) & v13 )
+          v30 |= 4u;
+        if ( pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(a1, a2, a3, &x, &y, &z, 1) )
+        {
+          v14 = abs(x);
+          if ( v14 >= abs(y) )
+          {
+            pGame->pIndoorCameraD3D->Project(x, y, z, &a5, &a6);
+
+            v15 = &pBillboardRenderList[uNumBillboardsToDraw];
+            assert(uNumBillboardsToDraw < 500);
+
+              ++uNumBillboardsToDraw;
+              ++uNumDecorationsDrawnThisFrame;
+              v16 = pRenderer->pRenderD3D == 0;
+              v15->uHwSpriteID = v12->pHwSpriteIDs[v9];
+              v15->uPalette = v12->uPaletteIndex;
+              v15->uIndoorSectorID = uSectorID;
+              if ( v16 )
+              {
+                LODWORD(v21) = pBLVRenderParams->field_40 << 16;
+                HIDWORD(v21) = pBLVRenderParams->field_40 >> 16;
+                v37 = v21 / x;
+                //LODWORD(v31) = v12->scale;
+                v37 = v21 / x;
+                v15->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v12->scale * v21 / x) >> 16;
+                v37 = (unsigned __int64)(v12->scale * (signed __int64)v37) >> 16;
+              }
+              else
+              {
+                v17 = &pGame->pIndoorCameraD3D;
+                v15->fov_x = pGame->pIndoorCameraD3D->fov_x;
+                v18 = (*v17)->fov_y;
+                //v19 = v15->fov_x;
+                v15->fov_y = v18;
+                //v31 = v19;
+                //v25 = v19 + 6.7553994e15;
+                //v25 = floorf(v15->fov_x + 0.5f);
+                LODWORD(v20) = 0;
+                HIDWORD(v20) = floorf(v15->fov_x + 0.5f);
+                v37 = v20 / x;
+                //LODWORD(v31) = v12->scale;
+                v37 = (unsigned __int64)(v12->scale * v20 / x) >> 16;
+                v15->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v12->scale * v20 / x) >> 16;
+                //v31 = v15->fov_y;
+                //v25 = v31 + 6.7553994e15;
+                //v25 = floorf(v15->fov_y + 0.5f);
+                LODWORD(v20) = 0;
+                HIDWORD(v20) = floorf(v15->fov_y + 0.5f);
+                v37 = v20 / x;
+                v37 = (unsigned __int64)(v12->scale * v20 / x) >> 16;
+              }
+              //HIWORD(v22) = HIWORD(x);
+              //LOWORD(v22) = 0;
+              v15->_screenspace_y_scaler_packedfloat = v37;
+              v15->field_1E = v30;
+              v15->world_x = a1;
+              v15->world_y = a2;
+              v15->world_z = a3;
+              v15->uScreenSpaceX = a5;
+              v15->uScreenSpaceY = a6;
+              //v23 = 8 * uDecorationID;
+              //LOBYTE(v23) = PID(OBJECT_Decoration,uDecorationID);
+
+              //v15->sZValue = v22 + v23;
+              v15->actual_z = HIWORD(x);
+              v15->object_pid = PID(OBJECT_Decoration,uDecorationID);
+
+              v15->uTintColor = 0;
+              v15->pSpriteFrame = v12;
+          }
+        }
+}
+//----- (0043F953) --------------------------------------------------------
+void PrepareBspRenderList_BLV()
+{
+  pBspRenderer->num_faces = 0;
+
+  if (pBLVRenderParams->uPartySectorID)
+  {
+    pBspRenderer->nodes[0].uSectorID = pBLVRenderParams->uPartySectorID;
+    pBspRenderer->nodes[0].uViewportW = pBLVRenderParams->uViewportW;
+    pBspRenderer->nodes[0].uViewportZ = pBLVRenderParams->uViewportZ;
+    pBspRenderer->nodes[0].uViewportY = pBLVRenderParams->uViewportY;
+    pBspRenderer->nodes[0].uViewportX = pBLVRenderParams->uViewportX;
+    pBspRenderer->nodes[0].field_C.GetViewportData(pBLVRenderParams->uViewportX, pBLVRenderParams->uViewportY,
+                                           pBLVRenderParams->uViewportZ, pBLVRenderParams->uViewportW);
+    pBspRenderer->nodes[0].uFaceID = -1;
+    pBspRenderer->nodes[0].viewing_portal_id = -1;
+    pBspRenderer->num_nodes = 1;
+    AddBspNodeToRenderList(0);
+  }
+
+  pBspRenderer->MakeVisibleSectorList();
+}
+
+//----- (0043F9E1) --------------------------------------------------------
+void BspRenderer_stru2::GetViewportData(__int16 x, int y, __int16 z, int w)
+{
+  _viewport_space_y = y;
+  _viewport_space_w = w;
+
+  for (uint i = 0; i < 480; ++i)
+  {
+    if ( i < y || i > w )
+    {
+      viewport_left_side[i] = 640;
+      viewport_right_side[i] = -1;
+    }
+    else
+    {
+      viewport_left_side[i] = x;
+      viewport_right_side[i] = z;
+    } 
+  }
+}
+//----- (0048653D) --------------------------------------------------------
+int stru149::_48653D(int a2, int a3, int a4, int a5, int a6, int a7)//portal frustum culling
+{
+  stru149 *v7; // esi@1
+  int v8; // edi@1
+  int v9; // eax@1
+  //int v10; // edx@1
+  //int v11; // ecx@1
+  int v12; // eax@1
+  int v13; // ebx@2
+  int v14; // ecx@2
+  int v15; // eax@2
+  int v16; // ST14_4@3
+  int v17; // ST10_4@3
+  int v18; // eax@5
+  int v19; // ST10_4@6
+  int v20; // eax@8
+  int v21; // ST10_4@9
+  int v22; // eax@10
+  int v23; // ecx@10
+  int v24; // eax@10
+  int result; // eax@10
+  //int v26; // [sp+14h] [bp-14h]@1
+  int v27; // [sp+18h] [bp-10h]@1
+  int v28; // [sp+1Ch] [bp-Ch]@1
+  int v29; // [sp+24h] [bp-4h]@1
+  int v30; // [sp+30h] [bp+8h]@10
+  int v31; // [sp+3Ch] [bp+14h]@10
+
+  v7 = this;
+  v8 = stru_5C6E00->Cos(pBLVRenderParams->sPartyRotY);
+  v29 = stru_5C6E00->Sin(pBLVRenderParams->sPartyRotY);
+  v28 = stru_5C6E00->Cos(pBLVRenderParams->sPartyRotX);
+  v9 = stru_5C6E00->Sin(pBLVRenderParams->sPartyRotX);
+  //v11 = -pBLVRenderParams->vPartyPos.y;
+  //v26 = -pBLVRenderParams->vPartyPos.x;
+  v27 = v9;
+  v12 = -pBLVRenderParams->vPartyPos.z;
+  if ( pBLVRenderParams->sPartyRotX )
+  {
+    v16 = v8 * -pBLVRenderParams->vPartyPos.x + v29 * -pBLVRenderParams->vPartyPos.y;
+    v13 = v28;
+    v17 = -65536 * pBLVRenderParams->vPartyPos.z;
+    v7->field_0_party_dir_x = ((unsigned __int64)(v16 * (signed __int64)v28) >> 16)
+                + ((unsigned __int64)(-65536 * pBLVRenderParams->vPartyPos.z * (signed __int64)v27) >> 16);
+    v7->field_4_party_dir_y = v8 * -pBLVRenderParams->vPartyPos.y - v29 * -pBLVRenderParams->vPartyPos.x;
+    v14 = v27;
+    v15 = ((unsigned __int64)(v17 * (signed __int64)v28) >> 16) - ((unsigned __int64)(v16 * (signed __int64)v27) >> 16);
+  }
+  else
+  {
+    v7->field_0_party_dir_x = v8 * -pBLVRenderParams->vPartyPos.x + v29 * -pBLVRenderParams->vPartyPos.y;
+    v13 = v28;
+    v7->field_4_party_dir_y = v8 * -pBLVRenderParams->vPartyPos.y - v29 * -pBLVRenderParams->vPartyPos.x;
+    v14 = v27;
+    v15 = v12 << 16;
+  }
+  v7->field_8 = v15;
+  if ( pBLVRenderParams->sPartyRotX )
+  {
+    v19 = ((unsigned __int64)(a2 * (signed __int64)v8) >> 16) + ((unsigned __int64)(a3 * (signed __int64)v29) >> 16);
+    v7->field_C = ((unsigned __int64)(v19 * (signed __int64)v13) >> 16)
+                + ((unsigned __int64)(a4 * (signed __int64)v14) >> 16);
+    v7->field_10 = ((unsigned __int64)(a3 * (signed __int64)v8) >> 16)
+                 - ((unsigned __int64)(a2 * (signed __int64)v29) >> 16);
+    v18 = ((unsigned __int64)(a4 * (signed __int64)v13) >> 16) - ((unsigned __int64)(v19 * (signed __int64)v14) >> 16);
+  }
+  else
+  {
+    v7->field_C = ((unsigned __int64)(a2 * (signed __int64)v8) >> 16)
+                + ((unsigned __int64)(a3 * (signed __int64)v29) >> 16);
+    v7->field_10 = ((unsigned __int64)(a3 * (signed __int64)v8) >> 16)
+                 - ((unsigned __int64)(a2 * (signed __int64)v29) >> 16);
+    v18 = a4;
+  }
+  v7->field_14 = v18;
+  if ( pBLVRenderParams->sPartyRotX )
+  {
+    v21 = ((unsigned __int64)(a5 * (signed __int64)v8) >> 16) + ((unsigned __int64)(a6 * (signed __int64)v29) >> 16);
+    v7->field_18 = ((unsigned __int64)(v21 * (signed __int64)v13) >> 16)
+                 + ((unsigned __int64)(a7 * (signed __int64)v14) >> 16);
+    v7->field_1C = ((unsigned __int64)(a6 * (signed __int64)v8) >> 16)
+                 - ((unsigned __int64)(a5 * (signed __int64)v29) >> 16);
+    v20 = ((unsigned __int64)(a7 * (signed __int64)v13) >> 16) - ((unsigned __int64)(v21 * (signed __int64)v14) >> 16);
+  }
+  else
+  {
+    v7->field_18 = ((unsigned __int64)(a5 * (signed __int64)v8) >> 16)
+                 + ((unsigned __int64)(a6 * (signed __int64)v29) >> 16);
+    v7->field_1C = ((unsigned __int64)(a6 * (signed __int64)v8) >> 16)
+                 - ((unsigned __int64)(a5 * (signed __int64)v29) >> 16);
+    v20 = a7;
+  }
+  v7->field_18 = -v7->field_18;
+  v7->field_1C = -v7->field_1C;
+  v7->field_20 = v20;
+  v22 = v7->field_C;
+  v7->field_20 = -v7->field_20;
+  v23 = ((unsigned __int64)(v22 * (signed __int64)v7->field_0_party_dir_x) >> 16)
+      + ((unsigned __int64)(v7->field_10 * (signed __int64)v7->field_4_party_dir_y) >> 16)
+      + ((unsigned __int64)(v7->field_14 * (signed __int64)v7->field_8) >> 16);
+  v30 = v7->field_18;
+  v24 = v7->field_0_party_dir_x;
+  v7->field_24 = v23;
+  v31 = (unsigned __int64)(v30 * (signed __int64)v24) >> 16;
+  result = (unsigned __int64)(v7->field_1C * (signed __int64)v7->field_4_party_dir_y) >> 16;
+  v7->field_28 = v31 + result + ((unsigned __int64)(v7->field_20 * (signed __int64)v7->field_8) >> 16);
+  return result;
+}
+//----- (00407A1C) --------------------------------------------------------
+bool __fastcall sub_407A1C(int x, int z, int y, Vec3_int_ v)
+{
+  unsigned int v4; // esi@1
+  Vec3_int_ v5; // ST08_12@2
+  int v6; // edi@2
+  int v7; // ebx@2
+  int v8; // esi@2
+  signed int v9; // ecx@2
+  int v10; // eax@2
+  int v11; // ecx@4
+  int v12; // eax@4
+  int v13; // ebx@4
+  int v14; // edx@6
+  char *v15; // edi@16
+  ODMFace *v16; // esi@19
+  int v17; // ST34_4@25
+  int v18; // ST38_4@25
+  int v19; // eax@25
+  char v20; // zf@25
+  int v21; // ebx@25
+  int v22; // eax@26
+  signed int v23; // edi@26
+  int v24; // ST34_4@30
+  signed __int64 v25; // qtt@31
+  int v26; // eax@31
+  Vec3_int_ v27; // ST08_12@37
+  Vec3_int_ v28; // ST08_12@37
+  int v29; // edi@37
+  int v30; // ebx@37
+  int v31; // esi@37
+  signed int v32; // ecx@37
+  int v33; // eax@37
+  int v34; // ecx@39
+  int v35; // eax@39
+  int v36; // ebx@39
+  int v37; // edx@41
+  char *v38; // edi@51
+  ODMFace *v39; // esi@54
+  int v40; // ebx@60
+  int v41; // eax@61
+  signed int v42; // edi@61
+  signed __int64 v43; // qtt@66
+  int v44; // eax@66
+  Vec3_int_ v45; // ST08_12@73
+  int v46; // edi@73
+  int v47; // ebx@73
+  int v48; // esi@73
+  signed int v49; // ecx@73
+  int v50; // eax@73
+  int v51; // edx@75
+  int v52; // ecx@75
+  int v53; // eax@75
+  int v54; // ebx@75
+  int v55; // edi@77
+  int v56; // ecx@77
+  int v57; // eax@81
+  int v58; // esi@81
+  int v59; // eax@90
+  BLVSector *v60; // edx@90
+  int v61; // ecx@90
+  BLVFace *v62; // esi@91
+  int v63; // ST34_4@98
+  int v64; // ST30_4@98
+  int v65; // eax@98
+  int v66; // ebx@98
+  int v67; // eax@99
+  signed int v68; // edi@99
+  int v69; // ST2C_4@103
+  signed __int64 v70; // qtt@104
+  int v71; // eax@104
+  Vec3_int_ v72; // ST08_12@111
+  Vec3_int_ v73; // ST08_12@111
+  int v74; // edi@111
+  int v75; // ebx@111
+  int v76; // esi@111
+  signed int v77; // ecx@111
+  int v78; // eax@111
+  int v79; // edx@113
+  int v80; // ecx@113
+  int v81; // eax@113
+  int v82; // ebx@113
+  int v83; // edi@115
+  int v84; // ecx@115
+  int v85; // eax@119
+  int v86; // esi@119
+  int v87; // ecx@128
+  BLVSector *v88; // eax@128
+  int v89; // ecx@128
+  BLVFace *v90; // esi@129
+  int v91; // ebx@136
+  int v92; // eax@137
+  signed int v93; // edi@137
+  signed __int64 v94; // qtt@142
+  int v95; // eax@142
+  Vec3_int_ v97; // [sp-18h] [bp-94h]@1
+  int v98; // [sp-Ch] [bp-88h]@88
+  int v99; // [sp-Ch] [bp-88h]@126
+  int v100; // [sp-8h] [bp-84h]@88
+  int v101; // [sp-8h] [bp-84h]@126
+  int v102; // [sp-4h] [bp-80h]@88
+  int v103; // [sp-4h] [bp-80h]@126
+  int v104; // [sp+Ch] [bp-70h]@13
+  int v105; // [sp+Ch] [bp-70h]@48
+  int v106; // [sp+10h] [bp-6Ch]@18
+  int v107; // [sp+10h] [bp-6Ch]@98
+  int v108; // [sp+10h] [bp-6Ch]@104
+  int v109; // [sp+18h] [bp-64h]@25
+  int v110; // [sp+18h] [bp-64h]@31
+  int i; // [sp+18h] [bp-64h]@90
+  int v112; // [sp+18h] [bp-64h]@128
+  signed int v113; // [sp+20h] [bp-5Ch]@1
+  signed int v114; // [sp+24h] [bp-58h]@1
+  unsigned __int64 a4; // [sp+28h] [bp-54h]@1
+  unsigned int a4_8; // [sp+30h] [bp-4Ch]@1
+  int v117; // [sp+34h] [bp-48h]@4
+  int v118; // [sp+34h] [bp-48h]@39
+  int v119; // [sp+34h] [bp-48h]@75
+  int v120; // [sp+34h] [bp-48h]@113
+  int v121; // [sp+38h] [bp-44h]@4
+  int v122; // [sp+38h] [bp-44h]@39
+  int v123; // [sp+38h] [bp-44h]@76
+  int v124; // [sp+38h] [bp-44h]@114
+  int v125; // [sp+3Ch] [bp-40h]@4
+  int v126; // [sp+3Ch] [bp-40h]@39
+  int v127; // [sp+3Ch] [bp-40h]@77
+  int v128; // [sp+3Ch] [bp-40h]@115
+  int v129; // [sp+40h] [bp-3Ch]@11
+  int v130; // [sp+40h] [bp-3Ch]@46
+  int v131; // [sp+40h] [bp-3Ch]@78
+  int v132; // [sp+40h] [bp-3Ch]@116
+  int v133; // [sp+44h] [bp-38h]@10
+  int v134; // [sp+44h] [bp-38h]@45
+  int v135; // [sp+44h] [bp-38h]@81
+  int v136; // [sp+44h] [bp-38h]@119
+  int v137; // [sp+48h] [bp-34h]@7
+  int v138; // [sp+48h] [bp-34h]@42
+  int v139; // [sp+48h] [bp-34h]@82
+  int v140; // [sp+48h] [bp-34h]@120
+  int v141; // [sp+4Ch] [bp-30h]@6
+  int v142; // [sp+4Ch] [bp-30h]@41
+  int v143; // [sp+4Ch] [bp-30h]@75
+  int v144; // [sp+4Ch] [bp-30h]@113
+  int v145; // [sp+50h] [bp-2Ch]@5
+  int v146; // [sp+50h] [bp-2Ch]@40
+  int v147; // [sp+50h] [bp-2Ch]@75
+  int v148; // [sp+50h] [bp-2Ch]@113
+  int v149; // [sp+54h] [bp-28h]@4
+  int v150; // [sp+54h] [bp-28h]@39
+  int v151; // [sp+54h] [bp-28h]@75
+  int v152; // [sp+54h] [bp-28h]@113
+  int sDepth; // [sp+58h] [bp-24h]@17
+  int sDeptha; // [sp+58h] [bp-24h]@52
+  int sDepthb; // [sp+58h] [bp-24h]@90
+  char *a5; // [sp+5Ch] [bp-20h]@16
+  char *a5a; // [sp+5Ch] [bp-20h]@51
+  signed int a5b; // [sp+5Ch] [bp-20h]@83
+  signed int a5c; // [sp+5Ch] [bp-20h]@121
+  signed int v160; // [sp+60h] [bp-1Ch]@12
+  signed int v161; // [sp+60h] [bp-1Ch]@47
+  int v162; // [sp+60h] [bp-1Ch]@128
+  int v163; // [sp+64h] [bp-18h]@2
+  int outx; // [sp+68h] [bp-14h]@2
+  int outy; // [sp+6Ch] [bp-10h]@2
+  int outz; // [sp+70h] [bp-Ch]@2
+  Vec3_int_ pOut; // [sp+74h] [bp-8h]@2
+  int ya; // [sp+84h] [bp+8h]@60
+  int yb; // [sp+84h] [bp+8h]@136
+  int ve; // [sp+88h] [bp+Ch]@60
+  int va; // [sp+88h] [bp+Ch]@60
+  int vb; // [sp+88h] [bp+Ch]@66
+  int vf; // [sp+88h] [bp+Ch]@136
+  int vc; // [sp+88h] [bp+Ch]@136
+  int vd; // [sp+88h] [bp+Ch]@142
+  int v_4; // [sp+8Ch] [bp+10h]@60
+  int v_4a; // [sp+8Ch] [bp+10h]@65
+  int v_4b; // [sp+8Ch] [bp+10h]@136
+  int v_4c; // [sp+8Ch] [bp+10h]@141
+  int v_8; // [sp+90h] [bp+14h]@53
+
+  a4 = __PAIR__(z, x);
+  v4 = stru_5C6E00->Atan2(v.x - x, v.y - z);
+  v114 = 0;
+  v97.z = y;
+  v113 = 0;
+  a4_8 = v4;
+  *(_QWORD *)&v97.x = a4;
+  if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor)
+  {
+    Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v97, &pOut.x, &pOut.y, &outz);
+    v45.z = v.z;
+    *(_QWORD *)&v45.x = *(_QWORD *)&v;
+    Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v45, &outx, &outy, &v163);
+    v46 = outy - pOut.y;
+    v47 = v163 - outz;
+    v48 = outx - pOut.x;
+    v49 = integer_sqrt(v48 * v48 + v46 * v46 + v47 * v47);
+    v50 = 65536;
+    if ( v49 )
+      v50 = 65536 / v49;
+    v51 = outx;
+    v143 = v48 * v50;
+    v52 = v46 * v50;
+    v53 = v47 * v50;
+    v54 = pOut.x;
+    v147 = v52;
+    v151 = v53;
+    v119 = pOut.x;
+    if ( pOut.x < outx )
+    {
+      v123 = outx;
+    }
+    else
+    {
+      v119 = outx;
+      v123 = pOut.x;
+    }
+    v55 = pOut.y;
+    v56 = outy;
+    v127 = pOut.y;
+    if ( pOut.y < outy )
+    {
+      v131 = outy;
+    }
+    else
+    {
+      v127 = outy;
+      v131 = pOut.y;
+    }
+    v57 = v163;
+    v58 = outz;
+    v135 = outz;
+    if ( outz < v163 )
+    {
+      v139 = v163;
+    }
+    else
+    {
+      v135 = v163;
+      v139 = outz;
+    }
+    a5b = 0;
+    while ( !v114 )
+    {
+      if ( a5b )
+      {
+        v102 = v58;
+        v100 = v55;
+        v98 = v54;
+      }
+      else
+      {
+        v102 = v57;
+        v100 = v56;
+        v98 = v51;
+      }
+      v59 = pIndoor->GetSector(v98, v100, v102);
+      v60 = pIndoor->pSectors;
+      v61 = 116 * v59;
+      sDepthb = 0;
+      for ( i = 116 * v59;
+            sDepthb < *(__int16 *)((char *)&pIndoor->pSectors->uNumWalls + v61)
+                    + 2 * *(__int16 *)((char *)&pIndoor->pSectors->uNumFloors + v61);
+            ++sDepthb )
+      {
+        v62 = &pIndoor->pFaces[(*(unsigned __int16 **)((char *)&v60->pWalls + v61))[sDepthb]];
+        if ( v62->Portal()
+          || v119 > v62->pBounding.x2
+          || v123 < v62->pBounding.x1
+          || v127 > v62->pBounding.y2
+          || v131 < v62->pBounding.y1
+          || v135 > v62->pBounding.z2
+          || v139 < v62->pBounding.z1
+          || (v63 = (unsigned __int64)(v143 * (signed __int64)v62->pFacePlane_old.vNormal.x) >> 16,
+              v64 = (unsigned __int64)(v151 * (signed __int64)v62->pFacePlane_old.vNormal.z) >> 16,
+              v65 = (unsigned __int64)(v147 * (signed __int64)v62->pFacePlane_old.vNormal.y) >> 16,
+              v20 = v63 + v64 + v65 == 0,
+              v66 = v63 + v64 + v65,
+              v107 = v63 + v64 + v65,
+              v20) )
+          goto LABEL_107;
+        v67 = outz * v62->pFacePlane_old.vNormal.z;
+        v68 = -(v62->pFacePlane_old.dist
+              + v67
+              + pOut.y * v62->pFacePlane_old.vNormal.y
+              + pOut.x * v62->pFacePlane_old.vNormal.x);
+        if ( v66 <= 0 )
+        {
+          if ( v62->pFacePlane_old.dist
+             + v67
+             + pOut.y * v62->pFacePlane_old.vNormal.y
+             + pOut.x * v62->pFacePlane_old.vNormal.x < 0 )
+            goto LABEL_107;
+        }
+        else
+        {
+          if ( v62->pFacePlane_old.dist
+             + v67
+             + pOut.y * v62->pFacePlane_old.vNormal.y
+             + pOut.x * v62->pFacePlane_old.vNormal.x > 0 )
+            goto LABEL_107;
+        }
+        v69 = abs(-(v62->pFacePlane_old.dist
+                  + v67
+                  + pOut.y * v62->pFacePlane_old.vNormal.y
+                  + pOut.x * v62->pFacePlane_old.vNormal.x)) >> 14;
+        if ( v69 <= abs(v66) )
+        {
+          LODWORD(v70) = v68 << 16;
+          HIDWORD(v70) = v68 >> 16;
+          v71 = v70 / v107;
+          v108 = v70 / v107;
+          if ( v71 >= 0 )
+          {
+            if ( sub_4075DB(
+                   pOut.x + ((signed int)(((unsigned __int64)(v108 * (signed __int64)v143) >> 16) + 32768) >> 16),
+                   pOut.y + ((signed int)(((unsigned __int64)(v108 * (signed __int64)v147) >> 16) + 32768) >> 16),
+                   outz + ((signed int)(((unsigned __int64)(v108 * (signed __int64)v151) >> 16) + 32768) >> 16),
+                   v62) )
+            {
+              v114 = 1;
+              break;
+            }
+          }
+        }
+        v61 = i;
+LABEL_107:
+        v60 = pIndoor->pSectors;
+      }
+      ++a5b;
+      if ( a5b >= 2 )
+        break;
+      v57 = v163;
+      v56 = outy;
+      v51 = outx;
+      v58 = outz;
+      v55 = pOut.y;
+      v54 = pOut.x;
+    }
+    v72.z = y;
+    *(_QWORD *)&v72.x = a4;
+    Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v72, &pOut.x, &pOut.y, &outz);
+    v73.z = v.z;
+    *(_QWORD *)&v73.x = *(_QWORD *)&v;
+    Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v73, &outx, &outy, &v163);
+    v74 = outy - pOut.y;
+    v75 = v163 - outz;
+    v76 = outx - pOut.x;
+    v77 = integer_sqrt(v76 * v76 + v74 * v74 + v75 * v75);
+    v78 = 65536;
+    if ( v77 )
+      v78 = 65536 / v77;
+    v79 = outx;
+    v144 = v76 * v78;
+    v80 = v74 * v78;
+    v81 = v75 * v78;
+    v82 = pOut.x;
+    v148 = v80;
+    v152 = v81;
+    v120 = pOut.x;
+    if ( pOut.x < outx )
+    {
+      v124 = outx;
+    }
+    else
+    {
+      v120 = outx;
+      v124 = pOut.x;
+    }
+    v83 = pOut.y;
+    v84 = outy;
+    v128 = pOut.y;
+    if ( pOut.y < outy )
+    {
+      v132 = outy;
+    }
+    else
+    {
+      v128 = outy;
+      v132 = pOut.y;
+    }
+    v85 = v163;
+    v86 = outz;
+    v136 = outz;
+    if ( outz < v163 )
+    {
+      v140 = v163;
+    }
+    else
+    {
+      v136 = v163;
+      v140 = outz;
+    }
+    a5c = 0;
+    while ( 1 )
+    {
+      if ( v113 )
+        return !v114 || !v113;
+      if ( a5c )
+      {
+        v103 = v86;
+        v101 = v83;
+        v99 = v82;
+      }
+      else
+      {
+        v103 = v85;
+        v101 = v84;
+        v99 = v79;
+      }
+      v87 = pIndoor->GetSector(v99, v101, v103);
+      v88 = pIndoor->pSectors;
+      v89 = 116 * v87;
+      v162 = 0;
+      v112 = v89;
+      if ( *(__int16 *)((char *)&pIndoor->pSectors->uNumWalls + v89)
+         + 2 * *(__int16 *)((char *)&pIndoor->pSectors->uNumFloors + v89) > 0 )
+        break;
+LABEL_148:
+      ++a5c;
+      if ( a5c >= 2 )
+        return !v114 || !v113;
+      v85 = v163;
+      v84 = outy;
+      v79 = outx;
+      v86 = outz;
+      v83 = pOut.y;
+      v82 = pOut.x;
+    }
+    while ( 1 )
+    {
+      v90 = &pIndoor->pFaces[(*(unsigned __int16 **)((char *)&v88->pWalls + v89))[v162]];
+      if ( v90->Portal()
+        || v120 > v90->pBounding.x2
+        || v124 < v90->pBounding.x1
+        || v128 > v90->pBounding.y2
+        || v132 < v90->pBounding.y1
+        || v136 > v90->pBounding.z2
+        || v140 < v90->pBounding.z1
+        || (yb = (unsigned __int64)(v144 * (signed __int64)v90->pFacePlane_old.vNormal.x) >> 16,
+            v_4b = (unsigned __int64)(v148 * (signed __int64)v90->pFacePlane_old.vNormal.y) >> 16,
+            vf = (unsigned __int64)(v152 * (signed __int64)v90->pFacePlane_old.vNormal.z) >> 16,
+            v20 = yb + vf + v_4b == 0,
+            v91 = yb + vf + v_4b,
+            vc = yb + vf + v_4b,
+            v20) )
+        goto LABEL_145;
+      v92 = outz * v90->pFacePlane_old.vNormal.z;
+      v93 = -(v90->pFacePlane_old.dist
+            + v92
+            + pOut.y * v90->pFacePlane_old.vNormal.y
+            + pOut.x * v90->pFacePlane_old.vNormal.x);
+      if ( v91 <= 0 )
+      {
+        if ( v90->pFacePlane_old.dist
+           + v92
+           + pOut.y * v90->pFacePlane_old.vNormal.y
+           + pOut.x * v90->pFacePlane_old.vNormal.x < 0 )
+          goto LABEL_145;
+      }
+      else
+      {
+        if ( v90->pFacePlane_old.dist
+           + v92
+           + pOut.y * v90->pFacePlane_old.vNormal.y
+           + pOut.x * v90->pFacePlane_old.vNormal.x > 0 )
+          goto LABEL_145;
+      }
+      v_4c = abs(-(v90->pFacePlane_old.dist
+                 + v92
+                 + pOut.y * v90->pFacePlane_old.vNormal.y
+                 + pOut.x * v90->pFacePlane_old.vNormal.x)) >> 14;
+      if ( v_4c <= abs(v91) )
+      {
+        LODWORD(v94) = v93 << 16;
+        HIDWORD(v94) = v93 >> 16;
+        v95 = v94 / vc;
+        vd = v94 / vc;
+        if ( v95 >= 0 )
+        {
+          if ( sub_4075DB(
+                 pOut.x + ((signed int)(((unsigned __int64)(vd * (signed __int64)v144) >> 16) + 32768) >> 16),
+                 pOut.y + ((signed int)(((unsigned __int64)(vd * (signed __int64)v148) >> 16) + 32768) >> 16),
+                 outz + ((signed int)(((unsigned __int64)(vd * (signed __int64)v152) >> 16) + 32768) >> 16),
+                 v90) )
+          {
+            v113 = 1;
+            goto LABEL_148;
+          }
+        }
+      }
+      v89 = v112;
+LABEL_145:
+      v88 = pIndoor->pSectors;
+      ++v162;
+      if ( v162 >= *(__int16 *)((char *)&pIndoor->pSectors->uNumWalls + v89)
+                 + 2 * *(__int16 *)((char *)&pIndoor->pSectors->uNumFloors + v89) )
+        goto LABEL_148;
+    }
+  }
+  Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v97, &pOut.x, &pOut.y, &outz);
+  v5.z = v.z;
+  *(_QWORD *)&v5.x = *(_QWORD *)&v;
+  Vec3_int_::Rotate(32, stru_5C6E00->uIntegerHalfPi + v4, 0, v5, &outx, &outy, &v163);
+  v6 = outy - pOut.y;
+  v7 = v163 - outz;
+  v8 = outx - pOut.x;
+  v9 = integer_sqrt(v8 * v8 + v6 * v6 + v7 * v7);
+  v10 = 65536;
+  if ( v9 )
+    v10 = 65536 / v9;
+  v125 = v8 * v10;
+  v11 = v10;
+  v12 = v7 * v10;
+  v13 = pOut.x;
+  v117 = v12;
+  v121 = v6 * v11;
+  v149 = pOut.x;
+  if ( pOut.x < outx )
+  {
+    v145 = outx;
+  }
+  else
+  {
+    v149 = outx;
+    v145 = pOut.x;
+  }
+  v14 = outy;
+  v141 = pOut.y;
+  if ( pOut.y < outy )
+  {
+    v137 = outy;
+  }
+  else
+  {
+    v141 = outy;
+    v137 = pOut.y;
+  }
+  v133 = outz;
+  if ( outz < v163 )
+  {
+    v129 = v163;
+  }
+  else
+  {
+    v133 = v163;
+    v129 = outz;
+  }
+  v160 = 0;
+  if ( (signed int)pOutdoor->uNumBModels > 0 )
+  {
+    v104 = 0;
+    while ( 1 )
+    {
+      v15 = (char *)&pOutdoor->pBModels[v104].pVertices;
+      a5 = (char *)&pOutdoor->pBModels[v104].pVertices;
+      if ( sub_4088E9(v13, pOut.y, outx, v14, pOutdoor->pBModels[v104].vPosition.x, pOutdoor->pBModels[v104].vPosition.y) <= pOutdoor->pBModels[v104].sBoundingRadius + 128 )
+      {
+        sDepth = 0;
+        if ( *((int *)v15 + 2) > 0 )
+          break;
+      }
+LABEL_36:
+      ++v160;
+      ++v104;
+      if ( v160 >= (signed int)pOutdoor->uNumBModels )
+        goto LABEL_37;
+      v14 = outy;
+      v13 = pOut.x;
+    }
+    v106 = 0;
+    while ( 1 )
+    {
+      v16 = (ODMFace *)(v106 + *((int *)a5 + 4));
+      if ( v149 > v16->pBoundingBox.x2
+        || v145 < v16->pBoundingBox.x1
+        || v141 > v16->pBoundingBox.y2
+        || v137 < v16->pBoundingBox.y1
+        || v133 > v16->pBoundingBox.z2
+        || v129 < v16->pBoundingBox.z1
+        || (v17 = (unsigned __int64)(v125 * (signed __int64)v16->pFacePlane.vNormal.x) >> 16,
+            v18 = (unsigned __int64)(v121 * (signed __int64)v16->pFacePlane.vNormal.y) >> 16,
+            v19 = (unsigned __int64)(v117 * (signed __int64)v16->pFacePlane.vNormal.z) >> 16,
+            v20 = v17 + v18 + v19 == 0,
+            v21 = v17 + v18 + v19,
+            v109 = v17 + v18 + v19,
+            v20) )
+        goto LABEL_33;
+      v22 = pOut.y * v16->pFacePlane.vNormal.y;
+      v23 = -(v16->pFacePlane.dist + v22 + outz * v16->pFacePlane.vNormal.z + pOut.x * v16->pFacePlane.vNormal.x);
+      if ( v21 <= 0 )
+      {
+        if ( v16->pFacePlane.dist + v22 + outz * v16->pFacePlane.vNormal.z + pOut.x * v16->pFacePlane.vNormal.x < 0 )
+          goto LABEL_33;
+      }
+      else
+      {
+        if ( v16->pFacePlane.dist + v22 + outz * v16->pFacePlane.vNormal.z + pOut.x * v16->pFacePlane.vNormal.x > 0 )
+          goto LABEL_33;
+      }
+      v24 = abs(-(v16->pFacePlane.dist + v22 + outz * v16->pFacePlane.vNormal.z + pOut.x * v16->pFacePlane.vNormal.x)) >> 14;
+      if ( v24 <= abs(v21) )
+      {
+        LODWORD(v25) = v23 << 16;
+        HIDWORD(v25) = v23 >> 16;
+        v26 = v25 / v109;
+        v110 = v25 / v109;
+        if ( v26 >= 0 )
+        {
+          if ( sub_4077F1(
+                 pOut.x + ((signed int)(((unsigned __int64)(v110 * (signed __int64)v125) >> 16) + 32768) >> 16),
+                 pOut.y + ((signed int)(((unsigned __int64)(v110 * (signed __int64)v121) >> 16) + 32768) >> 16),
+                 outz + ((signed int)(((unsigned __int64)(v110 * (signed __int64)v117) >> 16) + 32768) >> 16),
+                 v16,
+                 (BSPVertexBuffer *)a5) )
+          {
+            v114 = 1;
+            goto LABEL_36;
+          }
+        }
+      }
+LABEL_33:
+      ++sDepth;
+      v106 += 308;
+      if ( sDepth >= *((int *)a5 + 2) )
+        goto LABEL_36;
+    }
+  }
+LABEL_37:
+  v27.z = y;
+  *(_QWORD *)&v27.x = a4;
+  Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v27, &pOut.x, &pOut.y, &outz);
+  v28.z = v.z;
+  *(_QWORD *)&v28.x = *(_QWORD *)&v;
+  Vec3_int_::Rotate(32, a4_8 - stru_5C6E00->uIntegerHalfPi, 0, v28, &outx, &outy, &v163);
+  v29 = outy - pOut.y;
+  v30 = v163 - outz;
+  v31 = outx - pOut.x;
+  v32 = integer_sqrt(v31 * v31 + v29 * v29 + v30 * v30);
+  v33 = 65536;
+  if ( v32 )
+    v33 = 65536 / v32;
+  v126 = v31 * v33;
+  v34 = v33;
+  v35 = v30 * v33;
+  v36 = pOut.x;
+  v118 = v35;
+  v122 = v29 * v34;
+  v150 = pOut.x;
+  if ( pOut.x < outx )
+  {
+    v146 = outx;
+  }
+  else
+  {
+    v150 = outx;
+    v146 = pOut.x;
+  }
+  v37 = outy;
+  v142 = pOut.y;
+  if ( pOut.y < outy )
+  {
+    v138 = outy;
+  }
+  else
+  {
+    v142 = outy;
+    v138 = pOut.y;
+  }
+  v134 = outz;
+  if ( outz < v163 )
+  {
+    v130 = v163;
+  }
+  else
+  {
+    v134 = v163;
+    v130 = outz;
+  }
+  v161 = 0;
+  if ( (signed int)pOutdoor->uNumBModels > 0 )
+  {
+    v105 = 0;
+    while ( 1 )
+    {
+      v38 = (char *)&pOutdoor->pBModels[v105].pVertices;
+      a5a = (char *)&pOutdoor->pBModels[v105].pVertices;
+      if ( sub_4088E9(v36, pOut.y, outx, v37, pOutdoor->pBModels[v105].vPosition.x, pOutdoor->pBModels[v105].vPosition.y) <= pOutdoor->pBModels[v105].sBoundingRadius + 128 )
+      {
+        sDeptha = 0;
+        if ( *((int *)v38 + 2) > 0 )
+          break;
+      }
+LABEL_71:
+      ++v161;
+      ++v105;
+      if ( v161 >= (signed int)pOutdoor->uNumBModels )
+        return !v114 || !v113;
+      v37 = outy;
+      v36 = pOut.x;
+    }
+    v_8 = 0;
+    while ( 1 )
+    {
+      v39 = (ODMFace *)(v_8 + *((int *)a5a + 4));
+      if ( v150 > v39->pBoundingBox.x2
+        || v146 < v39->pBoundingBox.x1
+        || v142 > v39->pBoundingBox.y2
+        || v138 < v39->pBoundingBox.y1
+        || v134 > v39->pBoundingBox.z2
+        || v130 < v39->pBoundingBox.z1
+        || (ya = (unsigned __int64)(v126 * (signed __int64)v39->pFacePlane.vNormal.x) >> 16,
+            ve = (unsigned __int64)(v122 * (signed __int64)v39->pFacePlane.vNormal.y) >> 16,
+            v_4 = (unsigned __int64)(v118 * (signed __int64)v39->pFacePlane.vNormal.z) >> 16,
+            v20 = ya + ve + v_4 == 0,
+            v40 = ya + ve + v_4,
+            va = ya + ve + v_4,
+            v20) )
+        goto LABEL_68;
+      v41 = pOut.y * v39->pFacePlane.vNormal.y;
+      v42 = -(v39->pFacePlane.dist + v41 + outz * v39->pFacePlane.vNormal.z + pOut.x * v39->pFacePlane.vNormal.x);
+      if ( v40 <= 0 )
+      {
+        if ( v39->pFacePlane.dist + v41 + outz * v39->pFacePlane.vNormal.z + pOut.x * v39->pFacePlane.vNormal.x < 0 )
+          goto LABEL_68;
+      }
+      else
+      {
+        if ( v39->pFacePlane.dist + v41 + outz * v39->pFacePlane.vNormal.z + pOut.x * v39->pFacePlane.vNormal.x > 0 )
+          goto LABEL_68;
+      }
+      v_4a = abs(-(v39->pFacePlane.dist + v41 + outz * v39->pFacePlane.vNormal.z + pOut.x * v39->pFacePlane.vNormal.x)) >> 14;
+      if ( v_4a <= abs(v40) )
+      {
+        LODWORD(v43) = v42 << 16;
+        HIDWORD(v43) = v42 >> 16;
+        v44 = v43 / va;
+        vb = v43 / va;
+        if ( v44 >= 0 )
+        {
+          if ( sub_4077F1(
+                 pOut.x + ((signed int)(((unsigned __int64)(vb * (signed __int64)v126) >> 16) + 32768) >> 16),
+                 pOut.y + ((signed int)(((unsigned __int64)(vb * (signed __int64)v122) >> 16) + 32768) >> 16),
+                 outz + ((signed int)(((unsigned __int64)(vb * (signed __int64)v118) >> 16) + 32768) >> 16),
+                 v39,
+                 (BSPVertexBuffer *)a5a) )
+          {
+            v113 = 1;
+            goto LABEL_71;
+          }
+        }
+      }
+LABEL_68:
+      ++sDeptha;
+      v_8 += 308;
+      if ( sDeptha >= *((int *)a5a + 2) )
+        goto LABEL_71;
+    }
+  }
+  return !v114 || !v113;
+}
+//----- (0043F333) --------------------------------------------------------
+void BspRenderer::MakeVisibleSectorList()
+{
+  int v6; // ebx@3
+
+  uNumVisibleNotEmptySectors = 0;
+  for (uint i = 0; i < num_nodes; ++i)
+  {
+      if (!uNumVisibleNotEmptySectors)
+      {
+        pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++] = nodes[i].uSectorID;
+        continue;
+      }
+      
+      v6 = 0;
+        while (pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[v6] != nodes[i].uSectorID )
+        {
+          ++v6;
+          if ( v6 >= uNumVisibleNotEmptySectors)
+          {
+            pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++] = nodes[i].uSectorID;
+          }
+        }
+
+  }
+}
+//----- (0046A334) --------------------------------------------------------
+char __fastcall DoInteractionWithTopmostZObject(int a1, int a2)
+{
+  int v2; // edx@1
+  BLVFace *v4; // eax@9
+  unsigned int v5; // ecx@9
+  unsigned __int16 v6; // ax@11
+  //ODMFace *v7; // eax@16
+  LevelDecoration *v8; // esi@19
+  __int16 v9; // ax@19
+  int v10; // eax@22
+  int v11; // ecx@22
+  int v12; // edi@23
+  Actor *v13; // esi@23
+  unsigned __int16 v14; // ax@23
+  unsigned __int16 v15; // ax@33
+  const char *v16; // eax@34
+  int v17; // edi@36
+  int v18; // eax@36
+  ItemGen *v19; // esi@39
+  unsigned int v20; // eax@39
+  int v21; // ecx@40
+  std::string v22; // [sp-18h] [bp-2Ch]@5
+  const char *v23; // [sp-8h] [bp-1Ch]@5
+  int v24; // [sp-4h] [bp-18h]@5
+  char v25; // [sp+8h] [bp-Ch]@5
+  int v26; // [sp+Ch] [bp-8h]@1
+  int a3; // [sp+13h] [bp-1h]@5
+
+  v26 = a2;
+  v2 = a1;
+  switch ( PID_TYPE(a1) )
+  {
+    case OBJECT_Item: // take the item
+      v17 = PID_ID(a1);
+      v26 = PID_ID(a1);
+      v18 = PID_ID(a1);
+      if ( pObjectList->pObjects[pSpriteObjects[v18].uObjectDescID].uFlags & 0x10
+        || v17 >= 1000
+        || !pSpriteObjects[v18].uObjectDescID )
+        return 1;
+      v19 = &pSpriteObjects[v18].stru_24;
+      v20 = pSpriteObjects[v18].stru_24.uItemID;
+      if ( pItemsTable->pItems[v20].uEquipType == EQUIP_GOLD)
+      {
+        party_finds_gold(v19->uSpecEnchantmentType, 0);
+        viewparams->bRedrawGameUI = 1;
+        v21 = v17;
+      }
+      else
+      {
+        if ( pParty->pPickedItem.uItemID )
+          return 1;
+        v24 = (int)pItemsTable->pItems[v20].pUnidentifiedName;
+        sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], v24);
+        ShowStatusBarString(pTmpBuf2.data(), 2u);
+        if ( v19->uItemID == 506 )
+          _449B7E_toggle_bit(pParty->_quest_bits, 184, 1u);
+        if ( v19->uItemID == 455 )
+          _449B7E_toggle_bit(pParty->_quest_bits, 185, 1u);
+        if ( !pParty->AddItem(v19) )
+          pParty->SetHoldingItem(v19);
+        v21 = v26;
+      }
+      SpriteObject::OnInteraction(v21);
+      break;
+
+    case OBJECT_Actor:
+      v12 = PID_ID(a1);
+      v13 = &pActors[PID_ID(a1)];
+      v14 = v13->uAIState;
+      if ( v14 == 4 || v14 == 17 )
+        return 1;
+      if ( v14 == 5 )
+      {
+        stru_50C198.LootActor(&pActors[PID_ID(a1)]);
+      }
+      else
+      {
+        if ( !v13->GetActorsRelation(0) && !(BYTE2(v13->uAttributes) & 8) && v13->CanAct() )
+        {
+          Actor::AI_FaceObject(v12, 4u, 0, 0);
+          if ( v13->sNPC_ID )
+          {
+            pMessageQueue_50CBD0->AddMessage(UIMSG_StartNPCDialogue, v12, 0);
+          }
+          else
+          {
+            v15 = pNPCStats->pGroups_copy[v13->uGroup];
+            if ( v15 )
+            {
+              v16 = pNPCStats->pCatchPhrases[v15];
+              if ( v16 )
+              {
+                pParty->uFlags |= 2u;
+                strcpy(byte_5B0938.data(), v16);
+                sub_4451A8_press_any_key(0, 0, 0);
+              }
+            }
+          }
+        }
+      }
+      break;
+
+    case OBJECT_Decoration:
+      v8 = &pLevelDecorations[PID_ID(a1)];
+      v9 = v8->field_16_event_id;
+      if ( v9 )
+      {
+        EventProcessor(v9, a1, 1);
+        LOBYTE(v8->field_2) |= 8u;
+      }
+      else
+      {
+        if ( !pLevelDecorations[PID_ID(a1)].IsInteractive() )
+          return 1;
+        v10 = v8->_idx_in_stru123;
+        v24 = 1;
+        v11 = stru_5E4C90._decor_events[v10 - 75] + 380;
+        activeLevelDecoration = v8;
+        EventProcessor(v11, 0, 1);
+        activeLevelDecoration = NULL;
+      }
+      break;
+
+    default:
+      MessageBoxW(nullptr, L"Warning: Invalid ID reached!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Mouse.cpp:2020", 0);
+      return 1;
+
+    case OBJECT_BModel:
+      if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor )
+      {
+        int bmodel_id = a1 >> 9,
+            face_id = PID_ID(a1) & 0x3F;
+        if (bmodel_id >= pOutdoor->uNumBModels)
+          return 1;
+        auto face = &pOutdoor->pBModels[bmodel_id].pFaces[face_id];
+        if (face->uAttributes & 0x100000 || face->sCogTriggeredID == 0 )
+          return 1;
+        EventProcessor((signed __int16)face->sCogTriggeredID, v2, 1);
+      }
+      else
+      {
+        v4 = &pIndoor->pFaces[PID_ID(a1)];
+        v5 = v4->uAttributes;
+        if ( !(v5 & 0x2000000) )
+        {
+          ShowNothingHereStatus();
+          return 1;
+        }
+        if ( v5 & 0x100000 || (v6 = pIndoor->pFaceExtras[v4->uFaceExtraID].uEventID) == 0 )
+          return 1;
+        if ( pCurrentScreen != SCREEN_BRANCHLESS_NPC_DIALOG )
+          EventProcessor((signed __int16)v6, v2, 1);
+      }
+      return 0;
+      break;
+  }
+  return 0;
+}
 //----- (0046BDF1) --------------------------------------------------------
 void __cdecl BLV_UpdateUserInputAndOther()
 {
@@ -4648,4 +6842,850 @@
   UpdateActors_BLV();
   BLV_UpdateDoors();
   check_event_triggers();
+}
+//----- (00424829) --------------------------------------------------------
+bool sub_424829(int pNumVertices, BspRenderer_stru2 *a2, BspRenderer_stru2 *a3, int uFaceID)
+{
+  //int v4; // edi@1
+  //BspRenderer_stru2 *v5; // ebx@1
+  int v6; // eax@3
+  int min_y; // esi@5
+  int max_y; // edx@5
+  //int v9; // ecx@6
+  int v10; // eax@12
+  //int v11; // edi@13
+  //int v12; // edx@18
+  int v13; // eax@22
+  //int v14; // edi@28
+  int v15; // ecx@29
+  //int v16; // edi@30
+  //int v17; // edx@35
+  int v18; // eax@39
+  int v19; // eax@44
+  int v20; // ecx@44
+  //int v21; // edi@45
+  int v22; // edi@46
+  //__int16 *v23; // ecx@47
+  int v24; // edx@48
+  //int v25; // eax@50
+  int v26; // eax@55
+  signed int v27; // edi@55
+  //int v28; // edx@56
+  int v29; // edx@57
+  //int v30; // eax@59
+  int v31; // eax@64
+  signed int v32; // edi@64
+  //int v33; // edx@65
+  int v34; // eax@66
+  int v35; // dx@66
+  __int16 v36; // dx@67
+  __int16 v37; // di@67
+  __int16 v38; // dx@67
+  //BspRenderer_stru2 *v39; // ecx@69
+  //int v40; // edx@69
+  //int v41; // edi@70
+  //__int16 *v42; // eax@76
+  //__int16 *v43; // eax@81
+  //__int16 *v45; // eax@87
+  int v46; // edx@87
+  //__int16 v47; // cx@88
+  //int v48; // eax@93
+  int v49; // esi@93
+  //__int16 *v50; // ecx@94
+  //int v51; // eax@95
+  //int v52; // eax@97
+  int v53; // [sp+Ch] [bp-34h]@44
+  int v54; // [sp+10h] [bp-30h]@0
+  int v55; // [sp+14h] [bp-2Ch]@12
+  //__int16 *v56; // [sp+14h] [bp-2Ch]@47
+  //__int16 v57; // [sp+14h] [bp-2Ch]@76
+  //__int16 v58; // [sp+14h] [bp-2Ch]@81
+  int v59; // [sp+14h] [bp-2Ch]@87
+  //BspRenderer_stru2 *v60; // [sp+18h] [bp-28h]@1
+  int v61; // [sp+1Ch] [bp-24h]@29
+  int v62; // [sp+20h] [bp-20h]@0
+  signed int v63; // [sp+24h] [bp-1Ch]@3
+  signed int v64; // [sp+28h] [bp-18h]@3
+  int v65; // [sp+2Ch] [bp-14h]@5
+  //int v66; // [sp+2Ch] [bp-14h]@39
+  //int v67; // [sp+30h] [bp-10h]@22
+  int v68; // [sp+34h] [bp-Ch]@12
+  int v69; // [sp+34h] [bp-Ch]@29
+  int v70; // [sp+34h] [bp-Ch]@46
+  int v71; // [sp+34h] [bp-Ch]@75
+  int v72; // [sp+34h] [bp-Ch]@80
+  //int v73; // [sp+38h] [bp-8h]@11
+  //int v74; // [sp+3Ch] [bp-4h]@1
+  //int a3a; // [sp+48h] [bp+8h]@76
+  //int a3b; // [sp+48h] [bp+8h]@87
+
+  //try graphic engine with function returning 1 always, and without
+  //return true;
+  if ( pNumVertices <= 1 )
+    return false;
+  min_y = stru_50B700._screen_space_y[0];
+  v65 = 0;
+  max_y = stru_50B700._screen_space_y[0];
+  if ( !stru_50B700.field_0 )
+  {
+    v63 = 1;
+    v64 = -1;
+  }
+  else 
+  {
+    v63 = -1;
+    v64 = 1;
+  }
+
+  for ( v6 = 1; v6 < pNumVertices; ++v6 )
+  {
+    if ( stru_50B700._screen_space_y[v6] >= min_y )
+    {
+      if ( stru_50B700._screen_space_y[v6] > max_y )
+        max_y = stru_50B700._screen_space_y[v6];
+    }
+    if ( stru_50B700._screen_space_y[v6] < min_y )
+    {
+      v65 = v6;
+      min_y = stru_50B700._screen_space_y[v6];
+    }
+  }
+  if ( max_y == min_y )
+    return false;
+
+  v10 = v65;
+  a2->_viewport_space_y = min_y;
+  a2->_viewport_space_w = max_y;
+  v55 = v65;
+
+  for ( v68 = 0; v68 < pNumVertices; ++v68 )
+  {
+    v10 += v64;
+    if ( v10 < pNumVertices )
+    {
+      if ( v10 < 0 )
+        v10 += pNumVertices;
+    }
+    else
+      v10 -= pNumVertices;
+    if ( stru_50B700._screen_space_y[v10] <= stru_50B700._screen_space_y[v65] )
+    {
+      v55 = v10;
+      v65 = v10;
+    }
+    if ( stru_50B700._screen_space_y[v10] == max_y )
+      break;
+  }
+  v13 = v55 + v64;
+  if ( v13 < pNumVertices )
+  {
+    if ( v13 < 0 )
+      v13 += pNumVertices;
+  }
+  else
+    v13 -= pNumVertices;
+  if ( stru_50B700._screen_space_y[v13] != stru_50B700._screen_space_y[v55] )
+  {
+    v62 = stru_50B700._screen_space_x[v55] << 16;
+    v54 = ((stru_50B700._screen_space_x[v13] - stru_50B700._screen_space_x[v55]) << 16) / (stru_50B700._screen_space_y[v13] - stru_50B700._screen_space_y[v55]);
+    a2->viewport_left_side[min_y] = LOWORD(stru_50B700._screen_space_x[v55]);
+  }
+  v15 = v65;
+  v61 = v65;
+
+  for ( v69 = 0; v69 < pNumVertices; ++v69 )
+  {
+    v15 += v63;
+    if ( v15 < pNumVertices )
+    {
+      if ( v15 < 0 )
+        v15 += pNumVertices;
+    }
+    else
+      v15 -= pNumVertices;
+    if ( stru_50B700._screen_space_y[v15] <= stru_50B700._screen_space_y[v65] )
+    {
+      v61 = v15;
+      v65 = v15;
+    }
+    if ( stru_50B700._screen_space_y[v15] == max_y )
+      break;
+  }
+  v18 = v63 + v61;
+  if ( v18 < pNumVertices )
+  {
+    if ( v18 < 0 )
+      v18 += pNumVertices;
+  }
+  else
+    v18 -= pNumVertices;
+  v19 = v18;
+  v20 = v61;
+  if ( stru_50B700._screen_space_y[v19] != stru_50B700._screen_space_y[v61] )
+  {
+    v61 = stru_50B700._screen_space_x[v20] << 16;
+    v53 = ((stru_50B700._screen_space_x[v19] - stru_50B700._screen_space_x[v20]) << 16) / stru_50B700._screen_space_y[v19] - stru_50B700._screen_space_y[v20];
+    a2->viewport_right_side[max_y] = LOWORD(stru_50B700._screen_space_x[v20]);
+  }
+  v22 = min_y;
+  if ( min_y <= max_y )
+  {
+    //v56 = &a2->array_3D8[v7];
+    //v23 = &a2->array_18[v7];
+    for ( v70 = min_y; v70 <= max_y; ++v70 )
+    {
+      v24 = v13;
+      if ( v22 >= stru_50B700._screen_space_y[v13] && v22 != max_y )
+      {
+        v13 = v64 + v13;
+        if ( v13 < pNumVertices )
+        {
+          if ( v13 < 0 )
+            v13 += pNumVertices;
+        }
+        else
+          v13 -= pNumVertices;
+        v26 = v13;
+        //v27 = stru_50B700._screen_space_y[v26] - stru_50B700._screen_space_y[v24];
+        if ( stru_50B700._screen_space_y[v26] - stru_50B700._screen_space_y[v24] > 0 )
+        {
+          v54 = ((stru_50B700._screen_space_x[v26] - stru_50B700._screen_space_x[v24]) << 16) / stru_50B700._screen_space_y[v26] - stru_50B700._screen_space_y[v24];
+          v62 = stru_50B700._screen_space_x[v24] << 16;
+        }
+      }
+      v29 = v18;
+      if ( v70 >= stru_50B700._screen_space_y[v18] && v70 != max_y )
+      {
+        v18 += v63;
+        if ( v18 < pNumVertices )
+        {
+          if ( v18 < 0 )
+            v18 += pNumVertices;
+        }
+        else
+          v18 -= pNumVertices;
+        v31 = v18;
+        //v32 = stru_50B700._screen_space_y[v31] - stru_50B700._screen_space_y[v29];
+        if ( stru_50B700._screen_space_y[v31] - stru_50B700._screen_space_y[v29] > 0 )
+        {
+          v53 = ((stru_50B700._screen_space_x[v31] - stru_50B700._screen_space_x[v29]) << 16) / stru_50B700._screen_space_y[v31] - stru_50B700._screen_space_y[v29];
+          v61 = stru_50B700._screen_space_x[v29] << 16;
+        }
+      }
+	  //v34 = (char *)a2->array_18 - (char *)a2->array_3D8;
+	  //v35 = *(__int16 *)((char *)&a2->array_3D8[v70] + v34);
+      //v35 = HIWORD(v62);
+      a2->viewport_left_side[v70] = HIWORD(v62);
+      a2->viewport_right_side[v70] = HIWORD(v61);
+      //v34 = &a2->array_3D8[v70];
+      //v35 = a2->array_3D8[v70];
+      if ( a2->viewport_left_side[v70] > a2->viewport_right_side[v70] )
+      {
+        v36 = a2->viewport_left_side[v70] ^ a2->viewport_right_side[v70];
+        v37 = a2->viewport_right_side[v70];
+        a2->viewport_left_side[v70] = v36;
+        v38 = v37 ^ v36;
+        a2->viewport_left_side[v70] ^= v38;
+        a2->viewport_right_side[v70] = v38;
+      }
+      //++v56;
+      v62 += v54;
+      v22 = v70 + 1;
+      v61 += v53;
+      //++v23;
+    }
+  }
+  if ( max_y < a3->_viewport_space_y )
+    return false;
+  if ( min_y > a3->_viewport_space_w )
+    return false;
+  if ( min_y < a3->_viewport_space_y )
+    min_y = a3->_viewport_space_y;
+  if ( max_y > a3->_viewport_space_w )
+    max_y = a3->_viewport_space_w;
+  if ( min_y <= max_y )
+  {
+    //a3a = (char *)a2 - (char *)a3;
+    //v42 = &a3->array_3D8[v7];
+    //v57 = *(__int16 *)((char *)v42 + a3a);
+    for ( v71 = min_y; v71 <= max_y; ++v71 )
+    {
+      if ( a2->viewport_left_side[v71] >= a3->viewport_left_side[v71] && a2->viewport_left_side[v71] <= a3->viewport_right_side[v71] )
+        break;
+      //++v57;
+      ++min_y;
+      //++v42;
+    }
+  }
+  if ( max_y < min_y )
+    return false;
+  //a3a = (char *)a2 - (char *)a3;
+  //v43 = &a3->array_3D8[v8];
+  //v58 = *(__int16 *)((char *)v43 + a3a);
+  for ( v72 = max_y; v72 >= min_y; --v72 )
+  {
+    if ( a2->viewport_right_side[v72] >= a3->viewport_left_side[v72] && a2->viewport_left_side[v72] <= a3->viewport_right_side[v72] )
+      break;
+    //--v58;
+    --max_y;
+    //--v43;
+    //v8 = v8;
+  }
+  if ( min_y >= max_y )
+    return false;
+  //a3b = (char *)a3 - (char *)a2;
+  v59 = min_y;
+  //v45 = &a2->array_18[v7];
+  
+  for ( v46 = max_y - min_y + 1; v46; --v46 )
+  {
+    //v47 = *(__int16 *)((char *)v45 + a3b);
+    if ( a2->viewport_left_side[v59] < a3->viewport_left_side[v59] )
+      a2->viewport_left_side[v59] = a3->viewport_left_side[v59];
+    if ( a2->viewport_right_side[v59] > a3->viewport_right_side[v59] )
+      a2->viewport_right_side[v59] = a3->viewport_right_side[v59];
+    ++v59;
+    //++v45;
+  }
+  a2->_viewport_space_y = min_y;
+  a2->_viewport_space_w = max_y;
+  a2->field_8 = a2->viewport_left_side[min_y];
+  //v48 = a2->viewport_right_side[v7];
+  a2->field_10 = min_y;
+  a2->field_14 = min_y;
+  a2->field_C = a2->viewport_right_side[min_y];
+  v49 = min_y + 1;
+  if ( v49 <= max_y )
+  {
+    //v50 = &a2->array_3D8[v49];
+    for ( v49; v49 <= max_y; ++v49 )
+    {
+      //v51 = a2->array_18[v49];
+      if ( a2->viewport_left_side[v49] < a2->field_8 )
+      {
+        a2->field_8 = a2->viewport_left_side[v49];
+        a2->field_10 = v49;
+      }
+      if ( a2->viewport_right_side[v49] > a2->field_C )
+      {
+        a2->field_C = a2->viewport_right_side[v49];
+        a2->field_14 = v49;
+      }
+      //++v50;
+    }
+  }
+  return true;
+}
+//----- (00423B5D) --------------------------------------------------------
+int __fastcall sub_423B5D(unsigned int uFaceID)
+{
+  BLVFace *pFace; // ebx@1
+  Vec3_short_ *v2; // esi@1
+  //int v3; // ST28_4@1
+  //__int16 v4; // ST2C_2@1
+  signed int v5; // esi@1
+  //Vec3_short_ *v6; // eax@4
+  signed int v7; // edi@5
+  signed int v8; // eax@5
+  signed int v9; // ecx@10
+  int v10; // eax@10
+  int v11; // edx@11
+  int v12; // ST28_4@12
+  signed int v13; // edx@12
+  signed __int64 v14; // qtt@12
+  char *v15; // ebx@12
+  int v16; // ST28_4@14
+  signed int v17; // eax@14
+  signed __int64 v18; // qtt@14
+  signed int v19; // edx@15
+  signed int v20; // edx@17
+  signed int v21; // ebx@19
+  signed int v22; // esi@20
+  int v23; // edi@21
+  int v24; // eax@21
+  int v25; // eax@22
+  int v26; // eax@22
+  signed int v27; // ST30_4@24
+  signed __int64 v28; // qtt@24
+  int v29; // ST18_4@25
+  int v30; // eax@26
+  int v31; // eax@27
+  int v32; // eax@27
+  signed int v33; // ST30_4@29
+  signed __int64 v34; // qtt@29
+  int v35; // ST30_4@30
+  signed int v36; // edi@31
+  unsigned int v37; // eax@31
+  bool v38; // edx@31
+  int v39; // ecx@31
+  int v40; // ecx@32
+  int v41; // esi@32
+  int v42; // eax@34
+  signed int v43; // ebx@41
+  unsigned int v44; // eax@41
+  signed int v45; // ecx@42
+  int v46; // esi@42
+  int v47; // eax@44
+  signed int v48; // edi@51
+  unsigned int v49; // eax@51
+  bool v50; // edx@51
+  int v51; // ecx@51
+  int v52; // ecx@52
+  int v53; // esi@52
+  int v54; // eax@54
+  int v55; // ebx@61
+  unsigned int v56; // eax@61
+  signed int v57; // ecx@62
+  int v58; // esi@62
+  int v59; // eax@64
+  char v61; // zf@72
+  signed int v62; // edx@75
+  int v63; // ecx@76
+  int v64; // esi@76
+  int v65; // ecx@83
+  signed int v66; // [sp+14h] [bp-14h]@3
+  int v67; // [sp+14h] [bp-14h]@34
+  int v68; // [sp+14h] [bp-14h]@44
+  int v69; // [sp+14h] [bp-14h]@54
+  int v70; // [sp+14h] [bp-14h]@64
+  signed int v71; // [sp+14h] [bp-14h]@75
+  IndoorCameraD3D *_this; // [sp+18h] [bp-10h]@1
+  bool thisa; // [sp+18h] [bp-10h]@9
+  int thisb; // [sp+18h] [bp-10h]@12
+  int thisc; // [sp+18h] [bp-10h]@20
+  bool thisd; // [sp+18h] [bp-10h]@41
+  bool thise; // [sp+18h] [bp-10h]@61
+  int thisf; // [sp+18h] [bp-10h]@74
+  signed int v79; // [sp+1Ch] [bp-Ch]@9
+  int v80; // [sp+1Ch] [bp-Ch]@76
+  bool v81; // [sp+20h] [bp-8h]@10
+  bool v82; // [sp+20h] [bp-8h]@32
+  bool v83; // [sp+20h] [bp-8h]@42
+  bool v84; // [sp+20h] [bp-8h]@52
+  bool v85; // [sp+20h] [bp-8h]@62
+  signed int v86; // [sp+24h] [bp-4h]@9
+  signed int v87; // [sp+24h] [bp-4h]@19
+  signed int v88; // [sp+24h] [bp-4h]@31
+  signed int v89; // [sp+24h] [bp-4h]@41
+  signed int v90; // [sp+24h] [bp-4h]@51
+  signed int v91; // [sp+24h] [bp-4h]@61
+
+  pFace = &pIndoor->pFaces[uFaceID];
+  _this = pGame->pIndoorCameraD3D;
+  v2 = &pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]];
+  //v3 = *(_DWORD *)pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].x;
+  //v4 = pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].z;
+  v5 = 0;
+  if ( pFace->pFacePlane_old.vNormal.x * (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].x - pBLVRenderParams->vPartyPos.x)
+     + pFace->pFacePlane_old.vNormal.y * (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].y - pBLVRenderParams->vPartyPos.y)
+     + pFace->pFacePlane_old.vNormal.z * (pIndoor->pVertices[pIndoor->pFaces[uFaceID].pVertexIDs[0]].z - pBLVRenderParams->vPartyPos.z) < 0 )
+  {
+    stru_50B700.field_0 = 1;
+  }
+  else
+  {
+    stru_50B700.field_0 = 0;
+    if ( !(pFace->uAttributes & 1) )
+      return 0;
+  }
+  v66 = pFace->uNumVertices;
+  if ( (signed int)pFace->uNumVertices > 0 )
+  {
+    do
+    {
+      //v6 = &pIndoor->pVertices[pFace->pVertexIDs[v5]];
+      pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible(
+        pIndoor->pVertices[pFace->pVertexIDs[v5]].x,
+        pIndoor->pVertices[pFace->pVertexIDs[v5]].y,
+        pIndoor->pVertices[pFace->pVertexIDs[v5]].z,
+        &stru_50B700._view_transformed_xs[v5 + 3],
+        &stru_50B700._view_transformed_zs[v5 + 3],
+        &stru_50B700._view_transformed_ys[v5 + 3],
+        0);
+      ++v5;
+    }
+    while ( v5 < v66 );
+  }
+  v7 = v66;
+  v8 = 0;
+  if ( v66 <= 0 )
+    return 0;
+  do
+  {
+    if ( stru_50B700._view_transformed_xs[v8 + 3] >= 524288 )
+      break;
+    ++v8;
+  }
+  while ( v8 < v66 );
+  if ( v8 >= v66 )
+    return 0;
+  v79 = 0;
+  stru_50B700._view_transformed_xs[v66 + 3] = stru_50B700._view_transformed_xs[3];
+  stru_50B700._view_transformed_zs[v66 + 3] = stru_50B700._view_transformed_zs[3];
+  stru_50B700._view_transformed_ys[v66 + 3] = stru_50B700._view_transformed_ys[3];
+  thisa = stru_50B700._view_transformed_xs[3] >= 524288;
+  v86 = 1;
+  if ( v66 >= 1 )
+  {
+    do
+    {
+      v9 = v86;
+      v10 = stru_50B700._view_transformed_xs[v86 + 3];
+      v81 = v10 >= 524288;
+      if ( thisa ^ v81 )
+      {
+        v11 = stru_50B700._view_transformed_xs[v9 + 2];
+        if ( v10 >= 524288 )
+        {
+          v12 = v10 - v11;
+          v13 = 524288 - v11;
+          LODWORD(v14) = v13 << 16;
+          HIDWORD(v14) = v13 >> 16;
+          v15 = (char *)&stru_50B700._view_transformed_ys[v9 + 2];
+          stru_50B700._view_transformed_zs[v79] = ((unsigned __int64)((stru_50B700._view_transformed_zs[v9 + 3]
+                                                                     - stru_50B700._view_transformed_zs[v9 + 2])
+                                                                    * v14
+                                                                    / v12) >> 16)
+                                                + stru_50B700._view_transformed_zs[v9 + 2];
+          thisb = (unsigned __int64)((stru_50B700._view_transformed_ys[v9 + 3] - stru_50B700._view_transformed_ys[v9 + 2])
+                                   * v14
+                                   / v12) >> 16;
+        }
+        else
+        {
+          v16 = v11 - v10;
+          v17 = 524288 - v10;
+          LODWORD(v18) = v17 << 16;
+          HIDWORD(v18) = v17 >> 16;
+          v15 = (char *)&stru_50B700._view_transformed_ys[v9 + 3];
+          stru_50B700._view_transformed_zs[v79] = ((unsigned __int64)((stru_50B700._view_transformed_zs[v9 + 2]
+                                                                     - stru_50B700._view_transformed_zs[v9 + 3])
+                                                                    * v18
+                                                                    / v16) >> 16)
+                                                + stru_50B700._view_transformed_zs[v9 + 3];
+          thisb = (unsigned __int64)((stru_50B700._view_transformed_ys[v9 + 2] - stru_50B700._view_transformed_ys[v9 + 3])
+                                   * v18
+                                   / v16) >> 16;
+        }
+        v19 = v79++;
+        v7 = v66;
+        stru_50B700._view_transformed_ys[v19] = thisb + *(_DWORD *)v15;
+        stru_50B700._view_transformed_xs[v19] = 524288;
+      }
+      if ( v81 )
+      {
+        v20 = v79++;
+        stru_50B700._view_transformed_xs[v20] = stru_50B700._view_transformed_xs[v9 + 3];
+        stru_50B700._view_transformed_zs[v20] = stru_50B700._view_transformed_zs[v9 + 3];
+        stru_50B700._view_transformed_ys[v20] = stru_50B700._view_transformed_ys[v9 + 3];
+      }
+      ++v86;
+      thisa = v81;
+    }
+    while ( v86 <= v7 );
+  }
+  v87 = 0;
+  v21 = v79;
+  stru_50B700._view_transformed_xs[v79] = stru_50B700._view_transformed_xs[0];
+  stru_50B700._view_transformed_zs[v79] = stru_50B700._view_transformed_zs[0];
+  for ( stru_50B700._view_transformed_ys[v79] = stru_50B700._view_transformed_ys[0];
+        v87 < v79;
+        stru_50B700._screen_space_y[v22 + 12] = pBLVRenderParams->uViewportCenterY - v35 )
+  {
+    v22 = v87;
+    thisc = abs(stru_50B700._view_transformed_xs[v87]);
+    if ( abs(stru_50B700._view_transformed_zs[v87]) >> 13 <= thisc )
+    {
+      v27 = stru_50B700._view_transformed_zs[v22];
+      LODWORD(v28) = v27 << 16;
+      HIDWORD(v28) = v27 >> 16;
+      v26 = v28 / stru_50B700._view_transformed_xs[v22];
+      v23 = 0;
+    }
+    else
+    {
+      v23 = 0;
+      v24 = 0;
+      if ( stru_50B700._view_transformed_zs[v22] >= 0 )
+      {
+        LOBYTE(v24) = stru_50B700._view_transformed_xs[v22] >= 0;
+        v26 = ((v24 - 1) & 0xFF800000) + 4194304;
+      }
+      else
+      {
+        LOBYTE(v24) = stru_50B700._view_transformed_xs[v22] >= 0;
+        v25 = v24 - 1;
+        v26 = (v25 & 0x800000) - 4194304;
+      }
+    }
+    v29 = stru_50B700._view_transformed_ys[v22];
+    stru_50B700._screen_space_x[v22 + 12] = v26;
+    if ( abs(v29) >> 13 <= thisc )
+    {
+      v33 = stru_50B700._view_transformed_ys[v22];
+      LODWORD(v34) = v33 << 16;
+      HIDWORD(v34) = v33 >> 16;
+      v32 = v34 / stru_50B700._view_transformed_xs[v22];
+    }
+    else
+    {
+      v30 = 0;
+      if ( stru_50B700._view_transformed_ys[v22] >= v23 )
+      {
+        LOBYTE(v30) = stru_50B700._view_transformed_xs[v22] >= v23;
+        v32 = ((v30 - 1) & 0xFF800000) + 4194304;
+      }
+      else
+      {
+        LOBYTE(v30) = stru_50B700._view_transformed_xs[v22] >= v23;
+        v31 = v30 - 1;
+        v32 = (v31 & 0x800000) - 4194304;
+      }
+    }
+    stru_50B700._screen_space_y[v22 + 12] = v32;
+    stru_50B700._screen_space_x[v22 + 12] = (unsigned __int64)(SHIWORD(pBLVRenderParams->field_40)
+                                                             * (signed __int64)stru_50B700._screen_space_x[v22 + 12]) >> 16;
+    v35 = (unsigned __int64)(SHIWORD(pBLVRenderParams->field_40) * (signed __int64)stru_50B700._screen_space_y[v22 + 12]) >> 16;
+    stru_50B700._screen_space_x[v22 + 12] = pBLVRenderParams->uViewportCenterX - stru_50B700._screen_space_x[v22 + 12];
+    ++v87;
+  }
+  v36 = 0;
+  stru_50B700._screen_space_x[v21 + 12] = stru_50B700._screen_space_x[12];
+  stru_50B700._screen_space_y[v21 + 12] = stru_50B700._screen_space_y[12];
+  v37 = pBLVRenderParams->uViewportX;
+  v38 = stru_50B700._screen_space_x[12] < (signed int)pBLVRenderParams->uViewportX;
+  LOBYTE(v38) = stru_50B700._screen_space_x[12] >= (signed int)pBLVRenderParams->uViewportX;
+  v39 = 1;
+  v88 = 1;
+  if ( v79 < 1 )
+    return 0;
+  do
+  {
+    v40 = v39;
+    v41 = stru_50B700._screen_space_x[v40 + 12];
+    v82 = v41 >= (signed int)v37;
+    if ( v38 ^ v82 )
+    {
+      if ( v41 >= (signed int)v37 )
+      {
+        v67 = (signed int)(v37 - stru_50B700._screen_space_x[v40 + 11])
+            * (signed __int64)(stru_50B700._screen_space_y[v40 + 12] - stru_50B700._screen_space_y[v40 + 11])
+            / (v41 - stru_50B700._screen_space_x[v40 + 11]);
+        v42 = stru_50B700._screen_space_y[v40 + 11];
+      }
+      else
+      {
+        v67 = (signed int)(v37 - v41)
+            * (signed __int64)(stru_50B700._screen_space_y[v40 + 11] - stru_50B700._screen_space_y[v40 + 12])
+            / (stru_50B700._screen_space_x[v40 + 11] - v41);
+        v42 = stru_50B700._screen_space_y[v40 + 12];
+      }
+      ++v36;
+      stru_50B700._screen_space_y[v36 + 8] = v67 + v42;
+      v37 = pBLVRenderParams->uViewportX;
+      stru_50B700._screen_space_x[v36 + 8] = pBLVRenderParams->uViewportX;
+    }
+    v38 = v82;
+    if ( v82 )
+    {
+      stru_50B700._screen_space_x[v36 + 9] = stru_50B700._screen_space_x[v40 + 12];
+      stru_50B700._screen_space_y[v36++ + 9] = stru_50B700._screen_space_y[v40 + 12];
+    }
+    v39 = v88++ + 1;
+  }
+  while ( v88 <= v79 );
+  if ( !v36
+    || (v43 = 0,
+        stru_50B700._screen_space_x[v36 + 9] = stru_50B700._screen_space_x[9],
+        stru_50B700._screen_space_y[v36 + 9] = stru_50B700._screen_space_y[9],
+        v44 = pBLVRenderParams->uViewportZ,
+        thisd = stru_50B700._screen_space_x[9] <= (signed int)pBLVRenderParams->uViewportZ,
+        v89 = 1,
+        v36 < 1) )
+    return 0;
+  do
+  {
+    v45 = v89;
+    v46 = stru_50B700._screen_space_x[v89 + 9];
+    v83 = v46 <= (signed int)v44;
+    if ( thisd ^ v83 )
+    {
+      if ( v46 <= (signed int)v44 )
+      {
+        v68 = (signed int)(v44 - stru_50B700._screen_space_x[v45 + 8])
+            * (signed __int64)(stru_50B700._screen_space_y[v45 + 9] - stru_50B700._screen_space_y[v45 + 8])
+            / (v46 - stru_50B700._screen_space_x[v45 + 8]);
+        v47 = stru_50B700._screen_space_y[v45 + 8];
+      }
+      else
+      {
+        v68 = (signed int)(v44 - v46)
+            * (signed __int64)(stru_50B700._screen_space_y[v45 + 8] - stru_50B700._screen_space_y[v45 + 9])
+            / (stru_50B700._screen_space_x[v45 + 8] - v46);
+        v47 = stru_50B700._screen_space_y[v45 + 9];
+      }
+      ++v43;
+      stru_50B700._screen_space_y[v43 + 5] = v68 + v47;
+      v44 = pBLVRenderParams->uViewportZ;
+      stru_50B700._screen_space_x[v43 + 5] = pBLVRenderParams->uViewportZ;
+    }
+    if ( v83 )
+    {
+      stru_50B700._screen_space_x[v43 + 6] = stru_50B700._screen_space_x[v45 + 9];
+      stru_50B700._screen_space_y[v43++ + 6] = stru_50B700._screen_space_y[v45 + 9];
+    }
+    ++v89;
+    thisd = v83;
+  }
+  while ( v89 <= v36 );
+  if ( !v43
+    || (v48 = 0,
+        stru_50B700._screen_space_x[v43 + 6] = stru_50B700._screen_space_x[6],
+        stru_50B700._screen_space_y[v43 + 6] = stru_50B700._screen_space_y[6],
+        v49 = pBLVRenderParams->uViewportY,
+        v50 = stru_50B700._screen_space_y[6] < (signed int)pBLVRenderParams->uViewportY,
+        LOBYTE(v50) = stru_50B700._screen_space_y[6] >= (signed int)pBLVRenderParams->uViewportY,
+        v51 = 1,
+        v90 = 1,
+        v43 < 1) )
+    return 0;
+  do
+  {
+    v52 = v51;
+    v53 = stru_50B700._screen_space_y[v52 + 6];
+    v84 = v53 >= (signed int)v49;
+    if ( v50 ^ v84 )
+    {
+      if ( v53 >= (signed int)v49 )
+      {
+        v69 = (signed int)(v49 - stru_50B700._screen_space_y[v52 + 5])
+            * (signed __int64)(stru_50B700._screen_space_x[v52 + 6] - stru_50B700._screen_space_x[v52 + 5])
+            / (v53 - stru_50B700._screen_space_y[v52 + 5]);
+        v54 = stru_50B700._screen_space_x[v52 + 5];
+      }
+      else
+      {
+        v69 = (signed int)(v49 - v53)
+            * (signed __int64)(stru_50B700._screen_space_x[v52 + 5] - stru_50B700._screen_space_x[v52 + 6])
+            / (stru_50B700._screen_space_y[v52 + 5] - v53);
+        v54 = stru_50B700._screen_space_x[v52 + 6];
+      }
+      ++v48;
+      stru_50B700._screen_space_x[v48 + 2] = v69 + v54;
+      v49 = pBLVRenderParams->uViewportY;
+      stru_50B700._screen_space_y[v48 + 2] = pBLVRenderParams->uViewportY;
+    }
+    v50 = v84;
+    if ( v84 )
+    {
+      stru_50B700._screen_space_x[v48 + 3] = stru_50B700._screen_space_x[v52 + 6];
+      stru_50B700._screen_space_y[v48++ + 3] = stru_50B700._screen_space_y[v52 + 6];
+    }
+    v51 = v90++ + 1;
+  }
+  while ( v90 <= v43 );
+  if ( !v48
+    || (v55 = 0,
+        stru_50B700._screen_space_x[v48 + 3] = stru_50B700._screen_space_x[3],
+        stru_50B700._screen_space_y[v48 + 3] = stru_50B700._screen_space_y[3],
+        v56 = pBLVRenderParams->uViewportW,
+        thise = stru_50B700._screen_space_y[3] <= (signed int)pBLVRenderParams->uViewportW,
+        v91 = 1,
+        v48 < 1) )
+    return 0;
+  do
+  {
+    v57 = v91;
+    v58 = stru_50B700._screen_space_y[v91 + 3];
+    v85 = v58 <= (signed int)v56;
+    if ( thise ^ v85 )
+    {
+      if ( v58 <= (signed int)v56 )
+      {
+        v70 = (signed int)(v56 - stru_50B700._screen_space_y[v57 + 2])
+            * (signed __int64)(stru_50B700._screen_space_x[v57 + 3] - stru_50B700._screen_space_x[v57 + 2])
+            / (v58 - stru_50B700._screen_space_y[v57 + 2]);
+        v59 = stru_50B700._screen_space_x[v57 + 2];
+      }
+      else
+      {
+        v70 = (signed int)(v56 - v58)
+            * (signed __int64)(stru_50B700._screen_space_x[v57 + 2] - stru_50B700._screen_space_x[v57 + 3])
+            / (stru_50B700._screen_space_y[v57 + 2] - v58);
+        v59 = stru_50B700._screen_space_x[v57 + 3];
+      }
+      ++v55;
+      //stru_50B700._screen_space_y[v55 + 59] = v70 + v59;
+	  stru_50B700._screen_space_x[v55 - 1] = v70 + v59;
+      v56 = pBLVRenderParams->uViewportW;
+      //stru_50B700._view_transformed_xs[v55 + 47] = pBLVRenderParams->uViewportW;
+	  stru_50B700._screen_space_y[v55 - 1] = pBLVRenderParams->uViewportW;
+    }
+    if ( v85 )
+    {
+      stru_50B700._screen_space_x[v55] = stru_50B700._screen_space_x[v57 + 3];
+      stru_50B700._screen_space_y[v55++] = stru_50B700._screen_space_y[v57 + 3];
+    }
+    ++v91;
+    thise = v85;
+  }
+  while ( v91 <= v48 );
+  if ( !v55 )
+    return 0;
+  v61 = pRenderer->pRenderD3D == 0;
+  stru_50B700._screen_space_x[v55] = stru_50B700._screen_space_x[0];
+  stru_50B700._screen_space_y[v55] = stru_50B700._screen_space_y[0];
+  if ( v61 && v55 > 3 )
+  {
+    stru_50B700._screen_space_x[v55 + 1] = stru_50B700._screen_space_x[1];
+    stru_50B700._screen_space_y[v55 + 1] = stru_50B700._screen_space_y[1];
+    thisf = 2 * (stru_50B700.field_0 != 0) - 1;
+    if ( v55 > 0 )
+    {
+      v62 = 1;
+      v71 = 1;
+      do
+      {
+        v63 = v62 - 1;
+        v64 = v62 + 1;
+        v80 = v62 + 1;
+        if ( v62 - 1 >= v55 )
+          v63 -= v55;
+        if ( v62 >= v55 )
+          v62 -= v55;
+        if ( v64 >= v55 )
+          v64 -= v55;
+        if ( thisf
+           * ((stru_50B700._screen_space_y[v64] - stru_50B700._screen_space_y[v63])
+            * (stru_50B700._screen_space_x[v62] - stru_50B700._screen_space_x[v63])
+            - (stru_50B700._screen_space_y[v62] - stru_50B700._screen_space_y[v63])
+            * (stru_50B700._screen_space_x[v64] - stru_50B700._screen_space_x[v63])) < 0 )
+        {
+          v62 = v80;
+          v71 = v80;
+        }
+        else
+        {
+          v62 = v71;
+          v65 = v71;
+          if ( v71 < v55 || (v65 = v71 - v55, v71 - v55 < v55) )
+          {
+            memcpy(
+              &stru_50B700._screen_space_y[v65],
+              &stru_50B700._screen_space_y[v65 + 1],
+              4 * ((unsigned int)(4 * (v55 - v65)) >> 2));
+            memcpy(
+              &stru_50B700._screen_space_x[v65],
+              &stru_50B700._screen_space_x[v65 + 1],
+              4 * ((unsigned int)(4 * (v55 - v65)) >> 2));
+          }
+          --v55;
+        }
+      }
+      while ( v62 - 1 < v55 );
+    }
+    stru_50B700._screen_space_x[v55] = stru_50B700._screen_space_x[0];
+    stru_50B700._screen_space_y[v55] = stru_50B700._screen_space_y[0];
+  }
+  return v55;
 }
\ No newline at end of file