changeset 795:472ca68386d4

more stru10 & stru9
author Nomad
date Mon, 25 Mar 2013 14:23:40 +0200
parents 4a00901e063c
children 14beae4f1723 e95389c8680a
files Indoor.cpp Indoor.h IndoorCameraD3D.cpp IndoorCameraD3D.h Indoor_stuff.h mm7_3.cpp stru10.cpp stru10.h stru9.cpp stru9.h
diffstat 10 files changed, 158 insertions(+), 515 deletions(-) [+]
line wrap: on
line diff
--- a/Indoor.cpp	Mon Mar 25 11:58:38 2013 +0200
+++ b/Indoor.cpp	Mon Mar 25 14:23:40 2013 +0200
@@ -271,9 +271,9 @@
 void IndoorLocation::ExecDraw(bool bD3D)
 {
   int v2; // eax@3
-  IndoorCameraD3D_Vec4 *v3; // edx@4
-  unsigned int v5; // ecx@9
-  RenderVertexSoft *v6; // [sp-4h] [bp-8h]@4
+  //IndoorCameraD3D_Vec4 *v3; // edx@4
+  //unsigned int v5; // ecx@9
+  //RenderVertexSoft *v6; // [sp-4h] [bp-8h]@4
 
   if (bD3D)
   {
@@ -281,27 +281,16 @@
     for (uint i = 0; i < pBspRenderer->num_faces; ++i)
     {
       v2 = pBspRenderer->faces[i].uNodeID;
-      if ( pBspRenderer->nodes[v2].std__vector_0007A8 == -1 )
-      {
-        v6 = 0;
-        v3 = 0;
-      }
+      if (pBspRenderer->nodes[v2].viewing_portal_id == -1)
+        IndoorLocation::ExecDraw_d3d(pBspRenderer->faces[i].uFaceID, nullptr, 4, nullptr);
       else
-      {
-        v3 = pBspRenderer->nodes[v2].std__vector_0007AC;
-        v6 = pBspRenderer->nodes[v2].pPortalBounding;
-      }
-      IndoorLocation::ExecDraw_d3d(pBspRenderer->faces[i].uFaceID, v3, 4, v6);
+        IndoorLocation::ExecDraw_d3d(pBspRenderer->faces[i].uFaceID, pBspRenderer->nodes[v2].std__vector_0007AC, 4, pBspRenderer->nodes[v2].pPortalBounding);
     }
   }
-  else
+  else for (uint j = 0; j < pBspRenderer->num_faces; ++j )
   {
-    for (uint j = 0; j < pBspRenderer->num_faces; ++j )
-    {
-      v5 = pBspRenderer->faces[j].uFaceID;
-      pBLVRenderParams->field_7C = &pBspRenderer->nodes[pBspRenderer->faces[j].uNodeID].field_C;
-      IndoorLocation::ExecDraw_sw(v5);
-    }
+    pBLVRenderParams->field_7C = &pBspRenderer->nodes[pBspRenderer->faces[j].uNodeID].field_C;
+    IndoorLocation::ExecDraw_sw(pBspRenderer->faces[j].uFaceID);
   }
 }
 
