changeset 794:4a00901e063c

stru10
author Nomad
date Mon, 25 Mar 2013 11:58:38 +0200
parents 290afbd48b6b
children 472ca68386d4 9a3121bbc1d0
files Game.cpp Indoor.cpp Indoor.h Indoor_stuff.h Monsters.h stru10.cpp stru10.h stru9.cpp stru9.h
diffstat 9 files changed, 218 insertions(+), 268 deletions(-) [+]
line wrap: on
line diff
--- a/Game.cpp	Mon Mar 25 09:17:42 2013 +0200
+++ b/Game.cpp	Mon Mar 25 11:58:38 2013 +0200
@@ -173,6 +173,35 @@
     GameUI_DrawTorchlightAndWizardEye();
   }
 
+
+  static bool render_framerate = false;
+  static float framerate = 0.0f;
+  static uint frames_this_second = 0;
+  static uint last_frame_time = GetTickCount();
+  static uint framerate_time_elapsed = 0;
+
+  auto frame_dt = GetTickCount() - last_frame_time;
+  last_frame_time = GetTickCount();
+
+  framerate_time_elapsed += frame_dt;
+  if (framerate_time_elapsed >= 1000)
+  {
+    framerate = frames_this_second *  (1000.0f / framerate_time_elapsed);
+
+    framerate_time_elapsed = 0;
+    frames_this_second = 0;
+    render_framerate = true;
+  }
+
+  ++frames_this_second;
+
+
+  if (render_framerate)
+  {
+    sprintf(pTmpBuf, "FPS: % .4f", framerate);
+    pPrimaryWindow->DrawText(pFontArrus, 494, 0, GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, 0, 0), pTmpBuf, 0, 0, 0);
+  }
+
   if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
   {
     sprintf(pTmpBuf, "Party Sector ID:        %u/%u\n", pBLVRenderParams->uPartySectorID, pIndoor->uNumSectors);
@@ -660,7 +689,7 @@
     return false;
 
     if ( uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
-      LOBYTE(pStru10Instance->field_4) = 0;
+      pStru10Instance->bDoNotDrawPortalFrustum = false;
     if ( pRenderer->pRenderD3D && uCurrentlyLoadedLevelType == LEVEL_Outdoor)
     {
       v5 = GetLevelFogColor();
--- a/Indoor.cpp	Mon Mar 25 09:17:42 2013 +0200
+++ b/Indoor.cpp	Mon Mar 25 11:58:38 2013 +0200
@@ -289,7 +289,7 @@
       else
       {
         v3 = pBspRenderer->nodes[v2].std__vector_0007AC;
-        v6 = pBspRenderer->nodes[v2].pVertices;
+        v6 = pBspRenderer->nodes[v2].pPortalBounding;
       }
       IndoorLocation::ExecDraw_d3d(pBspRenderer->faces[i].uFaceID, v3, 4, v6);
     }
@@ -439,7 +439,7 @@
 }
 
 //----- (004B0A25) --------------------------------------------------------
-void IndoorLocation::ExecDraw_d3d(unsigned int uFaceID, IndoorCameraD3D_Vec4 *pVertices, unsigned int uNumVertices, RenderVertexSoft *a4)
+void IndoorLocation::ExecDraw_d3d(unsigned int uFaceID, IndoorCameraD3D_Vec4 *pVertices, unsigned int uNumVertices, RenderVertexSoft *pPortalBounding)
 {
   //unsigned int v4; // esi@1
   char *v5; // eax@4
@@ -515,7 +515,7 @@
     }
 
     if (!pVertices ||
-        (pGame->pStru9Instance->_498377(a4, 4u, pVertices, static_vertices_F7C228, &uNumVerticesa), uNumVerticesa) )
+        (pGame->pStru9Instance->_498377(pPortalBounding, 4u, pVertices, static_vertices_F7C228, &uNumVerticesa), uNumVerticesa) )
     {
       if (pGame->pIndoorCameraD3D->_437285_prolly_colide_vertices_against_frustrum(static_vertices_F7C228, &uNumVerticesa,
                      static_vertices_F7B628, pGame->pIndoorCameraD3D->std__vector_000034_prolly_frustrum, 4, false, 0) != 1 || uNumVerticesa )
@@ -1422,7 +1422,7 @@
           //a0a = pGame->pIndoorCameraD3D;
           if (p->std__vector_0007A8 == -1 )
           {
-            v29 = pGame->pStru10Instance->_49C681_DrawDebugStuff(pFace, nodes[num_nodes].std__vector_0007AC, nodes[num_nodes].pVertices);
+            v29 = pGame->pStru10Instance->MessWithPortal(pFace, nodes[num_nodes].std__vector_0007AC, nodes[num_nodes].pPortalBounding);
           }
           else
           {
@@ -1459,7 +1459,7 @@
               0);
             v29 = pGame->pStru10Instance->_49C5DA(pFace, static_subAddFaceToRenderList_d3d_stru_F79E08, (int *)&a2,
                     nodes[num_nodes].std__vector_0007AC,
-                    nodes[num_nodes].pVertices);
+                    nodes[num_nodes].pPortalBounding);
           }
           if ( v29 )
           {
--- a/Indoor.h	Mon Mar 25 09:17:42 2013 +0200
+++ b/Indoor.h	Mon Mar 25 11:58:38 2013 +0200
@@ -443,7 +443,7 @@
   static unsigned int GetLocationIndex(const char *Str1);
   static void ExecDraw(bool bD3D);
   static void ExecDraw_sw(unsigned int uFaceID);
-  static void ExecDraw_d3d(unsigned int uFaceID, struct IndoorCameraD3D_Vec4 *pVertices, unsigned int uNumVertices, struct RenderVertexSoft *a4);
+  static void ExecDraw_d3d(unsigned int uFaceID, struct IndoorCameraD3D_Vec4 *pVertices, unsigned int uNumVertices, struct RenderVertexSoft *pPortalBounding);
 
   char pFilename[32];
   char field_20[48];
--- a/Indoor_stuff.h	Mon Mar 25 09:17:42 2013 +0200
+++ b/Indoor_stuff.h	Mon Mar 25 11:58:38 2013 +0200
@@ -56,7 +56,7 @@
   __int16 field_7A6;
   unsigned int std__vector_0007A8;
   IndoorCameraD3D_Vec4 std__vector_0007AC[4];
-  RenderVertexSoft pVertices[4];
+  RenderVertexSoft pPortalBounding[4];
 };
 #pragma pack(pop)
 