@@ -517,7 +506,7 @@
     if (!pVertices ||
         (pGame->pStru9Instance->_498377(pPortalBounding, 4u, pVertices, static_vertices_F7C228, &uNumVerticesa), uNumVerticesa) )
     {
-      if (pGame->pIndoorCameraD3D->_437285_prolly_colide_vertices_against_frustrum(static_vertices_F7C228, &uNumVerticesa,
+      if (pGame->pIndoorCameraD3D->CalcPortalShape(static_vertices_F7C228, &uNumVerticesa,
                      static_vertices_F7B628, pGame->pIndoorCameraD3D->std__vector_000034_prolly_frustrum, 4, false, 0) != 1 || uNumVerticesa )
       {
         a4a = SHIWORD(stru_F8AD28.uCurrentAmbientLightLevel);
@@ -1273,7 +1262,7 @@
   //double v27; // st7@47
   //signed int v28; // ST28_4@47
   char v29; // al@48
-  signed int v30; // eax@51
+  //signed int v30; // eax@51
   //int v31; // eax@52
   //unsigned int v32; // eax@55
   //__int16 v33; // cx@56
@@ -1287,7 +1276,7 @@
   //v3 = uFaceID;
   //v4 = this;
   //v5 = &pIndoor->pFaces[uFaceID];
-  nodes[num_nodes].std__vector_0007A8 = -1;
+  nodes[num_nodes].viewing_portal_id = -1;
   //v39 = &pIndoor->pFaces[uFaceID];
 
   auto pFace = &pIndoor->pFaces[uFaceID];
@@ -1420,57 +1409,40 @@
           nodes[num_nodes].uViewportW = pBLVRenderParams->uViewportW;
           //v38 = pGame->pStru10Instance;
           //a0a = pGame->pIndoorCameraD3D;
-          if (p->std__vector_0007A8 == -1 )
+          v29 = false;
+          if (p->viewing_portal_id == -1)
           {
-            v29 = pGame->pStru10Instance->MessWithPortal(pFace, nodes[num_nodes].std__vector_0007AC, nodes[num_nodes].pPortalBounding);
+            v29 = pGame->pStru10Instance->CalcPortalShape(pFace, nodes[num_nodes].std__vector_0007AC, nodes[num_nodes].pPortalBounding);
           }
           else
           {
             static RenderVertexSoft static_subAddFaceToRenderList_d3d_stru_F7AA08[64];
             static RenderVertexSoft static_subAddFaceToRenderList_d3d_stru_F79E08[64];
 
-            //v23 = 0;
-            unsigned int a2 = pFace->uNumVertices;
             for (uint k = 0; k < pFace->uNumVertices; ++k)
             {
-              //v24 = (char *)&static_subAddFaceToRenderList_d3d_stru_F7AA08[0].vWorldPosition.z;
-              //do
-              //{
-                //v25 = pFace->pVertexIDs[k];
-                //v26 = &pIndoor->pVertices[pFace->pVertexIDs[k]];
-                auto pVertex = &pIndoor->pVertices[pFace->pVertexIDs[k]];
-                //v27 = (double)v26->z;
-                //v28 = v26->y;
-                //v17 = v39;
-                static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.x = pVertex->x;
-                static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.y = pVertex->y;
-                static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.z = pVertex->z;
-                //v24 += 48;
-              //}
-              //while ( v23 < a2 );
+              static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.x = pIndoor->pVertices[pFace->pVertexIDs[k]].x;
+              static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.y = pIndoor->pVertices[pFace->pVertexIDs[k]].y;
+              static_subAddFaceToRenderList_d3d_stru_F7AA08[k].vWorldPosition.z = pIndoor->pVertices[pFace->pVertexIDs[k]].z;
             }
-            pGame->pIndoorCameraD3D->_437285_prolly_colide_vertices_against_frustrum(
-              static_subAddFaceToRenderList_d3d_stru_F7AA08,
-              &a2,
-              static_subAddFaceToRenderList_d3d_stru_F79E08,
-              p->std__vector_0007AC,
-              4,
-              0,
-              0);
-            v29 = pGame->pStru10Instance->_49C5DA(pFace, static_subAddFaceToRenderList_d3d_stru_F79E08, (int *)&a2,
-                    nodes[num_nodes].std__vector_0007AC,
-                    nodes[num_nodes].pPortalBounding);
+
+
+            unsigned int a2 = pFace->uNumVertices;
+            pGame->pIndoorCameraD3D->CalcPortalShape(static_subAddFaceToRenderList_d3d_stru_F7AA08,
+                                                     &a2,
+                                                     static_subAddFaceToRenderList_d3d_stru_F79E08,
+                                                     p->std__vector_0007AC, 4, 0, 0);
+
+            v29 = pGame->pStru10Instance->_49C5DA(pFace, static_subAddFaceToRenderList_d3d_stru_F79E08, &a2,
+                                                  nodes[num_nodes].std__vector_0007AC,
+                                                  nodes[num_nodes].pPortalBounding);
           }
           if ( v29 )
           {
-            nodes[num_nodes].std__vector_0007A8 = uFaceID;
-            v30 = num_nodes;
-            if ( v30 < 150 )
-            {
-              //v31 = v30 + 1;
-              num_nodes = v30 + 1;
-              AddBspNodeToRenderList(v30);
-            }
+            assert(num_nodes < 150);
+
+            nodes[num_nodes].viewing_portal_id = uFaceID;
+            AddBspNodeToRenderList(++num_nodes - 1);
           }
           if (pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_SW_OUTLINES)
             pGame->pIndoorCameraD3D->PrepareAndDrawDebugOutline(pFace, 0x1E1EFF);
--- a/Indoor.h	Mon Mar 25 11:58:38 2013 +0200
+++ b/Indoor.h	Mon Mar 25 14:23:40 2013 +0200
@@ -253,6 +253,9 @@
 #define FACE_PORTAL             0x00000001 // portal/two-sided
 #define FACE_CAN_SATURATE_COLOR 0x00000002
 #define FACE_FLUID              0x00000010 // wavy animated water or lava
+#define FACE_XY_PLANE           0x00000100
+#define FACE_XZ_PLANE           0x00000200
+#define FACE_YZ_PLANE           0x00000400
 #define FACE_INVISIBLE          0x00002000
 #define FACE_TEXTURE_FRAME      0x00004000 // Texture ID is a frameset from TextureFrameTable, otherwise BitmapID
 #define FACE_OUTLINED           0x00010000 // outline face edges
--- a/IndoorCameraD3D.cpp	Mon Mar 25 11:58:38 2013 +0200
+++ b/IndoorCameraD3D.cpp	Mon Mar 25 14:23:40 2013 +0200
@@ -651,7 +651,7 @@
   if ( pRenderer->pRenderD3D )
   {
     LODWORD(a7) = 1;
-    if ( v7->_437285_prolly_colide_vertices_against_frustrum(
+    if ( v7->CalcPortalShape(
            &a1,
            (unsigned int *)&a7,
            vert,
@@ -922,7 +922,7 @@
     v15 = pLineEnd->vWorldPosition.z;
     a1[1].vWorldPosition.y = pLineEnd->vWorldPosition.y;
     a1[1].vWorldPosition.z = v15;
-    if ( _437285_prolly_colide_vertices_against_frustrum(
+    if ( CalcPortalShape(
            a1,
            &uOutNumVertices,
            pVertices,
@@ -1349,7 +1349,7 @@
 }
 
 //----- (00437285) --------------------------------------------------------
-bool IndoorCameraD3D::_437285_prolly_colide_vertices_against_frustrum(RenderVertexSoft *a1, unsigned int *pOutNumVertices, RenderVertexSoft *pVertices, IndoorCameraD3D_Vec4 *a4, signed int uNumVertices, char a6, int _unused)
+bool IndoorCameraD3D::CalcPortalShape(RenderVertexSoft *a1, unsigned int *pOutNumVertices, RenderVertexSoft *pVertices, IndoorCameraD3D_Vec4 *a4, signed int uNumVertices, char a6, int _unused)
 {
   char *v8; // eax@2
   signed int v9; // ecx@2
@@ -1368,7 +1368,6 @@
 
   v17 = 0.0;
   //thisa = pGame->pStru9Instance;
-
   
   static RenderVertexSoft sr_vertices_50D9D8[64];
 
@@ -1400,7 +1399,7 @@
       a5.x = a4[i].x;
       a5.y = a4[i].y;
       a5.z = a4[i].z;
-      pGame->pStru9Instance->_4985FB(v15, *pOutNumVertices, v14, pOutNumVertices, &a5, a4[i].dot, (char *)&a7a, _unused);
+      pGame->pStru9Instance->CalcPortalShape(v15, *pOutNumVertices, v14, pOutNumVertices, &a5, a4[i].dot, (char *)&a7a, _unused);
       //v12 = *pOutNumVertices;
       if (*pOutNumVertices < v18)
         break;
@@ -1462,7 +1461,7 @@
     }
     while ( v12 < (signed int)*v7 );
   }
-  return _437285_prolly_colide_vertices_against_frustrum(
+  return CalcPortalShape(
            static_4371C3_array_50E5E0,
            v7,
            v6,
--- a/IndoorCameraD3D.h	Mon Mar 25 11:58:38 2013 +0200
+++ b/IndoorCameraD3D.h	Mon Mar 25 14:23:40 2013 +0200
@@ -135,7 +135,7 @@
   void _436F09_mess_with_lightmap__clipflag_4(struct RenderVertexSoft *pInVertices, int uNumInVertices, struct RenderVertexSoft *pOutVertices, unsigned int *pOutNumVertices);
   int _437143(unsigned int uNumInVertices, struct RenderVertexSoft *pOutVertices, struct RenderVertexSoft *pInVertices, unsigned int *pOutNumVertices);
   bool _4371C3(struct RenderVertexSoft *pVertices, unsigned int *pOutNumVertices, int _unused);
-  bool _437285_prolly_colide_vertices_against_frustrum(struct RenderVertexSoft *a1, unsigned int *pOutNumVertices, struct RenderVertexSoft *pVertices, IndoorCameraD3D_Vec4 *a4, signed int uNumVertices, char a6, int _unused);
+  bool CalcPortalShape(struct RenderVertexSoft *a1, unsigned int *pOutNumVertices, struct RenderVertexSoft *pVertices, IndoorCameraD3D_Vec4 *a4, signed int uNumVertices, char a6, int _unused);
   char _437376(struct stru154 *thisa, struct RenderVertexSoft *a2, unsigned int *pOutNumVertices);
   void _4374E8_ProllyBuildFrustrum();
   void _437607(IndoorCameraD3D_Vec3 *a1, IndoorCameraD3D_Vec4 *a2);
--- a/Indoor_stuff.h	Mon Mar 25 11:58:38 2013 +0200
+++ b/Indoor_stuff.h	Mon Mar 25 14:23:40 2013 +0200
@@ -54,9 +54,9 @@
   BspRenderer_stru2 field_C;
   unsigned __int16 uFaceID;
   __int16 field_7A6;
-  unsigned int std__vector_0007A8;
+  unsigned int         viewing_portal_id;             // portal through which we're seeing this node
   IndoorCameraD3D_Vec4 std__vector_0007AC[4];
-  RenderVertexSoft pPortalBounding[4];
+  RenderVertexSoft     pPortalBounding[4];
 };
 #pragma pack(pop)
 
--- a/mm7_3.cpp	Mon Mar 25 11:58:38 2013 +0200
+++ b/mm7_3.cpp	Mon Mar 25 14:23:40 2013 +0200
@@ -11035,7 +11035,7 @@
                                            pBLVRenderParams->uViewportZ,
                                            pBLVRenderParams->uViewportW);
     pBspRenderer->nodes[0].uFaceID = -1;
-    pBspRenderer->nodes[0].std__vector_0007A8 = -1;
+    pBspRenderer->nodes[0].viewing_portal_id = -1;
     pBspRenderer->num_nodes = 1;
     AddBspNodeToRenderList(0);
   }
--- a/stru10.cpp	Mon Mar 25 11:58:38 2013 +0200
+++ b/stru10.cpp	Mon Mar 25 14:23:40 2013 +0200
@@ -10,412 +10,103 @@
 
 
 
+int _49CE9E_sub0_x(RenderVertexSoft *pVertices, unsigned int uNumVertices, float test_val)
+{
+  float max_val = FLT_MAX;
+  int   idx = -1;
+
+  float temp_val;
+  for (uint i = 0; i < uNumVertices; ++i)
+  {
+    if (pVertices[i].vWorldPosition.x <= test_val)
+      temp_val = test_val - pVertices[i].vWorldPosition.x;
+    else
+      temp_val = pVertices[i].vWorldPosition.x - test_val;
+
+    if (temp_val < max_val)
+    {
+      max_val = temp_val;
+      idx = i;
+    }
+  }
+  return idx;
+}
+
+
+int _49CE9E_sub0_y(RenderVertexSoft *pVertices, unsigned int uNumVertices, float test_val)
+{
+  float max_val = FLT_MAX;
+  int   idx = -1;
+
+  float temp_val;
+  for (uint i = 0; i < uNumVertices; ++i)
+  {
+    if (pVertices[i].vWorldPosition.y <= test_val)
+      temp_val = test_val - pVertices[i].vWorldPosition.y;
+    else
+      temp_val = pVertices[i].vWorldPosition.y - test_val;
+
+    if (temp_val < max_val)
+    {
+      max_val = temp_val;
+      idx = i;
+    }
+  }
+  return idx;
+}
+
+
+int _49CE9E_sub0_z(RenderVertexSoft *pVertices, unsigned int uNumVertices, float test_val)
+{
+  float max_val = FLT_MAX;
+  int   idx = -1;
+
+  float temp_val;
+  for (uint i = 0; i < uNumVertices; ++i)
+  {
+    if (pVertices[i].vWorldPosition.z <= test_val)
+      temp_val = test_val - pVertices[i].vWorldPosition.z;
+    else
+      temp_val = pVertices[i].vWorldPosition.z - test_val;
+
+    if (temp_val < max_val)
+    {
+      max_val = temp_val;
+      idx = i;
+    }
+  }
+  return idx;
+}
 
 //----- (0049CE9E) --------------------------------------------------------
-void stru10::_49CE9E(BLVFace *pFace, RenderVertexSoft *a2, signed int a3, RenderVertexSoft *a4)
+void stru10::_49CE9E(BLVFace *pFace, RenderVertexSoft *pVertices, unsigned int uNumVertices, RenderVertexSoft *pOutLimits)
 {
-  char *v5; // eax@1
-  signed int v6; // edx@1
-  unsigned int v7; // eax@3
-  signed int v8; // ecx@11
-  signed int v9; // esi@11
-  RenderVertexSoft *v10; // edx@12
-  double v11; // st6@14
-  RenderVertexSoft *v12; // edx@19
-  signed int v13; // ecx@19
-  signed int v14; // esi@19
-  RenderVertexSoft *v15; // edi@20
-  double v16; // st6@22
-  signed int v17; // ecx@27
-  signed int v18; // edi@27
-  char *v19; // esi@28
-  double v20; // st6@30
-  signed int v21; // ecx@35
-  signed int v22; // edi@35
-  char *v23; // esi@36
-  double v24; // st7@38
-  signed int v25; // ecx@45
-  signed int v26; // esi@45
-  RenderVertexSoft *v27; // edx@46
-  double v28; // st6@48
-  signed int v29; // ecx@53
-  signed int v30; // esi@53
-  RenderVertexSoft *v31; // edi@54
-  double v32; // st6@56
-  signed int v33; // ecx@61
-  signed int v34; // edi@61
-  char *v35; // esi@62
-  double v36; // st6@64
-  signed int v37; // edi@69
-  char *v38; // esi@70
-  double v39; // st7@72
-  RenderVertexSoft *v40; // esi@77
-  signed int v41; // ecx@79
-  signed int v42; // esi@79
-  char *v43; // edx@80
-  double v44; // st6@82
-  RenderVertexSoft *v45; // eax@87
-  signed int v46; // ecx@87
-  signed int v47; // edi@87
-  char *v48; // esi@88
-  double v49; // st6@90
-  signed int v50; // ecx@96
-  signed int v51; // edi@96
-  char *v52; // esi@97
-  double v53; // st6@99
-  signed int v54; // ecx@105
-  signed int v55; // edi@105
-  char *v56; // esi@106
-  double v57; // st7@108
-  RenderVertexSoft a2a[64]; // [sp+0h] [bp-C18h]@1
-  float v59; // [sp+C00h] [bp-18h]@4
-  float v60; // [sp+C04h] [bp-14h]@9
-  float v61; // [sp+C08h] [bp-10h]@4
-  float v62; // [sp+C0Ch] [bp-Ch]@9
-  float v63; // [sp+C10h] [bp-8h]@4
-  float v64; // [sp+C14h] [bp-4h]@4
-  float a1a; // [sp+C20h] [bp+8h]@11
-  float a1b; // [sp+C20h] [bp+8h]@19
-  float a1c; // [sp+C20h] [bp+8h]@27
-  float a1d; // [sp+C20h] [bp+8h]@35
-  float a1e; // [sp+C20h] [bp+8h]@45
-  float a1f; // [sp+C20h] [bp+8h]@53
-  float a1g; // [sp+C20h] [bp+8h]@61
-  float a1h; // [sp+C20h] [bp+8h]@69
-  float a1i; // [sp+C20h] [bp+8h]@79
-  float a1j; // [sp+C20h] [bp+8h]@87
-  float a1k; // [sp+C20h] [bp+8h]@96
-  float a1l; // [sp+C20h] [bp+8h]@105
+  assert(sizeof(RenderVertexSoft) == 0x30);
+  
+  RenderVertexSoft pLimits[64];
+  stru10::CalcPolygonLimits(pFace, pLimits);
 
-  v5 = (char *)&a2a[0].flt_2C;
-  v6 = 64;
-  do
-  {
-    *(float *)v5 = 0.0;
-    v5 += 48;
-    --v6;
-  }
-  while ( v6 );
-  stru10::CalcPolygonLimits(pFace, a2a);
-  v7 = pFace->uAttributes;
-  if ( v7 & 0x100 )
-  {
-    v63 = a2a[0].vWorldPosition.x;
-    v59 = a2a[2].vWorldPosition.x;
-    v61 = a2a[1].vWorldPosition.y;
-    v64 = a2a[3].vWorldPosition.y;
-    goto LABEL_10;
-  }
-  if ( v7 & 0x200 )
-  {
-    v63 = a2a[0].vWorldPosition.x;
-    v59 = a2a[2].vWorldPosition.x;
-  }
-  else
-  {
-    if ( !(v7 & 0x400) )
-      goto LABEL_10;
-    v61 = a2a[0].vWorldPosition.y;
-    v64 = a2a[2].vWorldPosition.y;
-  }
-  v62 = a2a[1].vWorldPosition.z;
-  v60 = a2a[3].vWorldPosition.z;
-LABEL_10:
-  if ( v7 & 0x100 )
+  if (pFace->uAttributes & FACE_XY_PLANE)
   {
-    v8 = -1;
-    a1a = 3.4028235e38;
-    v9 = 0;
-    if ( a3 > 0 )
-    {
-      v10 = a2;
-      do
-      {
-        if ( v10->vWorldPosition.x <= (double)v63 )
-          v11 = v63 - v10->vWorldPosition.x;
-        else
-          v11 = v10->vWorldPosition.x - v63;
-        if ( v11 < a1a )
-        {
-          a1a = v11;
-          v8 = v9;
-        }
-        ++v9;
-        ++v10;
-      }
-      while ( v9 < a3 );
-    }
-    v12 = a4;
-    a1b = 3.4028235e38;
-    memcpy(a4, &a2[v8], 0x30u);
-    v13 = -1;
-    v14 = 0;
-    if ( a3 > 0 )
-    {
-      v15 = a2;
-      do
-      {
-        if ( v15->vWorldPosition.x <= (double)v59 )
-          v16 = v59 - v15->vWorldPosition.x;
-        else
-          v16 = v15->vWorldPosition.x - v59;
-        if ( v16 < a1b )
-        {
-          a1b = v16;
-          v13 = v14;
-        }
-        ++v14;
-        ++v15;
-      }
-      while ( v14 < a3 );
-    }
-    a1c = 3.4028235e38;
-    memcpy(&a4[2], &a2[v13], sizeof(a4[2]));
-    v17 = -1;
-    v18 = 0;
-    if ( a3 > 0 )
-    {
-      v19 = (char *)&a2->vWorldPosition.y;
-      do
-      {
-        if ( *(float *)v19 <= (double)v61 )
-          v20 = v61 - *(float *)v19;
-        else
-          v20 = *(float *)v19 - v61;
-        if ( v20 < a1c )
-        {
-          a1c = v20;
-          v17 = v18;
-        }
-        ++v18;
-        v19 += 48;
-      }
-      while ( v18 < a3 );
-    }
-    a1d = 3.4028235e38;
-    memcpy(&a4[1], &a2[v17], sizeof(a4[1]));
-    v21 = -1;
-    v22 = 0;
-    if ( a3 > 0 )
-    {
-      v23 = (char *)&a2->vWorldPosition.y;
-      do
-      {
-        if ( *(float *)v23 <= (double)v64 )
-          v24 = v64 - *(float *)v23;
-        else
-          v24 = *(float *)v23 - v64;
-        if ( v24 < a1d )
-        {
-          a1d = v24;
-          v21 = v22;
-        }
-        ++v22;
-        v23 += 48;
-      }
-      while ( v22 < a3 );
-    }
-LABEL_77:
-    v40 = &a2[v21];
-    goto LABEL_115;
+    memcpy(&pOutLimits[0], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[0].vWorldPosition.x)], 0x30);
+    memcpy(&pOutLimits[2], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[2].vWorldPosition.x)], 0x30);
+    memcpy(&pOutLimits[1], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[1].vWorldPosition.y)], 0x30);
+    memcpy(&pOutLimits[3], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[3].vWorldPosition.y)], 0x30);
   }
-  if ( v7 & 0x200 )
+  else if (pFace->uAttributes & FACE_XZ_PLANE)
+  {    
+    memcpy(&pOutLimits[0], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[0].vWorldPosition.x)], 0x30);
+    memcpy(&pOutLimits[2], &pVertices[_49CE9E_sub0_x(pVertices, uNumVertices, pLimits[2].vWorldPosition.x)], 0x30);
+    memcpy(&pOutLimits[1], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[1].vWorldPosition.z)], 0x30);
+    memcpy(&pOutLimits[3], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[3].vWorldPosition.z)], 0x30);
+  }
+  else if (pFace->uAttributes & FACE_YZ_PLANE)
   {
-    v25 = -1;
-    a1e = 3.4028235e38;
-    v26 = 0;
-    if ( a3 > 0 )
-    {
-      v27 = a2;
-      do
-      {
-        if ( v27->vWorldPosition.x <= (double)v63 )
-          v28 = v63 - v27->vWorldPosition.x;
-        else
-          v28 = v27->vWorldPosition.x - v63;
-        if ( v28 < a1e )
-        {
-          a1e = v28;
-          v25 = v26;
-        }
-        ++v26;
-        ++v27;
-      }
-      while ( v26 < a3 );
-    }
-    v12 = a4;
-    a1f = 3.4028235e38;
-    memcpy(a4, &a2[v25], 0x30u);
-    v29 = -1;
-    v30 = 0;
-    if ( a3 > 0 )
-    {
-      v31 = a2;
-      do
-      {
-        if ( v31->vWorldPosition.x <= (double)v59 )
-          v32 = v59 - v31->vWorldPosition.x;
-        else
-          v32 = v31->vWorldPosition.x - v59;
-        if ( v32 < a1f )
-        {
-          a1f = v32;
-          v29 = v30;
-        }
-        ++v30;
-        ++v31;
-      }
-      while ( v30 < a3 );
-    }
-    a1g = 3.4028235e38;
-    memcpy(&a4[2], &a2[v29], sizeof(a4[2]));
-    v33 = -1;
-    v34 = 0;
-    if ( a3 > 0 )
-    {
-      v35 = (char *)&a2->vWorldPosition.z;
-      do
-      {
-        if ( *(float *)v35 <= (double)v62 )
-          v36 = v62 - *(float *)v35;
-        else
-          v36 = *(float *)v35 - v62;
-        if ( v36 < a1g )
-        {
-          a1g = v36;
-          v33 = v34;
-        }
-        ++v34;
-        v35 += 48;
-      }
-      while ( v34 < a3 );
-    }
-    a1h = 3.4028235e38;
-    memcpy(&a4[1], &a2[v33], sizeof(a4[1]));
-    v21 = -1;
-    v37 = 0;
-    if ( a3 > 0 )
-    {
-      v38 = (char *)&a2->vWorldPosition.z;
-      do
-      {
-        if ( *(float *)v38 <= (double)v60 )
-          v39 = v60 - *(float *)v38;
-        else
-          v39 = *(float *)v38 - v60;
-        if ( v39 < a1h )
-        {
-          a1h = v39;
-          v21 = v37;
-        }
-        ++v37;
-        v38 += 48;
-      }
-      while ( v37 < a3 );
-    }
-    goto LABEL_77;
+    memcpy(&pOutLimits[0], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[0].vWorldPosition.y)], 0x30);
+    memcpy(&pOutLimits[2], &pVertices[_49CE9E_sub0_y(pVertices, uNumVertices, pLimits[2].vWorldPosition.y)], 0x30);
+    memcpy(&pOutLimits[1], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[1].vWorldPosition.z)], 0x30);
+    memcpy(&pOutLimits[3], &pVertices[_49CE9E_sub0_z(pVertices, uNumVertices, pLimits[3].vWorldPosition.z)], 0x30);
   }
-  if ( !(v7 & 0x400) )
-    return;
-  v41 = -1;
-  a1i = 3.4028235e38;
-  v42 = 0;
-  if ( a3 > 0 )
-  {
-    v43 = (char *)&a2->vWorldPosition.y;
-    do
-    {
-      if ( *(float *)v43 <= (double)v61 )
-        v44 = v61 - *(float *)v43;
-      else
-        v44 = *(float *)v43 - v61;
-      if ( v44 < a1i )
-      {
-        a1i = v44;
-        v41 = v42;
-      }
-      ++v42;
-      v43 += 48;
-    }
-    while ( v42 < a3 );
-  }
-  v45 = a2;
-  v12 = a4;
-  a1j = 3.4028235e38;
-  memcpy(a4, &a2[v41], 0x30u);
-  v46 = -1;
-  v47 = 0;
-  if ( a3 > 0 )
-  {
-    v48 = (char *)&a2->vWorldPosition.y;
-    do
-    {
-      if ( *(float *)v48 <= (double)v64 )
-        v49 = v64 - *(float *)v48;
-      else
-        v49 = *(float *)v48 - v64;
-      if ( v49 < a1j )
-      {
-        a1j = v49;
-        v46 = v47;
-      }
-      ++v47;
-      v48 += 48;
-    }
-    while ( v47 < a3 );
-    v45 = a2;
-  }
-  a1k = 3.4028235e38;
-  memcpy(&a4[2], &v45[v46], sizeof(a4[2]));
-  v50 = -1;
-  v51 = 0;
-  if ( a3 > 0 )
-  {
-    v52 = (char *)&v45->vWorldPosition.z;
-    do
-    {
-      if ( *(float *)v52 <= (double)v62 )
-        v53 = v62 - *(float *)v52;
-      else
-        v53 = *(float *)v52 - v62;
-      if ( v53 < a1k )
-      {
-        a1k = v53;
-        v50 = v51;
-      }
-      ++v51;
-      v52 += 48;
-    }
-    while ( v51 < a3 );
-    v45 = a2;
-  }
-  a1l = 3.4028235e38;
-  memcpy(&a4[1], &v45[v50], sizeof(a4[1]));
-  v54 = -1;
-  v55 = 0;
-  if ( a3 > 0 )
-  {
-    v56 = (char *)&v45->vWorldPosition.z;
-    do
-    {
-      if ( *(float *)v56 <= (double)v60 )
-        v57 = v60 - *(float *)v56;
-      else
-        v57 = *(float *)v56 - v60;
-      if ( v57 < a1l )
-      {
-        a1l = v57;
-        v54 = v55;
-      }
-      ++v55;
-      v56 += 48;
-    }
-    while ( v55 < a3 );
-    v45 = a2;
-  }
-  v40 = &v45[v54];
-LABEL_115:
-  memcpy(&v12[3], v40, sizeof(v12[3]));
 }
 
 //----- (0049D379) --------------------------------------------------------