--- a/Monsters.h	Mon Mar 25 09:17:42 2013 +0200
+++ b/Monsters.h	Mon Mar 25 11:58:38 2013 +0200
@@ -86,6 +86,10 @@
     Hostility_Long = 4
   };
 
+  inline MonsterInfo():
+    pName(nullptr), pPictureName(nullptr)
+  {}
+
   char *pName;
   char *pPictureName;
   unsigned __int8 uLevel;
--- a/stru10.cpp	Mon Mar 25 09:17:42 2013 +0200
+++ b/stru10.cpp	Mon Mar 25 11:58:38 2013 +0200
@@ -96,7 +96,7 @@
     --v6;
   }
   while ( v6 );
-  stru10::CalcPolygonBoundingBox(pFace, a2a);
+  stru10::CalcPolygonLimits(pFace, a2a);
   v7 = pFace->uAttributes;
   if ( v7 & 0x100 )
   {
@@ -419,7 +419,7 @@
 }
 
 //----- (0049D379) --------------------------------------------------------
-void stru10::CalcPolygonBoundingBox(BLVFace *pFace, RenderVertexSoft *pOutVertices)
+void stru10::CalcPolygonLimits(BLVFace *pFace, RenderVertexSoft *pOutVertices)
 {
   struct
   {
@@ -526,7 +526,7 @@
 
 
 //----- (0049C9E3) --------------------------------------------------------
-bool stru10::_49C9E3(BLVFace *pFace, RenderVertexSoft *pFaceBounding, unsigned int uNumVertices, RenderVertexSoft *arg0)
+bool stru10::CalcFaceBounding(BLVFace *pFace, RenderVertexSoft *pFaceLimits, unsigned int uNumVertices, RenderVertexSoft *pOutBounding)
 {
   //IndoorCameraD3D *v6; // edi@1
   //PolygonType v7; // al@1
@@ -547,9 +547,9 @@
   //RenderVertexSoft v26; // [sp+40h] [bp-60h]@20
   //IndoorCameraD3D *thisa; // [sp+70h] [bp-30h]@1
   //stru10 *v31; // [sp+84h] [bp-1Ch]@1
-  float v32; // [sp+88h] [bp-18h]@8
+  //float v32; // [sp+88h] [bp-18h]@8
   Vec3_float_ a1; // [sp+8Ch] [bp-14h]@1
-  float v35; // [sp+9Ch] [bp-4h]@8
+  //float v35; // [sp+9Ch] [bp-4h]@8
 
   //auto a3 = pFace;
   //auto arg4 = pFaceBounding;
@@ -565,85 +565,68 @@
 
   float var_28;
   float var_24;
-  if (pFace->uPolygonType == POLYGON_VerticalWall)
+  switch (pFace->uPolygonType)
   {
-    a1.x = -pFace->pFacePlane.vNormal.y;
-    a1.y = pFace->pFacePlane.vNormal.x;
-    a1.z = 0.0f;
-    a1.Normalize();
+    case POLYGON_VerticalWall:
+      a1.x = -pFace->pFacePlane.vNormal.y;
+      a1.y = pFace->pFacePlane.vNormal.x;
+      a1.z = 0.0f;
+      a1.Normalize();
+
+      var_28 = 0;
+      var_24 = 1;
+    break;
 
-    var_28 = 0;
-    var_24 = 1;
+    case POLYGON_Floor:
+    case POLYGON_Ceiling:
+      a1.x = 1;
+      a1.y = 0;
+      a1.z = 0.0f;
+
+      var_28 = 1;
+      var_24 = 0;
+    break;
+
+    default:
+      assert(false);
   }
-  else if (pFace->uPolygonType == POLYGON_Floor ||
-           pFace->uPolygonType == POLYGON_Ceiling)
-  {
-    a1.x = 1;
-    a1.y = 0;
-    a1.z = 0.0f;
-
-    var_28 = 1;
-    var_24 = 0;
-  }
-  else assert(false);
 
 
-  float arg_4;
-  float var_18;
-  float var_4;
+  float face_center_x;
+  float face_center_y;
+  float face_center_z;
   float a3;
   float var_8;
-  //v8 = _ESI->uAttributes;
-  //_ECX = pFaceBounding;
-  //__asm { fld     0.5 }
+
   if (pFace->uAttributes & 0x0100)
   {
-    /*arg_4 = ([2].x + [0].x) * flt_4D84F0
-      var_18 = ([3].y + [1].y) * flt_4D84F0
+    face_center_x = (pFaceLimits[0].vWorldPosition.x + pFaceLimits[2].vWorldPosition.x) / 2;
+    face_center_y = (pFaceLimits[3].vWorldPosition.y + pFaceLimits[1].vWorldPosition.y) / 2;
+    face_center_z = (pFaceLimits[0].vWorldPosition.z + pFaceLimits[2].vWorldPosition.z) / 2;
 
-      fld     dword ptr [ecx+94h]
-      fadd    dword ptr [ecx+34h]
-      fmul    st, st(1)
-      fstp    [ebp+var_18]
-      fld     dword ptr [ecx+68h]
-      fadd    dword ptr [ecx+8]
-      fmul    st, st(1)
-      fstp    [ebp+var_4]
-      fld     [ebp+arg4]
-      fsub    dword ptr [ecx]
-      fstp    [ebp+a3]
-      fld     [ebp+var_18]
-      fsub    dword ptr [ecx+34h]
-      fstp    [ebp+var_8]*/
-
-
-    arg_4 = (pFaceBounding[0].vWorldPosition.x + pFaceBounding[2].vWorldPosition.x) / 2;
-    var_18 = (pFaceBounding[3].vWorldPosition.y + pFaceBounding[1].vWorldPosition.y) / 2;
-    var_4 = (pFaceBounding[0].vWorldPosition.z + pFaceBounding[2].vWorldPosition.z) / 2;
-
-    a3 = arg_4 - pFaceBounding[0].vWorldPosition.x;
-    var_8 = var_18 - pFaceBounding[1].vWorldPosition.y;
+    a3 = face_center_x - pFaceLimits[0].vWorldPosition.x;
+    var_8 = face_center_y - pFaceLimits[1].vWorldPosition.y;
   }
   if (pFace->uAttributes & 0x0200)
   {
-    arg_4 = (pFaceBounding[0].vWorldPosition.x + pFaceBounding[2].vWorldPosition.x) / 2;
-    var_18 = (pFaceBounding[0].vWorldPosition.y + pFaceBounding[2].vWorldPosition.y) / 2;
-    var_4 = (pFaceBounding[1].vWorldPosition.z + pFaceBounding[3].vWorldPosition.z) / 2;
+    face_center_x = (pFaceLimits[0].vWorldPosition.x + pFaceLimits[2].vWorldPosition.x) / 2;
+    face_center_y = (pFaceLimits[0].vWorldPosition.y + pFaceLimits[2].vWorldPosition.y) / 2;
+    face_center_z = (pFaceLimits[1].vWorldPosition.z + pFaceLimits[3].vWorldPosition.z) / 2;
 
-    a3 = arg_4 - pFaceBounding[0].vWorldPosition.x;
-    var_8 = var_4 - pFaceBounding[1].vWorldPosition.z;
+    a3 = face_center_x - pFaceLimits[0].vWorldPosition.x;
+    var_8 = face_center_z - pFaceLimits[1].vWorldPosition.z;
 
     if (pFace->uPolygonType == POLYGON_VerticalWall)
       a3 /= a1.x;
   }
   if (pFace->uAttributes & 0x0400)
   {
-    arg_4 = (pFaceBounding[0].vWorldPosition.x + pFaceBounding[2].vWorldPosition.x) / 2;
-    var_18 = (pFaceBounding[0].vWorldPosition.y + pFaceBounding[2].vWorldPosition.y) / 2;
-    var_4 = (pFaceBounding[1].vWorldPosition.z + pFaceBounding[3].vWorldPosition.z) / 2;
+    face_center_x = (pFaceLimits[0].vWorldPosition.x + pFaceLimits[2].vWorldPosition.x) / 2;
+    face_center_y = (pFaceLimits[0].vWorldPosition.y + pFaceLimits[2].vWorldPosition.y) / 2;
+    face_center_z = (pFaceLimits[1].vWorldPosition.z + pFaceLimits[3].vWorldPosition.z) / 2;
 
-    a3 = var_18 - pFaceBounding[0].vWorldPosition.y;
-    var_8 = var_4 - pFaceBounding[1].vWorldPosition.z;
+    a3 = face_center_y - pFaceLimits[0].vWorldPosition.y;
+    var_8 = face_center_z - pFaceLimits[1].vWorldPosition.z;
                                        // [0.5]
     if (pFace->uPolygonType == POLYGON_VerticalWall)
     {
@@ -653,15 +636,7 @@
   }
 
 
-  if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
-  {
-    RenderVertexSoft v26; // [sp+40h] [bp-60h]@20
-    v26.vWorldPosition.x = arg_4;
-    v26.vWorldPosition.y = v32;
-    v26.vWorldPosition.z = v35;
 
-    pGame->pIndoorCameraD3D->do_draw_debug_line_sw(pFaceBounding, 0xFF00u, &v26, 0xFF0000u, 0, 0);
-  }
 
   //_EBX = arg0;
   //v15 = v31;
@@ -980,82 +955,95 @@
 							0 empty
 */
 
-  arg0[0].vWorldPosition.x = arg_4 - a3 * a1.x + var_8 * flt_4D84E8;
-  arg0[0].vWorldPosition.y = var_18 - a3 * a1.y + var_8 * var_28;
-  arg0[0].vWorldPosition.z = var_4 - a3 * a1.z + var_8 * var_24;
+  pOutBounding[0].vWorldPosition.x = face_center_x - a3 * a1.x + var_8 * flt_4D84E8;
+  pOutBounding[0].vWorldPosition.y = face_center_y - a3 * a1.y + var_8 * var_28;
+  pOutBounding[0].vWorldPosition.z = face_center_z - a3 * a1.z + var_8 * var_24;
 
-  arg0[1].vWorldPosition.x = arg_4 - a3 * a1.x - var_8 * flt_4D84E8;
-  arg0[1].vWorldPosition.y = var_18 - a3 * a1.y - var_8 * var_28;
-  arg0[1].vWorldPosition.z = var_4 - a3 * a1.z - var_8 * var_24;
+  pOutBounding[1].vWorldPosition.x = face_center_x - a3 * a1.x - var_8 * flt_4D84E8;
+  pOutBounding[1].vWorldPosition.y = face_center_y - a3 * a1.y - var_8 * var_28;
+  pOutBounding[1].vWorldPosition.z = face_center_z - a3 * a1.z - var_8 * var_24;
 
-  arg0[2].vWorldPosition.x = arg_4 + a3 * a1.x - var_8 * flt_4D84E8;
-  arg0[2].vWorldPosition.y = var_18 + a3 * a1.y - var_8 * var_28;
-  arg0[2].vWorldPosition.z = var_4 + a3 * a1.z - var_8 * var_24;
+  pOutBounding[2].vWorldPosition.x = face_center_x + a3 * a1.x - var_8 * flt_4D84E8;
+  pOutBounding[2].vWorldPosition.y = face_center_y + a3 * a1.y - var_8 * var_28;
+  pOutBounding[2].vWorldPosition.z = face_center_z + a3 * a1.z - var_8 * var_24;
 
-  arg0[3].vWorldPosition.x = arg_4 + a3 * a1.x + var_8 * flt_4D84E8;
-  arg0[3].vWorldPosition.y = var_18 + a3 * a1.y + var_8 * var_28;
-  arg0[3].vWorldPosition.z = var_4 + a3 * a1.z + var_8 * var_24;
-
+  pOutBounding[3].vWorldPosition.x = face_center_x + a3 * a1.x + var_8 * flt_4D84E8;
+  pOutBounding[3].vWorldPosition.y = face_center_y + a3 * a1.y + var_8 * var_28;
+  pOutBounding[3].vWorldPosition.z = face_center_z + a3 * a1.z + var_8 * var_24;
 
   a1.x = 0.0f;
   a1.y = 0.0f;
   a1.z = 0.0f;
-  a3 = arg_4 + a3 * a1.x;
+  a3 = face_center_x + a3 * a1.x;
 
-  if (!_49C8DC(arg0, &a1, &a3))
+  if (!FindFacePlane(pOutBounding, &a1, &a3))
     return false;
 
 
-  if ( byte_4D864C )
-  {
-      if ( pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
-      {
-        RenderVertexSoft v25; // [sp+10h] [bp-90h]@20
-        RenderVertexSoft v26; // [sp+40h] [bp-60h]@20
-
-        v25.vWorldPosition.x = arg_4;
-        v25.vWorldPosition.y = v32;
-        v25.vWorldPosition.z = v35;
-
-        v26.vWorldPosition.x = a1.x * 30.0f;
-        v26.vWorldPosition.y = a1.y * 30.0f;
-        v26.vWorldPosition.z = a1.z * 30.0f;
-
-        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v25, 0xFFFFFFFFu, &v26, 0xFFFF00u, 0, 0);
-      }
-  }
-
 
   RenderVertexSoft v25; // [sp+10h] [bp-90h]@20
-  memcpy(&v25, arg0, sizeof(RenderVertexSoft));
+  memcpy(&v25, pOutBounding, sizeof(RenderVertexSoft));
 
   float _dp = (v25.vWorldPosition.x - pBLVRenderParams->vPartyPos.x) * a1.x +
               (v25.vWorldPosition.y - pBLVRenderParams->vPartyPos.y) * a1.y +
               (v25.vWorldPosition.z - pBLVRenderParams->vPartyPos.z) * a1.z;
   if (fabs(_dp) < 1e-6f)
   {
-    memcpy(&v25, arg0 + 1, sizeof(RenderVertexSoft));
-    memcpy(arg0 + 1, arg0 + 3, sizeof(RenderVertexSoft));
-    memcpy(arg0 + 3, &v25, sizeof(RenderVertexSoft));
+    memcpy(&v25, pOutBounding + 1, sizeof(RenderVertexSoft));
+    memcpy(pOutBounding + 1, pOutBounding + 3, sizeof(RenderVertexSoft));
+    memcpy(pOutBounding + 3, &v25, sizeof(RenderVertexSoft));
   }
 
-    if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
-    {
+    //if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
+    //{
       RenderVertexSoft v26; // [sp+40h] [bp-60h]@20
-      if ( !LOBYTE(field_4) )
+      if (!bDoNotDrawPortalFrustum)
       {
         v26.vWorldPosition.x = pParty->vPosition.x;
         v26.vWorldPosition.y = pParty->vPosition.y;
-        v26.vWorldPosition.z = pParty->vPosition.z + pParty->sEyelevel;
+        v26.vWorldPosition.z = pParty->vPosition.z + pParty->sEyelevel;             // frustum
+
+        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFF0000u, pOutBounding, 0xFF0000u, 0, 0);
+        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFF00u, pOutBounding + 1, 0xFF00u, 0, 0);
+        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFFu, pOutBounding + 2, 0xFFu, 0, 0);
+        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFFFFFFu, pOutBounding + 3, 0xFFFFFFu, 0, 0);
+        bDoNotDrawPortalFrustum = true;
+      }
+      pGame->pIndoorCameraD3D->debug_outline_sw(pOutBounding, uNumVertices, 0x1EFF1Eu, 0.00019999999);    // bounding
+    //}
+
+    //pGame->pIndoorCameraD3D->debug_outline_sw(pFaceLimits,  4, 0xFFF14040, 0.000099999997);     // limits
+
+  /*if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
+  {
+    RenderVertexSoft v26; // [sp+40h] [bp-60h]@20
+    v26.vWorldPosition.x = face_center_x;                                    // corner to center
+    v26.vWorldPosition.y = face_center_y;
+    v26.vWorldPosition.z = face_center_z;
 
-        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFF0000u, arg0, 0xFF0000u, 0, 0);
-        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFF00u, arg0 + 1, 0xFF00u, 0, 0);
-        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFFu, arg0 + 2, 0xFFu, 0, 0);
-        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v26, 0xFFFFFFu, arg0 + 3, 0xFFFFFFu, 0, 0);
-        LOBYTE(field_4) = 1;
+    pGame->pIndoorCameraD3D->do_draw_debug_line_sw(pFaceLimits, 0xFF00u, &v26, 0xFF0000u, 0, 0);  
+  }*/
+
+
+        /*if ( byte_4D864C )
+  {
+      if ( pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)*/
+      {
+        RenderVertexSoft v25; // [sp+10h] [bp-90h]@20
+        RenderVertexSoft v26; // [sp+40h] [bp-60h]@20
+
+        v25.vWorldPosition.x = face_center_x;                 // portal normal
+        v25.vWorldPosition.y = face_center_y;
+        v25.vWorldPosition.z = face_center_z;
+
+        v26.vWorldPosition.x = face_center_x + a1.x * 400.0f;
+        v26.vWorldPosition.y = face_center_y + a1.y * 400.0f;
+        v26.vWorldPosition.z = face_center_z + a1.z * 400.0f;
+
+        pGame->pIndoorCameraD3D->do_draw_debug_line_sw(&v25, 0xFFFFFFFFu, &v26, 0xFFFF00u, 0, 0);
       }
-      pGame->pIndoorCameraD3D->debug_outline_sw(arg0, uNumVertices, 0x1EFF1Eu, 0.00019999999);
-    }
+  //}
+
   return true;
 }
 