@@ -1061,38 +752,22 @@
 }
 
 //----- (0049C5DA) --------------------------------------------------------
-char stru10::_49C5DA(BLVFace *a2, RenderVertexSoft *a3, int *a4, IndoorCameraD3D_Vec4 *a5, RenderVertexSoft *a6)
+char stru10::_49C5DA(BLVFace *pFace, RenderVertexSoft *pVertices, unsigned int *pNumVertices, IndoorCameraD3D_Vec4 *a5, RenderVertexSoft *pOutBounding)
 {
-  //stru10 *v6; // edi@1
-  //char *v7; // eax@1
-  //signed int v8; // ecx@1
-  //IndoorCameraD3D *v9; // esi@3
-  char result; // al@6
-  RenderVertexSoft a4a[4]; // [sp+Ch] [bp-C0h]@1
+  RenderVertexSoft pLimits[4]; // [sp+Ch] [bp-C0h]@1
+
+  _49CE9E(pFace, pVertices, *pNumVertices, pLimits);
 
-  /*v6 = this;
-  v7 = (char *)&a4a[0].flt_2C;
-  v8 = 4;
-  do
-  {
-    *(float *)v7 = 0.0;
-    v7 += 48;
-    --v8;
-  }
-  while ( v8 );
-  v9 = pGame->pIndoorCameraD3D;*/
-  _49CE9E(a2, a3, *a4, a4a);
-  if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
-    pGame->pIndoorCameraD3D->debug_outline_sw(a4a, 4u, 0xFF1E1Eu, 0.000099999997);
-  result = CalcFaceBounding(a2, a4a, 4u, a6);
-  if ( result )
-    result = _49C720(a6, a5);
-  return result;
+  //if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
+  //  pGame->pIndoorCameraD3D->debug_outline_sw(a4a, 4u, 0xFF1E1Eu, 0.000099999997);
+  if (CalcFaceBounding(pFace, pLimits, 4, pOutBounding))
+    return _49C720(pOutBounding, a5);
+  return false;
 }
 // 4D864C: using guessed type char byte_4D864C;
 
 //----- (0049C681) --------------------------------------------------------