@@ -1064,7 +1052,7 @@
 //----- (0049C5B0) --------------------------------------------------------
 stru10::stru10()
 {
-  LOBYTE(this->field_4) = 0;
+  this->bDoNotDrawPortalFrustum = false;
 }
 
 //----- (0049C5BD) --------------------------------------------------------
@@ -1096,7 +1084,7 @@
   _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 = _49C9E3(a2, a4a, 4u, a6);
+  result = CalcFaceBounding(a2, a4a, 4u, a6);
   if ( result )
     result = _49C720(a6, a5);
   return result;
@@ -1104,15 +1092,15 @@
 // 4D864C: using guessed type char byte_4D864C;
 
 //----- (0049C681) --------------------------------------------------------
-char stru10::_49C681_DrawDebugStuff(BLVFace *pFace, IndoorCameraD3D_Vec4 *a3, RenderVertexSoft *pArrayOf4)
+char stru10::MessWithPortal(BLVFace *pFace, IndoorCameraD3D_Vec4 *a3, RenderVertexSoft *pOutBounding)
 {
-  RenderVertexSoft pBounding[4]; // [sp+Ch] [bp-C0h]@1
+  RenderVertexSoft pLimits[4]; // [sp+Ch] [bp-C0h]@1
 
-  CalcPolygonBoundingBox(pFace, pBounding);
-  if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
-    pGame->pIndoorCameraD3D->debug_outline_sw(pBounding, 4, 0xFF1E1E, 0.000099999997);
-  if (_49C9E3(pFace, pBounding, 4, pArrayOf4))
-    return _49C720(pArrayOf4, a3);
+  CalcPolygonLimits(pFace, pLimits);
+  //if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
+ //   pGame->pIndoorCameraD3D->debug_outline_sw(pLimits, 4, 0xFF1E1E, 0.000099999997);
+  if (CalcFaceBounding(pFace, pLimits, 4, pOutBounding))
+    return _49C720(pOutBounding, a3);
   return false;
 }
 // 4D864C: using guessed type char byte_4D864C;
@@ -1130,144 +1118,73 @@
   a3.y = (double)pBLVRenderParams->vPartyPos.y;
   thisa = this;
   a3.z = (double)pBLVRenderParams->vPartyPos.z;
-  if ( _49C7C5(a2, a2 + 1, &a3, a4)
-    && _49C7C5(a2 + 1, a2 + 2, &a3, a4 + 1)
-    && _49C7C5(a2 + 2, a2 + 3, &a3, a4 + 2) )
-    result = _49C7C5(a2 + 3, a2, &a3, a4 + 3) != 0;
+  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;
 }
 
 //----- (0049C7C5) --------------------------------------------------------
-bool stru10::_49C7C5(RenderVertexSoft *a1, RenderVertexSoft *a2, Vec3_float_ *a3, IndoorCameraD3D_Vec4 *a4)
+bool stru10::FindFaceNormal(RenderVertexSoft *a1, RenderVertexSoft *a2, Vec3_float_ *a3, IndoorCameraD3D_Vec4 *a4)
 {
-  double v5; // st7@1
-  double v6; // st6@1
-  double v7; // st5@1
-  Vec3_float_ *result; // eax@1
-  __int16 v9; // fps@3
-  char v10; // c0@3
-  char v11; // c2@3
-  char v12; // c3@3
-  float v13; // ecx@5
-  double v14; // st7@5
-  double v15; // st6@5
   Vec3_float_ v1; // [sp+4h] [bp-48h]@1
   Vec3_float_ v2; // [sp+10h] [bp-3Ch]@1
-  float v18; // [sp+20h] [bp-2Ch]@1
-  float v19; // [sp+24h] [bp-28h]@1
-  Vec3_float_ v20; // [sp+28h] [bp-24h]@1
-  Vec3_float_ v21; // [sp+34h] [bp-18h]@1
-  Vec3_float_ a1a; // [sp+40h] [bp-Ch]@1
+
+  v1.x = a1->vWorldPosition.x - a3->x;
+  v1.y = a1->vWorldPosition.y - a3->y;
+  v1.z = a1->vWorldPosition.z - a3->z;
+  Vec3_float_::Cross(&v1, &v2, a2->vWorldPosition.x - a1->vWorldPosition.x,
+                               a2->vWorldPosition.y - a1->vWorldPosition.y,
+                               a2->vWorldPosition.z - a1->vWorldPosition.z);
 
-  a1a.x = 0.0;
-  a1a.y = 0.0;
-  a1a.z = 0.0;
-  v21.x = a3->x;
-  v21.y = a3->y;
-  v21.z = a3->z;
-  v5 = a1->vWorldPosition.x;
-  v6 = a1->vWorldPosition.y;
-  v2.z = a1->vWorldPosition.z;
-  v7 = a2->vWorldPosition.x;
-  v18 = a2->vWorldPosition.y;
-  v19 = a2->vWorldPosition.z;
-  v20.x = v5 - v21.x;
-  v20.y = v6 - v21.y;
-  v20.z = v2.z - v21.z;
-  LODWORD(v1.x) = (int)v20.x;
-  v1.y = v20.y;
-  v1.z = v20.z;
-  v20.x = v7 - v5;
-  v20.y = v18 - v6;
-  v20.z = v19 - v2.z;
-  result = Vec3_float_::Cross(&v1, &v2, v20.x, v20.y, v20.z);
-  a1a.x = result->x;
-  a1a.y = result->y;
-  a1a.z = result->z;
-  if ( a1a.x != 0.0
-    || a1a.y != 0.0
-    || (/*UNDEF(v9),*/ v10 = a1a.z < 0.0, v11 = 0, v12 = a1a.z == 0.0, BYTE1(result) = HIBYTE(v9), a1a.z != 0.0) )
+  float sqr_mag = v2.x * v2.x + v2.y * v2.y + v2.z * v2.z;
+  if (fabsf(sqr_mag) > 1e-6f)
   {
-    a1a.Normalize();
-    result = (Vec3_float_ *)a4;
-    v13 = a1a.y;
-    a4->x = a1a.x;
-    v14 = v21.z * a1a.z;
-    v15 = v21.y * a1a.y;
-    a4->y = v13;
-    a4->z = a1a.z;
-    a4->dot = v14 + v15 + v21.x * a1a.x;
-    LOBYTE(result) = 1;
+    float inv_mag = 1.0f / sqrtf(sqr_mag);
+    v2.x *= inv_mag;
+    v2.y *= inv_mag;
+    v2.z *= inv_mag;
+    //v2.Normalize();
+
+    a4->x = v2.x;
+    a4->y = v2.y;
+    a4->z = v2.z;
+    a4->dot = a3->z * v2.z + a3->y * v2.y + a3->x * v2.x;
+    return true;
   }
-  else
-  {
-    LOBYTE(result) = 0;
-  }
-  return (bool)result;
+  return false;
 }
 
 //----- (0049C8DC) --------------------------------------------------------