-char stru10::MessWithPortal(BLVFace *pFace, IndoorCameraD3D_Vec4 *a3, RenderVertexSoft *pOutBounding)
+bool stru10::CalcPortalShape(BLVFace *pFace, IndoorCameraD3D_Vec4 *a3, RenderVertexSoft *pOutBounding)
 {
   RenderVertexSoft pLimits[4]; // [sp+Ch] [bp-C0h]@1
 
@@ -1106,25 +781,19 @@
 // 4D864C: using guessed type char byte_4D864C;
 
 //----- (0049C720) --------------------------------------------------------
-char stru10::_49C720(RenderVertexSoft *a2, IndoorCameraD3D_Vec4 *a4)
+char stru10::_49C720(RenderVertexSoft *pFaceBounding, IndoorCameraD3D_Vec4 *a4)
 {
-  char result; // al@2
   Vec3_float_ a3; // [sp+4h] [bp-34h]@1
-  float v5; // [sp+30h] [bp-8h]@1
-  stru10 *thisa; // [sp+34h] [bp-4h]@1
-
-  v5 = 0.0;
   a3.x = (double)pBLVRenderParams->vPartyPos.x;
   a3.y = (double)pBLVRenderParams->vPartyPos.y;
-  thisa = this;
   a3.z = (double)pBLVRenderParams->vPartyPos.z;
-  if ( FindFaceNormal(a2, a2 + 1, &a3, a4)
-    && FindFaceNormal(a2 + 1, a2 + 2, &a3, a4 + 1)
-    && FindFaceNormal(a2 + 2, a2 + 3, &a3, a4 + 2) )
-    result = FindFaceNormal(a2 + 3, a2, &a3, a4 + 3) != 0;
-  else
-    result = 0;
-  return result;
+
+  if (FindFaceNormal(pFaceBounding,     pFaceBounding + 1, &a3, a4) &&
+      FindFaceNormal(pFaceBounding + 1, pFaceBounding + 2, &a3, a4 + 1) &&
+      FindFaceNormal(pFaceBounding + 2, pFaceBounding + 3, &a3, a4 + 2) &&
+      FindFaceNormal(pFaceBounding + 3, pFaceBounding,     &a3, a4 + 3))
+    return true;
+  return false;
 }
 
 //----- (0049C7C5) --------------------------------------------------------
--- a/stru10.h	Mon Mar 25 11:58:38 2013 +0200
+++ b/stru10.h	Mon Mar 25 14:23:40 2013 +0200
@@ -7,14 +7,14 @@
 {
   stru10();
   virtual ~stru10();
-  char _49C5DA(struct BLVFace *a2, struct RenderVertexSoft *a3, int *a4, struct IndoorCameraD3D_Vec4 *a5, struct RenderVertexSoft *a6);
-  char MessWithPortal(struct BLVFace *pFace, struct IndoorCameraD3D_Vec4 *a3, struct RenderVertexSoft *pOutBounding);
-  char _49C720(struct RenderVertexSoft *a2, struct IndoorCameraD3D_Vec4 *a4);
+  char _49C5DA(struct BLVFace *pFace, struct RenderVertexSoft *pVertices, unsigned int *pNumVertices, struct IndoorCameraD3D_Vec4 *a5, struct RenderVertexSoft *pOutBounding);
+  bool CalcPortalShape(struct BLVFace *pFace, struct IndoorCameraD3D_Vec4 *a3, struct RenderVertexSoft *pOutBounding);
+  char _49C720(struct RenderVertexSoft *pFaceBounding, struct IndoorCameraD3D_Vec4 *a4);
   bool FindFaceNormal(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct Vec3_float_ *a3, struct IndoorCameraD3D_Vec4 *a4);
   bool FindFacePlane(struct RenderVertexSoft *face, struct Vec3_float_ *out_normal, float *out_distance);
   bool CalcFaceBounding(struct BLVFace *pFace, struct RenderVertexSoft *pFaceLimits, unsigned int uNumVertices, struct RenderVertexSoft *pOutBounding);
   void CalcPolygonLimits(struct BLVFace *pFace, struct RenderVertexSoft pOutVertices[4]);
-  void _49CE9E(struct BLVFace *pFace, struct RenderVertexSoft *a2, signed int a3, RenderVertexSoft *a4);
+  void _49CE9E(struct BLVFace *pFace, struct RenderVertexSoft *pVertices, unsigned int uNumVertices, RenderVertexSoft *pOutLimits);
 
 
   void (__thiscall ***vdestructor_ptr)(stru10 *, bool);
--- a/stru9.cpp	Mon Mar 25 11:58:38 2013 +0200
+++ b/stru9.cpp	Mon Mar 25 14:23:40 2013 +0200
@@ -174,7 +174,7 @@
 
 
 //----- (004985FB) --------------------------------------------------------
-bool stru9::_4985FB(struct RenderVertexSoft *a1, signed int a2, struct RenderVertexSoft *a3, unsigned int *pOutNumVertices, struct Vec3_float_ *a5, float a6, char *a7, int unused)
+bool stru9::CalcPortalShape(struct RenderVertexSoft *a1, signed int a2, struct RenderVertexSoft *a3, unsigned int *pOutNumVertices, struct Vec3_float_ *a5, float a6, char *a7, int unused)
 {
   RenderVertexSoft *v9; // ecx@1
   Vec3_float_ *v10; // esi@1
--- a/stru9.h	Mon Mar 25 11:58:38 2013 +0200
+++ b/stru9.h	Mon Mar 25 14:23:40 2013 +0200
@@ -52,7 +52,7 @@
 
   bool _4980B9(struct RenderVertexSoft *a1, unsigned int uNumVertices, float a3, float a4, float a5, struct RenderVertexSoft *pOutVertices, unsigned int *pOutNumVertices);
   bool _498377(struct RenderVertexSoft *pPortalBounding, unsigned int uNumVertices, struct IndoorCameraD3D_Vec4 *a3, struct RenderVertexSoft *pVertices, unsigned int *pOutNumVertices);
-  bool _4985FB(struct RenderVertexSoft *a1, signed int a2, struct RenderVertexSoft *a3, unsigned int *pOutNumVertices, struct Vec3_float_ *a5, float a6, char *a7, int unused);
+  bool CalcPortalShape(struct RenderVertexSoft *a1, signed int a2, struct RenderVertexSoft *a3, unsigned int *pOutNumVertices, struct Vec3_float_ *a5, float a6, char *a7, int unused);
   void AddVertex(struct VertexBuffer *pVertexBuffer, struct RenderVertexSoft *pVertex);
   bool _498774(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct RenderVertexSoft *a3, struct stru312 *a4, struct RenderVertexSoft *a5);
   bool AreVectorsCollinear(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct stru312 *a3);