-bool stru10::_49C8DC(RenderVertexSoft *arg0, Vec3_float_ *a2, float *a3)
+bool stru10::FindFacePlane(RenderVertexSoft *arg0, Vec3_float_ *a2, float *a3)
 {
-  //double v4; // st7@1
-  //double v5; // st6@1
-  //double v6; // st5@1
-  Vec3_float_ *result; // eax@1
-  __int16 v8; // fps@3
-  char v9; // c0@3
-  char v10; // c2@3
-  char v11; // c3@3
-  float v12; // ecx@5
-  double v13; // st7@5
-  double v14; // st6@5
   Vec3_float_ v1; // [sp+8h] [bp-3Ch]@1
   Vec3_float_ v2; // [sp+14h] [bp-30h]@1
-  //float v17; // [sp+24h] [bp-20h]@1
-  //float v18; // [sp+28h] [bp-1Ch]@1
-  //float v19; // [sp+2Ch] [bp-18h]@1
-  //float v20; // [sp+30h] [bp-14h]@1
-  //float v21; // [sp+34h] [bp-10h]@1
-  Vec3_float_ a1; // [sp+38h] [bp-Ch]@1
 
-  //v19 = arg0->vWorldPosition.x;
-  //v20 = arg0->vWorldPosition.y;
-  //v21 = arg0->vWorldPosition.z;
-  //v4 = arg0[1].vWorldPosition.x;
-  //v5 = arg0[1].vWorldPosition.y;
-  //v2.z = arg0[1].vWorldPosition.z;
-  //v6 = arg0[2].vWorldPosition.x;
-  //v17 = arg0[2].vWorldPosition.y;
-  //v18 = arg0[2].vWorldPosition.z;
-  //a1.x = v4 - v19;
-  //a1.y = v5 - v20;
-  //a1.z = v2.z - v21;
   v1.x = arg0[1].vWorldPosition.x - arg0[0].vWorldPosition.x;
   v1.y = arg0[1].vWorldPosition.y - arg0[0].vWorldPosition.y;
   v1.z = arg0[1].vWorldPosition.z - arg0[0].vWorldPosition.z;
 
-  a1.x = arg0[2].vWorldPosition.x - arg0[1].vWorldPosition.x;
-  a1.y = arg0[2].vWorldPosition.y - arg0[1].vWorldPosition.y;
-  a1.z = arg0[2].vWorldPosition.z - arg0[1].vWorldPosition.z;
+  Vec3_float_::Cross(&v1, &v2, arg0[2].vWorldPosition.x - arg0[1].vWorldPosition.x,
+                               arg0[2].vWorldPosition.y - arg0[1].vWorldPosition.y,
+                               arg0[2].vWorldPosition.z - arg0[1].vWorldPosition.z);
 
-  result = Vec3_float_::Cross(&v1, &v2, a1.x, a1.y, a1.z);
-  a1.x = result->x;
-  a1.y = result->y;
-  a1.z = result->z;
-  if ( a1.x != 0.0
-    || a1.y != 0.0
-    || (/*UNDEF(v8),*/ v9 = a1.z < 0.0, v10 = 0, v11 = a1.z == 0.0, /*BYTE1(result) = HIBYTE(v8),*/ a1.z != 0.0) )
+  float sqr_mag = v2.x * v2.x + v2.y * v2.y + v2.z * v2.z;
+  if (fabsf(sqr_mag) > 1e-6f)
   {
-    a1.Normalize();
-    v12 = a1.y;
-    a2->x = a1.x;
-    v13 = arg0[0].vWorldPosition.z * a1.z;
-    v14 = arg0[0].vWorldPosition.y * a1.y;
-    a2->y = v12;
-    a2->z = a1.z;
-    result = (Vec3_float_ *)a3;
-    *a3 = -(v13 + v14 + arg0[0].vWorldPosition.x * a1.x);
+    //v2.Normalize();
+    float inv_mag = 1.0f / sqrtf(sqr_mag);
+    v2.x *= inv_mag;
+    v2.y *= inv_mag;
+    v2.z *= inv_mag;
+
+    a2->x = v2.x;
+    a2->y = v2.y;
+    a2->z = v2.z;
+    *a3 = -(arg0[0].vWorldPosition.z * v2.z + arg0[0].vWorldPosition.y * v2.y + arg0[0].vWorldPosition.x * v2.x);
     return true;
   }
   return false;
--- a/stru10.h	Mon Mar 25 09:17:42 2013 +0200
+++ b/stru10.h	Mon Mar 25 11:58:38 2013 +0200
@@ -8,16 +8,16 @@
   stru10();
   virtual ~stru10();
   char _49C5DA(struct BLVFace *a2, struct RenderVertexSoft *a3, int *a4, struct IndoorCameraD3D_Vec4 *a5, struct RenderVertexSoft *a6);
-  char _49C681_DrawDebugStuff(struct BLVFace *pFace, struct IndoorCameraD3D_Vec4 *a3, struct RenderVertexSoft *pArrayOf4);
+  char MessWithPortal(struct BLVFace *pFace, struct IndoorCameraD3D_Vec4 *a3, struct RenderVertexSoft *pOutBounding);
   char _49C720(struct RenderVertexSoft *a2, struct IndoorCameraD3D_Vec4 *a4);
-  bool _49C7C5(struct RenderVertexSoft *a1, struct RenderVertexSoft *a2, struct Vec3_float_ *a3, struct IndoorCameraD3D_Vec4 *a4);
-  bool _49C8DC(struct RenderVertexSoft *arg0, struct Vec3_float_ *a2, float *a3);
-  bool _49C9E3(struct BLVFace *a3, struct RenderVertexSoft *arg4, unsigned int uNumVertices, struct RenderVertexSoft *arg0);
-  void CalcPolygonBoundingBox(struct BLVFace *pFace, struct RenderVertexSoft pOutVertices[4]);
+  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 (__thiscall ***vdestructor_ptr)(stru10 *, bool);
-  int field_4;
+  int bDoNotDrawPortalFrustum;
 };
 #pragma pack(pop)
--- a/stru9.cpp	Mon Mar 25 09:17:42 2013 +0200
+++ b/stru9.cpp	Mon Mar 25 11:58:38 2013 +0200
@@ -6,7 +6,7 @@
 
 
 //----- (00498377) --------------------------------------------------------
-bool stru9::_498377(struct RenderVertexSoft *a1, unsigned int uNumVertices, struct IndoorCameraD3D_Vec4 *a3, struct RenderVertexSoft *pVertices, unsigned int *pOutNumVertices)
+bool stru9::_498377(struct RenderVertexSoft *pPortalBounding, unsigned int uNumVertices, struct IndoorCameraD3D_Vec4 *a3, struct RenderVertexSoft *pVertices, unsigned int *pOutNumVertices)
 {
   int result; // eax@7
   //unsigned int *v7; // ebx@7
@@ -75,10 +75,10 @@
   {
     //v17 = result + 1;
     result = v17;
-    v9 = &a1[(result + 1) % (signed int)uNumVertices];
-    if ( a1->vWorldPosition.x != v9->vWorldPosition.x
-      || a1->vWorldPosition.y != v9->vWorldPosition.y
-      || a1->vWorldPosition.z != v9->vWorldPosition.z )
+    v9 = &pPortalBounding[(result + 1) % (signed int)uNumVertices];
+    if ( pPortalBounding->vWorldPosition.x != v9->vWorldPosition.x
+      || pPortalBounding->vWorldPosition.y != v9->vWorldPosition.y
+      || pPortalBounding->vWorldPosition.z != v9->vWorldPosition.z )
     {
       //v10 = a3->z;
       //v11 = a3->y;
@@ -100,8 +100,8 @@
         //v12 = &pVertices[result];
         if ( result )
         {
-          if ( _4989E1(&pVertices[i], &pVertices[i], a1, &static_AE3FA4) 
-            && _498774(&pVertices[i], &pVertices[i], a1, &static_AE3FA4, &static_AE3FB4) )
+          if ( _4989E1(&pVertices[i], &pVertices[i], pPortalBounding, &static_AE3FA4) 
+            && _498774(&pVertices[i], &pVertices[i], pPortalBounding, &static_AE3FA4, &static_AE3FB4) )
             AddVertex(&static_AE33A0, &static_AE3FB4);
         }
         else
@@ -109,7 +109,7 @@
           v19 = &pVertices[i];
         }
         //v20 = v12;
-        if ( AreVectorsCollinear(&pVertices[i], a1, &static_AE3FA4) )//
+        if ( AreVectorsCollinear(&pVertices[i], pPortalBounding, &static_AE3FA4) )//
           AddVertex(&static_AE33A0, &pVertices[i]);
         //pOutNumVertices = pOutNumVertices;
         //a3a++;
@@ -120,8 +120,8 @@
           *pOutNumVertices = 0;
           return true;
         }
-      if ( _4989E1(&pVertices[result], v19, a1, &static_AE3FA4)
-        && _498774(&pVertices[result], v19, a1, &static_AE3FA4, &static_AE3FB4) )
+      if ( _4989E1(&pVertices[result], v19, pPortalBounding, &static_AE3FA4)
+        && _498774(&pVertices[result], v19, pPortalBounding, &static_AE3FA4, &static_AE3FB4) )
         AddVertex(&static_AE33A0, &static_AE3FB4);
 
       for (uint i = 0; i < static_AE33A0.uNumVertices; ++i)
@@ -162,7 +162,7 @@
       *pOutNumVertices = static_AE33A0.uNumVertices;
     }
     //result = v17;
-    ++a1;
+    ++pPortalBounding;
     a3++;
     //v18 = (char *)&a3->y;
   }
--- a/stru9.h	Mon Mar 25 09:17:42 2013 +0200
+++ b/stru9.h	Mon Mar 25 11:58:38 2013 +0200
@@ -51,7 +51,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 *a1, unsigned int uNumVertices, struct IndoorCameraD3D_Vec4 *a3, struct RenderVertexSoft *pVertices, 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);
   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);