changeset 1638:ccde94f02b75

class IndoorCamera split into BLVRenderParams and ODMRenderParams
author Nomad
date Tue, 17 Sep 2013 15:40:09 +0200
parents 2c71fa8913d2
children b60ddd777d50
files Actor.cpp GUIWindow.cpp Game.cpp Indoor.cpp Indoor.h IndoorCamera.cpp IndoorCamera.h IndoorCameraD3D.cpp Outdoor.cpp Outdoor_stuff.h ParticleEngine.cpp Render.cpp UI/UICharacter.cpp UI/UIHouses.cpp UI/UISaveLoad.cpp Vis.cpp _deleted.cpp mm7_2.cpp mm7_3.cpp mm7_4.cpp
diffstat 20 files changed, 503 insertions(+), 364 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/Actor.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -17,7 +17,6 @@
 #include "ObjectList.h"
 #include "Overlays.h"
 #include "Events.h"
-#include "IndoorCamera.h"
 #include "FactionTable.h"
 #include "TurnEngine.h"
 #include "MapInfo.h"
@@ -26,6 +25,7 @@
 #include "LOD.h"
 #include "Party.h"
 #include "GUIWindow.h"
+#include "Outdoor_stuff.h"
 
 #include "MM7.h"
 #include "SpriteObject.h"
@@ -2927,7 +2927,12 @@
 
   actor->uCurrentActionLength = 8 * pSpriteFrameTable->pSpriteSFrames[actor->pSpriteIDs[ANIM_Bored]].uAnimLength;
 
-  v7 = stru_5C6E00->Atan2(actor->vPosition.x - pIndoorCamera->pos.x, actor->vPosition.y - pIndoorCamera->pos.y);
+  if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+    v7 = stru_5C6E00->Atan2(actor->vPosition.x - pODMRenderParams->vPartyPos.x, actor->vPosition.y - pODMRenderParams->vPartyPos.y);
+  else if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+    v7 = stru_5C6E00->Atan2(actor->vPosition.x - pBLVRenderParams->vPartyPos.x, actor->vPosition.y - pBLVRenderParams->vPartyPos.y);
+  else Error("(%u)", uCurrentlyLoadedLevelType);
+
   v9 = stru_5C6E00->uIntegerPi + actor->uYawAngle + ((signed int)stru_5C6E00->uIntegerPi >> 3) - v7;
 
   if ( BYTE1(v9) & 7 )      // turned away - just stand
--- a/GUIWindow.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/GUIWindow.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -7,7 +7,6 @@
 #include "Party.h"
 #include "LOD.h"
 #include "Keyboard.h"
-#include "IndoorCamera.h"
 #include "Math.h"
 #include "VideoPlayer.h"
 #include "MapInfo.h"
@@ -26,6 +25,8 @@
 #include "Autonotes.h"
 #include "Awards.h"
 #include "Chest.h"
+#include "Outdoor.h"
+#include "Outdoor_stuff.h"
 
 
 #include "mm7_data.h"
@@ -296,9 +297,16 @@
 		dword_5C35D4 = 0;
 		if ( bFlipOnExit )
 		{
-			pIndoorCamera->sRotationY = (stru_5C6E00->uIntegerDoublePi - 1) & (stru_5C6E00->uIntegerPi
+			/*pIndoorCamera->sRotationY = (stru_5C6E00->uIntegerDoublePi - 1) & (stru_5C6E00->uIntegerPi
 																			+ pIndoorCamera->sRotationY);
-			pParty->sRotationY = pIndoorCamera->sRotationY;
+			pParty->sRotationY = pIndoorCamera->sRotationY;*/
+
+          pParty->sRotationY = (stru_5C6E00->uIntegerDoublePi - 1) & (stru_5C6E00->uIntegerPi + pParty->sRotationY);
+          if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+            pBLVRenderParams->sPartyRotY = pParty->sRotationY;
+          else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+            pODMRenderParams->rotation_y = pParty->sRotationY;
+          else Error("(%u)", uCurrentlyLoadedLevelType);
 		}
 		pParty->uFlags |= 2u;
 		break;
--- a/Game.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/Game.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -17,7 +17,6 @@
 
 #include "Game.h"
 #include "Party.h"
-#include "IndoorCamera.h"
 #include "Viewport.h"
 #include "Time.h"
 #include "Outdoor.h"
@@ -74,14 +73,56 @@
   uFlags2 &= ~0x02;
   if ( pParty->_497FC5_check_party_perception_against_level() )
     uFlags2 |= 2u;
-  pIndoorCamera->sRotationX = pParty->sRotationX;
-  pIndoorCamera->sRotationY = pParty->sRotationY;
-  //pIndoorCamera->pos.x = pParty->vPosition.x - ((__int64)pParty->y_rotation_granularity * stru_5C6E00->SinCos(pIndoorCamera->sRotationY)) / 2048.0;//12552
-  //pIndoorCamera->pos.y = pParty->vPosition.y - ((__int64)pParty->y_rotation_granularity * stru_5C6E00->SinCos(pIndoorCamera->sRotationY)) / 2048.0;//800
-  pIndoorCamera->pos.x = pParty->vPosition.x - pParty->y_rotation_granularity * cosf(2 * 3.141592653589 * pIndoorCamera->sRotationY / 2048.0);
-  pIndoorCamera->pos.y = pParty->vPosition.y - pParty->y_rotation_granularity * sinf(2 * 3.141592653589 * pIndoorCamera->sRotationY / 2048.0);
-  pIndoorCamera->pos.z = pParty->vPosition.z + pParty->sEyelevel;//193, but real 353
-  pIndoorCamera->Initialize2();
+
+  if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+  {
+    pBLVRenderParams->sPartyRotX = pParty->sRotationX;
+    pBLVRenderParams->sPartyRotY = pParty->sRotationY;
+    pBLVRenderParams->vPartyPos.x = pParty->vPosition.x - pParty->y_rotation_granularity * cosf(2 * 3.141592653589 * pBLVRenderParams->sPartyRotY / 2048.0);
+    pBLVRenderParams->vPartyPos.y = pParty->vPosition.y - pParty->y_rotation_granularity * sinf(2 * 3.141592653589 * pBLVRenderParams->sPartyRotY / 2048.0);
+    pBLVRenderParams->vPartyPos.z = pParty->vPosition.z + pParty->sEyelevel;//193, but real 353
+  }
+  else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+  {
+    pODMRenderParams->rotation_x = pParty->sRotationX;
+    pODMRenderParams->rotation_y = pParty->sRotationY;
+    pODMRenderParams->vPartyPos.x = pParty->vPosition.x - pParty->y_rotation_granularity * cosf(2 * 3.141592653589 * pODMRenderParams->rotation_y / 2048.0);
+    pODMRenderParams->vPartyPos.y = pParty->vPosition.y - pParty->y_rotation_granularity * sinf(2 * 3.141592653589 * pODMRenderParams->rotation_y / 2048.0);
+    pODMRenderParams->vPartyPos.z = pParty->vPosition.z + pParty->sEyelevel;//193, but real 353
+  }
+
+  //pIndoorCamera->Initialize2();
+  {
+    float fRotationYSine = sin((3.141592653589793 + 3.141592653589793) * (double)pParty->sRotationY * 0.00048828125);
+    float fRotationYCosine = cos((3.141592653589793 + 3.141592653589793) * (double)pParty->sRotationY * 0.00048828125);
+    float fRotationXSine;
+    float fRotationXCosine;
+    if ( byte_4D864C && pGame->uFlags & 0x80 || uCurrentlyLoadedLevelType == LEVEL_Indoor)
+    {
+      fRotationXSine = sin((3.141592653589793 + 3.141592653589793) * (double)-pParty->sRotationX * 0.00048828125);
+      fRotationXCosine = cos((3.141592653589793 + 3.141592653589793) * (double)-pParty->sRotationX* 0.00048828125);
+    }
+    else
+    {
+      fRotationXSine = sin((3.141592653589793 + 3.141592653589793) * (double)pParty->sRotationX * 0.00048828125);
+      fRotationXCosine = cos((3.141592653589793 + 3.141592653589793) * (double)pParty->sRotationX * 0.00048828125);
+    }
+
+    if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+    {
+      pBLVRenderParams->fRotationYSine = fRotationYSine;
+      pBLVRenderParams->fRotationYCosine = fRotationYCosine;
+      pBLVRenderParams->fRotationXSine = fRotationXSine;
+      pBLVRenderParams->fRotationXCosine = fRotationXCosine;
+    }
+    else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+    {
+      pODMRenderParams->fRotationYSine = fRotationYSine;
+      pODMRenderParams->fRotationYCosine = fRotationYCosine;
+      pODMRenderParams->fRotationXSine = fRotationXSine;
+      pODMRenderParams->fRotationXCosine = fRotationXCosine;
+    }
+  }
   pIndoorCameraD3D->CreateWorldMatrixAndSomeStuff();
   pIndoorCameraD3D->_4374E8_ProllyBuildFrustrum();
 
--- a/Indoor.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/Indoor.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -29,7 +29,6 @@
 #include "TurnEngine.h"
 #include "PaletteManager.h"
 #include "MapInfo.h"
-#include "IndoorCamera.h"
 #include "Lights.h"
 
 #include "mm7_data.h"
@@ -333,7 +332,7 @@
     IndoorLocation::ExecDraw(pRenderer->pRenderD3D != 0);
   pRenderer->DrawBillboardList_BLV();
 
-  if ( !pRenderer->pRenderD3D )
+/*  if ( !pRenderer->pRenderD3D )
   {
     if (pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_D3D_OUTLINES)
       pBspRenderer->DrawFaceOutlines();
@@ -363,7 +362,7 @@
 		  }
 	  }
     }
-  }
+  }*/
 }
 
 
@@ -380,13 +379,12 @@
 
   _this.uFlags = 0;
   if (viewparams->draw_sw_outlines)
-    _this.uFlags |= INDOOR_CAMERA_DRAW_SW_OUTLINES;
+    _this.uFlags |= BLV_RENDER_DRAW_SW_OUTLINES;
   if (viewparams->draw_d3d_outlines)
-    _this.uFlags |= INDOOR_CAMERA_DRAW_D3D_OUTLINES;
-
-  _this.uFlags |= INDOOR_CAMERA_DRAW_D3D_OUTLINES;
-  _this.uFlags |= INDOOR_CAMERA_DRAW_SW_OUTLINES;
-  //INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES
+    _this.uFlags |= BLV_RENDER_DRAW_D3D_OUTLINES;
+  
+  _this.uFlags |= BLV_RENDER_DRAW_SW_OUTLINES;
+  _this.uFlags |= BLV_RENDER_DRAW_D3D_OUTLINES;
 
   _this.field_0_timer = pEventTimer->uTotalGameTimeElapsed;
   _this.field_1C_mb_fov = 65;
@@ -803,7 +801,7 @@
       nodes[num_nodes].viewing_portal_id = uFaceID;
       AddBspNodeToRenderList(++num_nodes - 1);
     }
-    if (pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_SW_OUTLINES)
+    if (pBLVRenderParams->uFlags & BLV_RENDER_DRAW_SW_OUTLINES)
       pGame->pIndoorCameraD3D->PrepareAndDrawDebugOutline(pFace, 0x1E1EFF);
     //pGame->pIndoorCameraD3D->DebugDrawPortal(pFace);
   }
--- a/Indoor.h	Tue Sep 17 14:10:41 2013 +0200
+++ b/Indoor.h	Tue Sep 17 15:40:09 2013 +0200
@@ -468,6 +468,8 @@
 
 
 
+#define BLV_RENDER_DRAW_SW_OUTLINES  1
+#define BLV_RENDER_DRAW_D3D_OUTLINES 2
 
 /*  263 */
 #pragma pack(push, 1)
@@ -548,6 +550,11 @@
   int field_8C;
   int field_90;
   int field_94;
+  
+  float fRotationYSine;       // moved from 157 struct IndoorCamera::2C
+  float fRotationYCosine;     // moved from 157 struct IndoorCamera::30
+  float fRotationXSine;       // moved from 157 struct IndoorCamera::34
+  float fRotationXCosine;     // moved from 157 struct IndoorCamera::38
 };
 #pragma pack(pop)
 extern BLVRenderParams *pBLVRenderParams;
--- a/IndoorCamera.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-#include "IndoorCamera.h"
-#include "Render.h"
-#include "Game.h"
-#include "Indoor.h"
-#include "Math.h"
-
-#include "mm7_data.h"
-
-
-
-
-/*
-IndoorCamera *pIndoorCamera; // idb
-
-
-
-
-
-//----- (00481CCE) --------------------------------------------------------
-float IndoorCamera::ViewTransform(RenderVertexSoft *a1)
-{
-  float result; // eax@1
-  double vCamToVertexZ; // st7@1
-  double v3; // st6@1
-  double v4; // st5@1
-  double v5; // st4@1
-  float v6; // ST04_4@3
-  float v7; // [sp+0h] [bp-14h]@1
-  float v8; // [sp+8h] [bp-Ch]@1
-  float vCamToVertexX; // [sp+Ch] [bp-8h]@1
-  float vCamToVertexY; // [sp+10h] [bp-4h]@1
-
-  v8 = fRotationXCosine;
-  result = fRotationXSine;
-  v7 = fRotationXSine;
-  vCamToVertexX = a1->vWorldPosition.x - (double)pos.x;
-  vCamToVertexY = a1->vWorldPosition.y - (double)pos.y;
-  vCamToVertexZ = a1->vWorldPosition.z - (double)pos.z;
-  v3 = fRotationYCosine;
-  v4 = fRotationYSine;
-  v5 = vCamToVertexY * fRotationYSine + fRotationYCosine * vCamToVertexX;
-  if ( sRotationX )
-  {
-    v6 = vCamToVertexY * fRotationYSine + fRotationYCosine * vCamToVertexX;
-    a1->vWorldViewPosition.x = v5 * fRotationXCosine + fRotationXSine * vCamToVertexZ;
-    a1->vWorldViewPosition.y = v3 * vCamToVertexY - v4 * vCamToVertexX;
-    a1->vWorldViewPosition.z = v8 * vCamToVertexZ - v6 * v7;
-  }
-  else
-  {
-    a1->vWorldViewPosition.x = vCamToVertexY * fRotationYSine + fRotationYCosine * vCamToVertexX;
-    a1->vWorldViewPosition.y = v3 * vCamToVertexY - v4 * vCamToVertexX;
-    a1->vWorldViewPosition.z = vCamToVertexZ;
-  }
-  return result;
-}
-
-
-
-//----- (0042394D) --------------------------------------------------------
-void IndoorCamera::Initialize(int degFov, unsigned int uViewportWidth, unsigned int uViewportHeight)
-{
-  IndoorCamera *v4; // esi@1
-  double v5; // st7@1
-
-  v4 = this;
-  v5 = (double)(signed int)(signed __int64)((double)(signed int)uViewportWidth
-                                          * 0.5
-                                          / tan((double)(degFov >> 1) * 0.01745329)
-                                          + 0.5);
-  v4->flt_1C_fov = v5;
-  v4->flt_20_inv_1C = 65536.0 / v5;
-}
-
-//----- (004239A7) --------------------------------------------------------
-void IndoorCamera::Initialize2()
-{
-  //IndoorCamera *v1; // esi@1
-  double v2; // st7@4
-  //double v3; // st7@6
-  //int v4; // eax@6
-  //int v5; // eax@6
-  //int v6; // ST04_4@6
-  //int v7; // eax@6
-  //int v8; // ST04_4@6
-
-  //v1 = this;
-  fRotationYSine = sin((3.141592653589793 + 3.141592653589793) * (double)sRotationY * 0.00048828125);
-  fRotationYCosine = cos((3.141592653589793 + 3.141592653589793) * (double)sRotationY * 0.00048828125);
-  if ( byte_4D864C && pGame->uFlags & 0x80 || uCurrentlyLoadedLevelType == LEVEL_Indoor)
-  {
-    fRotationXSine = sin((3.141592653589793 + 3.141592653589793) * (double)-sRotationX * 0.00048828125);
-    v2 = (3.141592653589793 + 3.141592653589793) * (double)-sRotationX;
-  }
-  else
-  {
-    fRotationXSine = sin((3.141592653589793 + 3.141592653589793) * (double)sRotationX * 0.00048828125);
-    v2 = (3.141592653589793 + 3.141592653589793) * (double)sRotationX;
-  }
-  //v3 = cos(v2 * 0.00048828125);
-  //v4 = sRotationY;
-  fRotationXCosine = cos(v2 * 0.00048828125);
-  //v5 = stru_5C6E00->SinCos(sRotationY - stru_5C6E00->uIntegerHalfPi);
-  //v6 = sRotationY;
-  _int_sine = stru_5C6E00->Sin(sRotationY);
-  _int_cosine = stru_5C6E00->Cos(sRotationY);
-  //v7 = stru_5C6E00->SinCos(sRotationX - stru_5C6E00->uIntegerHalfPi);
-  //v8 = sRotationX;
-  _int_sine_2 = stru_5C6E00->Sin(sRotationX);
-  _int_cosine_2 = stru_5C6E00->Cos(sRotationX);
-}
-// 4D864C: using guessed type char byte_4D864C;
-*/
\ No newline at end of file
--- a/IndoorCamera.h	Tue Sep 17 14:10:41 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-#pragma once
-#include "VectorTypes.h"
-
-
-#define INDOOR_CAMERA_DRAW_SW_OUTLINES 1
-#define INDOOR_CAMERA_DRAW_D3D_OUTLINES 2
-#define INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES 4
-//  157
-/*#pragma pack(push, 1)
-struct IndoorCamera
-{
-  //----- (0042391F) --------------------------------------------------------
-  IndoorCamera()
-  {
-    sRotationX = 0;
-    sRotationY = 0;
-    flt_1C_fov = 2000.0f;
-    flt_20_inv_1C = 32.768002f;
-
-    flags = 0;
-  }
-  void Initialize(int degFov, unsigned int uViewportWidth, unsigned int uViewportHeight);
-  void Initialize2();
-  float ViewTransform(struct RenderVertexSoft *a1);
-
-
-  Vec3_int_ pos;
-  unsigned int uMapGridCellX;
-  unsigned int uMapGridCellZ;
-  int sRotationX;
-  int sRotationY;
-  float flt_1C_fov;
-  float flt_20_inv_1C;
-  int field_24;
-  int field_28;
-  float fRotationYSine;
-  float fRotationYCosine;
-  float fRotationXSine;
-  float fRotationXCosine;
-  int _int_sine;
-  int _int_cosine;
-  int _int_sine_2;
-  int _int_cosine_2;
-  int flags;  // & INDOOR_CAMERA_DRAW_D3D_OUTLINES:  render terrain outlines in d3d
-};
-#pragma pack(pop)
-
-
-
-extern IndoorCamera *pIndoorCamera; // idb*/
\ No newline at end of file
--- a/IndoorCameraD3D.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/IndoorCameraD3D.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -3,7 +3,6 @@
 #include "Game.h"
 #include "Indoor.h"
 #include "Viewport.h"
-#include "IndoorCamera.h"
 #include "Outdoor_stuff.h"
 #include "Render.h"
 #include "LOD.h"
@@ -204,20 +203,61 @@
   return is_face_faced_to_camera(pFace, &v);
 }
 
+
+
+//----- (00481CCE) --------------------------------------------------------
+float ViewTransform_ODM(RenderVertexSoft *a1)
+{
+  float result; // eax@1
+  double vCamToVertexZ; // st7@1
+  double v3; // st6@1
+  double v4; // st5@1
+  double v5; // st4@1
+  float v6; // ST04_4@3
+  float v7; // [sp+0h] [bp-14h]@1
+  float v8; // [sp+8h] [bp-Ch]@1
+  float vCamToVertexX; // [sp+Ch] [bp-8h]@1
+  float vCamToVertexY; // [sp+10h] [bp-4h]@1
+
+  v8 = pODMRenderParams->fRotationXCosine;
+  result = pODMRenderParams->fRotationXSine;
+  v7 = pODMRenderParams->fRotationXSine;
+  vCamToVertexX = a1->vWorldPosition.x - (double)pODMRenderParams->vPartyPos.x;
+  vCamToVertexY = a1->vWorldPosition.y - (double)pODMRenderParams->vPartyPos.y;
+  vCamToVertexZ = a1->vWorldPosition.z - (double)pODMRenderParams->vPartyPos.z;
+  v3 = pODMRenderParams->fRotationYCosine;
+  v4 = pODMRenderParams->fRotationYSine;
+  v5 = vCamToVertexY * pODMRenderParams->fRotationYSine + pODMRenderParams->fRotationYCosine * vCamToVertexX;
+  if (pODMRenderParams->rotation_x)
+  {
+    v6 = vCamToVertexY * pODMRenderParams->fRotationYSine + pODMRenderParams->fRotationYCosine * vCamToVertexX;
+    a1->vWorldViewPosition.x = v5 * pODMRenderParams->fRotationXCosine + pODMRenderParams->fRotationXSine * vCamToVertexZ;
+    a1->vWorldViewPosition.y = v3 * vCamToVertexY - v4 * vCamToVertexX;
+    a1->vWorldViewPosition.z = v8 * vCamToVertexZ - v6 * v7;
+  }
+  else
+  {
+    a1->vWorldViewPosition.x = vCamToVertexY * pODMRenderParams->fRotationYSine + pODMRenderParams->fRotationYCosine * vCamToVertexX;
+    a1->vWorldViewPosition.y = v3 * vCamToVertexY - v4 * vCamToVertexX;
+    a1->vWorldViewPosition.z = vCamToVertexZ;
+  }
+  return result;
+}
+
 //----- (00436523) --------------------------------------------------------
 void IndoorCameraD3D::ViewTransform(RenderVertexSoft *a1a, unsigned int uNumVertices)
 {
   if (byte_4D864C && pGame->uFlags & 0x80 ||
       uCurrentlyLoadedLevelType == LEVEL_Indoor)
   {
-    float sin_x = pIndoorCamera->fRotationXSine,
-          cos_x = pIndoorCamera->fRotationXCosine;
-    float sin_y = pIndoorCamera->fRotationYSine,
-          cos_y = pIndoorCamera->fRotationYCosine;
+    float sin_x = pBLVRenderParams->fRotationXSine,
+          cos_x = pBLVRenderParams->fRotationXCosine;
+    float sin_y = pBLVRenderParams->fRotationYSine,
+          cos_y = pBLVRenderParams->fRotationYCosine;
 
     //v4 = uNumVertices;
     //v7 = pIndoorCamera->fRotationXSine;
-    if ( pIndoorCamera->sRotationX )
+    if (pBLVRenderParams->sPartyRotX)
     {
 
         //_EAX = a1a;
@@ -264,9 +304,9 @@
                                          // 4[pIndoorCamera->fRotationYSine]
                                          // 5[pIndoorCamera->fRotationYCosine]
             }*/
-            st0 = sin_y * (a1a[i].vWorldPosition.x - pIndoorCamera->pos.x) - cos_y * (a1a[i].vWorldPosition.y - pIndoorCamera->pos.y);
-            st1 = cos_y * (a1a[i].vWorldPosition.x - pIndoorCamera->pos.x) + sin_y * (a1a[i].vWorldPosition.y - pIndoorCamera->pos.y);
-            st2 = (a1a[i].vWorldPosition.z - pIndoorCamera->pos.z);
+            st0 = sin_y * (a1a[i].vWorldPosition.x - pBLVRenderParams->vPartyPos.x) - cos_y * (a1a[i].vWorldPosition.y - pBLVRenderParams->vPartyPos.y);
+            st1 = cos_y * (a1a[i].vWorldPosition.x - pBLVRenderParams->vPartyPos.x) + sin_y * (a1a[i].vWorldPosition.y - pBLVRenderParams->vPartyPos.y);
+            st2 = (a1a[i].vWorldPosition.z - pBLVRenderParams->vPartyPos.z);
           }
           else
           {
@@ -332,9 +372,9 @@
                                          // 4[pIndoorCamera->fRotationYSine]
                                          // 5[pIndoorCamera->fRotationYCosine]
             }*/
-            st0 = cos_y * (a1a[i].vWorldPosition.y - pIndoorCamera->pos.y) + sin_y * (a1a[i].vWorldPosition.x - pIndoorCamera->pos.x);
-            st1 = cos_y * (a1a[i].vWorldPosition.x - pIndoorCamera->pos.x) - sin_y * (a1a[i].vWorldPosition.y - pIndoorCamera->pos.y);
-            st2 = (a1a[i].vWorldPosition.z - pIndoorCamera->pos.z);
+            st0 = cos_y * (a1a[i].vWorldPosition.y - pBLVRenderParams->vPartyPos.y) + sin_y * (a1a[i].vWorldPosition.x - pBLVRenderParams->vPartyPos.x);
+            st1 = cos_y * (a1a[i].vWorldPosition.x - pBLVRenderParams->vPartyPos.x) - sin_y * (a1a[i].vWorldPosition.y - pBLVRenderParams->vPartyPos.y);
+            st2 = (a1a[i].vWorldPosition.z - pBLVRenderParams->vPartyPos.z);
           }
 
           a1a[i].vWorldViewPosition.x = st1*cos_x - st2*sin_x;
@@ -398,9 +438,9 @@
               fstp    dword ptr [eax+10h]
               fstp    dword ptr [eax+14h]
             }*/
-            a1a[i].vWorldViewPosition.x = cos_y * (a1a[i].vWorldPosition.x - pIndoorCamera->pos.x) + sin_y * (a1a[i].vWorldPosition.y - pIndoorCamera->pos.y);
-            a1a[i].vWorldViewPosition.y = sin_y * (a1a[i].vWorldPosition.x - pIndoorCamera->pos.x) - cos_y * (a1a[i].vWorldPosition.y - pIndoorCamera->pos.y);
-            a1a[i].vWorldViewPosition.z = (a1a[i].vWorldPosition.z - pIndoorCamera->pos.z);
+            a1a[i].vWorldViewPosition.x = cos_y * (a1a[i].vWorldPosition.x - pBLVRenderParams->vPartyPos.x) + sin_y * (a1a[i].vWorldPosition.y - pBLVRenderParams->vPartyPos.y);
+            a1a[i].vWorldViewPosition.y = sin_y * (a1a[i].vWorldPosition.x - pBLVRenderParams->vPartyPos.x) - cos_y * (a1a[i].vWorldPosition.y - pBLVRenderParams->vPartyPos.y);
+            a1a[i].vWorldViewPosition.z = (a1a[i].vWorldPosition.z - pBLVRenderParams->vPartyPos.z);
           }
           else
           {
@@ -427,9 +467,11 @@
     }
   }
   else for (uint i = 0; i < uNumVertices; ++i)
-    pIndoorCamera->ViewTransform(a1a + i);
+    //pIndoorCamera->ViewTransform_ODM(a1a + i);
+    ViewTransform_ODM(a1a + i);
 }
 
+
 //----- (00436932) --------------------------------------------------------
 bool IndoorCameraD3D::GetFacetOrientation(char polyType, Vec3_float_ *a2, Vec3_float_ *a3, Vec3_float_ *a4)
 {
@@ -498,10 +540,24 @@
   if (pFace->Portal())
     return false;
 
+  float pos_x, pos_y, pos_z;
+  if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+  {
+    pos_x = pBLVRenderParams->vPartyPos.x;
+    pos_y = pBLVRenderParams->vPartyPos.y;
+    pos_z = pBLVRenderParams->vPartyPos.z;
+  }
+  else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+  {
+    pos_x = pODMRenderParams->vPartyPos.x;
+    pos_y = pODMRenderParams->vPartyPos.y;
+    pos_z = pODMRenderParams->vPartyPos.z;
+  }
+
   //really strange cull; dot(to_cam, normal) < 0 means we see the BACK face, not font %_%
-  if ( (a2->vWorldPosition.z - (double)pIndoorCamera->pos.z) * (double)pFace->pFacePlane_old.vNormal.z
-     + (a2->vWorldPosition.y - (double)pIndoorCamera->pos.y) * (double)pFace->pFacePlane_old.vNormal.y
-     + (a2->vWorldPosition.x - (double)pIndoorCamera->pos.x) * (double)pFace->pFacePlane_old.vNormal.x < 0.0)
+  if ( (a2->vWorldPosition.z - (double)pos_z) * (double)pFace->pFacePlane_old.vNormal.z
+     + (a2->vWorldPosition.y - (double)pos_y) * (double)pFace->pFacePlane_old.vNormal.y
+     + (a2->vWorldPosition.x - (double)pos_x) * (double)pFace->pFacePlane_old.vNormal.x < 0.0)
     return false;
 
   return true;
@@ -855,15 +911,15 @@
   m5._21 = -sinf(0);        m5._22 = cosf(0);        m5._23 = 0;
   m5._31 = 0;               m5._32 = 0;              m5._33 = 1;
 
-  float cos_x1 = pIndoorCamera->fRotationXCosine,
-        sin_x1 = pIndoorCamera->fRotationXSine;
+  float cos_x1 = uCurrentlyLoadedLevelType == LEVEL_Indoor ? pBLVRenderParams->fRotationXCosine : pODMRenderParams->fRotationXCosine,
+        sin_x1 = uCurrentlyLoadedLevelType == LEVEL_Indoor ? pBLVRenderParams->fRotationXSine   : pODMRenderParams->fRotationXSine;
  //RotationX(x)
   m4._11 = 1;               m4._12 = 0;              m4._13 = 0;
   m4._21 = 0;               m4._22 = cos_x1;         m4._23 = sin_x1;
   m4._31 = 0;               m4._32 = -sin_x1;        m4._33 = cos_x1;
   
-  float cos_y1 = pIndoorCamera->fRotationYCosine,
-        sin_y1 = pIndoorCamera->fRotationYSine;
+  float cos_y1 = uCurrentlyLoadedLevelType == LEVEL_Indoor ? pBLVRenderParams->fRotationYCosine : pODMRenderParams->fRotationYCosine,
+        sin_y1 = uCurrentlyLoadedLevelType == LEVEL_Indoor ? pBLVRenderParams->fRotationYSine   : pODMRenderParams->fRotationYSine;
  //RotationY(some_angle)
   m3._11 = cos_y1;          m3._12 = 0;              m3._13 = -sin_y1;
   m3._21 = 0;               m3._22 = 1;              m3._23 = 0;
@@ -904,9 +960,9 @@
   double v4; // st7@1
   IndoorCameraD3D_Vec3 v8; // [sp+8h] [bp-1Ch]@1
 
-  v8.x = (double)pIndoorCamera->pos.x;
-  v8.y = (double)pIndoorCamera->pos.y;
-  v8.z = (double)pIndoorCamera->pos.z;
+  v8.x = (double)(uCurrentlyLoadedLevelType == LEVEL_Indoor ? pBLVRenderParams->vPartyPos.x : pODMRenderParams->vPartyPos.x);
+  v8.y = (double)(uCurrentlyLoadedLevelType == LEVEL_Indoor ? pBLVRenderParams->vPartyPos.y : pODMRenderParams->vPartyPos.y);
+  v8.z = (double)(uCurrentlyLoadedLevelType == LEVEL_Indoor ? pBLVRenderParams->vPartyPos.z : pODMRenderParams->vPartyPos.z);
   Vec3Transform(a1, a2);
 
   v4 = v8.x * a2->x + v8.y * a2->y + v8.z * a2->z;
--- a/Outdoor.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/Outdoor.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -14,7 +14,6 @@
 #include "PaletteManager.h"
 #include "GUIProgressBar.h"
 #include "AudioPlayer.h"
-#include "IndoorCamera.h"
 #include "DecorationList.h"
 #include "Math.h"
 #include "ObjectList.h"
@@ -88,25 +87,25 @@
   int v4; // ST04_4@19
   int v5; // eax@19
 
-  pIndoorCamera->flags = 0;
+  pODMRenderParams->flags = 0;
   if (viewparams->draw_d3d_outlines)
-    pIndoorCamera->flags |= INDOOR_CAMERA_DRAW_D3D_OUTLINES;
+    pODMRenderParams->flags |= ODM_RENDER_DRAW_D3D_OUTLINES;
   //INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES
 
-  pIndoorCamera->sRotationX = pParty->sRotationX;
-  pIndoorCamera->sRotationY = pParty->sRotationY;
-  pIndoorCamera->pos.x = pParty->vPosition.x - fixpoint_sub0(stru_5C6E00->Cos(pParty->sRotationY), pParty->y_rotation_granularity);
-  pIndoorCamera->pos.y = pParty->vPosition.y - fixpoint_sub0(stru_5C6E00->Sin(pParty->sRotationY), pParty->y_rotation_granularity);
-  pIndoorCamera->pos.z = pParty->vPosition.z + pParty->sEyelevel;
+  pODMRenderParams->rotation_x = pParty->sRotationX;
+  pODMRenderParams->rotation_y = pParty->sRotationY;
+  pODMRenderParams->vPartyPos.x = pParty->vPosition.x - fixpoint_sub0(stru_5C6E00->Cos(pParty->sRotationY), pParty->y_rotation_granularity);
+  pODMRenderParams->vPartyPos.y = pParty->vPosition.y - fixpoint_sub0(stru_5C6E00->Sin(pParty->sRotationY), pParty->y_rotation_granularity);
+  pODMRenderParams->vPartyPos.z = pParty->vPosition.z + pParty->sEyelevel;
   if (bRedraw || pRenderer->pRenderD3D)
   {
     pODMRenderParams->RotationToInts();
     sub_481ED9_MessWithODMRenderParams();
   }
 
-  pIndoorCamera->uMapGridCellX = WorldPosToGridCellX(pParty->vPosition.x);
-  pIndoorCamera->uMapGridCellZ = WorldPosToGridCellZ(pParty->vPosition.y);
-  assert(pIndoorCamera->uMapGridCellX <= 127 && pIndoorCamera->uMapGridCellZ <= 127);
+  pODMRenderParams->uMapGridCellX = WorldPosToGridCellX(pParty->vPosition.x);
+  pODMRenderParams->uMapGridCellZ = WorldPosToGridCellZ(pParty->vPosition.y);
+  assert(pODMRenderParams->uMapGridCellX <= 127 && pODMRenderParams->uMapGridCellZ <= 127);
 
   if (bRedraw)
   {
@@ -753,9 +752,9 @@
     v22 = v6->vWorldViewPosition.y - v4->vWorldViewPosition.y;
     v23 = v6->vWorldViewPosition.z - v4->vWorldViewPosition.z;
   }
-  if ( ((double)pIndoorCamera->pos.x - v4->vWorldPosition.x) * v26
-     + ((double)pIndoorCamera->pos.z - v4->vWorldPosition.z) * v25
-     + ((double)pIndoorCamera->pos.y - v4->vWorldPosition.y) * v24 > 0.0 )
+  if ( ((double)pODMRenderParams->vPartyPos.x - v4->vWorldPosition.x) * v26
+     + ((double)pODMRenderParams->vPartyPos.z - v4->vWorldPosition.z) * v25
+     + ((double)pODMRenderParams->vPartyPos.y - v4->vWorldPosition.y) * v24 > 0.0 )
   {
     a3b = v23 * v18 - v22 * v20;
     v14 = a3b + 6.7553994e15;
@@ -2953,8 +2952,8 @@
             z = actor->vPosition.z;
         }
       }
-      v8 = stru_5C6E00->Atan2(actor->vPosition.x - pIndoorCamera->pos.x,
-                              actor->vPosition.y - pIndoorCamera->pos.y);
+      v8 = stru_5C6E00->Atan2(actor->vPosition.x - pODMRenderParams->vPartyPos.x,
+                              actor->vPosition.y - pODMRenderParams->vPartyPos.y);
 	  LOWORD(v9) = actor->uYawAngle;
       v41 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + v9 - v8) >> 8) & 7;
 	  v10 = actor->uCurrentActionAnimation;
@@ -3009,15 +3008,15 @@
         //LOBYTE(v16) = byte_4E94D3;
         pMobileLightsStack->AddLight(x, y, z, 0, v15->uGlowRadius, 0xFFu, 0xFFu, 0xFFu, byte_4E94D3);
       }
-      v17 = (x - pIndoorCamera->pos.x) << 16;
-      if ( pIndoorCamera->sRotationX )
+      v17 = (x - pODMRenderParams->vPartyPos.x) << 16;
+      if (pODMRenderParams->rotation_x)
       {
-        v18 = (y - pIndoorCamera->pos.y) << 16;
+        v18 = (y - pODMRenderParams->vPartyPos.y) << 16;
         v47 = ((unsigned __int64)(v17 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16)
             + ((unsigned __int64)(v18 * (signed __int64)pODMRenderParams->camera_rotation_y_int_sine) >> 16);
         v50 = (unsigned __int64)(v17 * (signed __int64)pODMRenderParams->camera_rotation_y_int_sine) >> 16;
         v53 = (unsigned __int64)(v18 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16;
-        v44 = (z - pIndoorCamera->pos.z) << 16;
+        v44 = (z - pODMRenderParams->vPartyPos.z) << 16;
         v19 = ((unsigned __int64)(v44 * (signed __int64)pODMRenderParams->camera_rotation_x_int_sine) >> 16)
             + ((unsigned __int64)(v47 * (signed __int64)pODMRenderParams->camera_rotation_x_int_cosine) >> 16);
         X = ((unsigned __int64)(v44 * (signed __int64)pODMRenderParams->camera_rotation_x_int_sine) >> 16)
@@ -3031,17 +3030,17 @@
       }
       else
       {
-        v48 = (y - pIndoorCamera->pos.y) << 16;
+        v48 = (y - pODMRenderParams->vPartyPos.y) << 16;
         v51 = (unsigned __int64)(v17 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16;
         v22 = (unsigned __int64)(v48 * (signed __int64)pODMRenderParams->camera_rotation_y_int_sine) >> 16;
         X = v22 + v51;
         if ( v22 + v51 < 262144 || v22 + v51 > pODMRenderParams->shading_dist_mist << 16 )
           continue;
-        v23 = (unsigned __int64)(((x - pIndoorCamera->pos.x) << 16)
+        v23 = (unsigned __int64)(((x - pODMRenderParams->vPartyPos.x) << 16)
                                * (signed __int64)pODMRenderParams->camera_rotation_y_int_sine) >> 16;
         v20 = ((unsigned __int64)(v48 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16) - v23;
         v42 = ((unsigned __int64)(v48 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16) - v23;
-        v21 = (z - pIndoorCamera->pos.z) << 16;
+        v21 = (z - pODMRenderParams->vPartyPos.z) << 16;
       }
       v45 = v21;
       v24 = abs(v20);
--- a/Outdoor_stuff.h	Tue Sep 17 14:10:41 2013 +0200
+++ b/Outdoor_stuff.h	Tue Sep 17 15:40:09 2013 +0200
@@ -90,6 +90,8 @@
 
 
 
+#define ODM_RENDER_DRAW_D3D_OUTLINES     (1 << 1) // 2
+#define ODM_RENDER_DRAW_TERRAIN_OUTLINES (1 << 2) // 4
 
 /*   88 */
 #pragma pack(push, 1)
@@ -119,8 +121,8 @@
   int shading_dist_shademist;
   int shading_dist_mist;
   unsigned int uCameraFovInDegrees;
-  int int_fov_rad;
-  int int_fov_rad_inv;
+  int int_fov_rad;                      // 157 struct IndoorCamera::fov_rad
+  int int_fov_rad_inv;                  // 157 struct IndoorCamera::fov_rad_inv
   int camera_rotation_y_int_sine;
   int camera_rotation_y_int_cosine;
   int camera_rotation_x_int_sine;
@@ -144,8 +146,16 @@
   int building_gamme;
   int terrain_gamma;
   
-  int rotation_y;  // moved from 157 struct IndoorCamera
-  int rotation_x;
+  int          rotation_y;    // moved from 157 struct IndoorCamera::18
+  int          rotation_x;    // moved from 157 struct IndoorCamera::14
+  Vec3_int_    vPartyPos;     // moved from 157 struct IndoorCamera::00
+  unsigned int flags;         // moved from 157 struct IndoorCamera::4C
+  unsigned int uMapGridCellX; // moved from 157 struct IndoorCamera::0C
+  unsigned int uMapGridCellZ; // moved from 157 struct IndoorCamera::10
+  float fRotationYSine;       // moved from 157 struct IndoorCamera::2C
+  float fRotationYCosine;     // moved from 157 struct IndoorCamera::30
+  float fRotationXSine;       // moved from 157 struct IndoorCamera::34
+  float fRotationXCosine;     // moved from 157 struct IndoorCamera::38
 };
 #pragma pack(pop)
 extern ODMRenderParams *pODMRenderParams;
--- a/ParticleEngine.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/ParticleEngine.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -4,7 +4,6 @@
 #include "Viewport.h"
 #include "Outdoor.h"
 #include "Game.h"
-#include "IndoorCamera.h"
 #include "Outdoor_stuff.h"
 #include "Math.h"
 #include "LOD.h"
@@ -507,10 +506,10 @@
   //int uIDf; // [sp+58h] [bp+8h]@8
   //int uIDb; // [sp+58h] [bp+8h]@9
 
-  v3 = stru_5C6E00->Cos(pIndoorCamera->sRotationX);
-  v44 = stru_5C6E00->Sin(pIndoorCamera->sRotationX);
-  v4 = stru_5C6E00->Cos(pIndoorCamera->sRotationY);
-  v5 = stru_5C6E00->Sin(pIndoorCamera->sRotationY);
+  v3 = stru_5C6E00->Cos(pODMRenderParams->rotation_x);
+  v44 = stru_5C6E00->Sin(pODMRenderParams->rotation_x);
+  v4 = stru_5C6E00->Cos(pODMRenderParams->rotation_y);
+  v5 = stru_5C6E00->Sin(pODMRenderParams->rotation_y);
 
   v6 = &pParticles[uID];
   if (v6->type == ParticleType_Invalid)
@@ -528,11 +527,11 @@
         //uIDc = (LODWORD(v8) - pIndoorCamera->pos.x) << 16;
         //v9 = v6->_y + 6.7553994e15;
         //v10 = (LODWORD(v9) - pIndoorCamera->pos.y) << 16;
-        v11 = fixpoint_mul(v6->x - pIndoorCamera->pos.x, v4) + fixpoint_mul(v6->y - pIndoorCamera->pos.y, v5);
+        v11 = fixpoint_mul(v6->x - pODMRenderParams->vPartyPos.x, v4) + fixpoint_mul(v6->y - pODMRenderParams->vPartyPos.y, v5);
         //HIDWORD(v8) = fixpoint_mul(v6->x - pIndoorCamera->pos.x, v5);
         //v12 = v6->_z + 6.7553994e15;
         //uIDd = (LODWORD(v12) - pIndoorCamera->pos.z) << 16;
-        auto _hidword_v12 = fixpoint_sub0(v11, v3) + fixpoint_mul(v6->z - pIndoorCamera->pos.z, v44);
+        auto _hidword_v12 = fixpoint_sub0(v11, v3) + fixpoint_mul(v6->z - pODMRenderParams->vPartyPos.z, v44);
         LODWORD(v13) = 0;
         HIDWORD(v13) = SLOWORD(pODMRenderParams->int_fov_rad);
         //v14 = v13 / _hidword_v12;
@@ -540,24 +539,24 @@
         //v15 = v6->_screenspace_scale;
         v6->uScreenSpaceX = pViewport->uScreenCenterX
                           - ((signed int)((unsigned __int64)(v6->_screenspace_scale
-                                                           * (signed __int64)(fixpoint_mul(v6->y - pIndoorCamera->pos.y, v4)
-                                                                                        - fixpoint_mul(v6->x - pIndoorCamera->pos.x, v5))) >> 16) >> 16);
+                                                           * (signed __int64)(fixpoint_mul(v6->y - pODMRenderParams->vPartyPos.y, v4)
+                                                                                        - fixpoint_mul(v6->x - pODMRenderParams->vPartyPos.x, v5))) >> 16) >> 16);
         v6->uScreenSpaceY = pViewport->uScreenCenterY
                           - ((signed int)((unsigned __int64)(v6->_screenspace_scale
-                                                           * (signed __int64)(fixpoint_mul(v6->z - pIndoorCamera->pos.z, v3)
+                                                           * (signed __int64)(fixpoint_mul(v6->z - pODMRenderParams->vPartyPos.z, v3)
                                                                                         - ((unsigned __int64)(v11 * (signed __int64)v44) >> 16))) >> 16) >> 16);
         v6->sZValue = _hidword_v12;
       }
       //uIDe = (v41 - pIndoorCamera->pos.x) << 16;
       //v47 = (LODWORD(v39) - pIndoorCamera->pos.y) << 16;
-      v45 = fixpoint_mul(v6->x - pIndoorCamera->pos.x, v4) + fixpoint_mul(v6->y - pIndoorCamera->pos.y, v5);
+      v45 = fixpoint_mul(v6->x - pODMRenderParams->vPartyPos.x, v4) + fixpoint_mul(v6->y - pODMRenderParams->vPartyPos.y, v5);
       //HIDWORD(v42) = fixpoint_mul(v6->x - pIndoorCamera->pos.x, v5);
       //uIDa = (LODWORD(v42) - pIndoorCamera->pos.z) << 16;
-      X_4 = fixpoint_mul(v6->z - pIndoorCamera->pos.z, v44) + fixpoint_sub0(v45, v3);
+      X_4 = fixpoint_mul(v6->z - pODMRenderParams->vPartyPos.z, v44) + fixpoint_sub0(v45, v3);
       if ( X_4 < 0x40000 )
         return 0;
-      v16 = fixpoint_mul(v6->y - pIndoorCamera->pos.y, v4) - fixpoint_mul(v6->x - pIndoorCamera->pos.x, v5);
-      v17 = fixpoint_mul(v6->z - pIndoorCamera->pos.z, v3) - fixpoint_sub0(v45, v44);
+      v16 = fixpoint_mul(v6->y - pODMRenderParams->vPartyPos.y, v4) - fixpoint_mul(v6->x - pODMRenderParams->vPartyPos.x, v5);
+      v17 = fixpoint_mul(v6->z - pODMRenderParams->vPartyPos.z, v3) - fixpoint_sub0(v45, v44);
     }
     else
     {
@@ -570,26 +569,26 @@
         //v21 = v6->_z + 6.7553994e15;
         LODWORD(v22) = 0;
         HIDWORD(v22) = SLOWORD(pODMRenderParams->int_fov_rad);
-        auto _var_123 = fixpoint_mul(v6->x - pIndoorCamera->pos.x, v4) + fixpoint_mul(v6->y - pIndoorCamera->pos.y, v5);
+        auto _var_123 = fixpoint_mul(v6->x - pODMRenderParams->vPartyPos.x, v4) + fixpoint_mul(v6->y - pODMRenderParams->vPartyPos.y, v5);
         //v23 = v22 / _var_123;
         v6->_screenspace_scale = v22 / _var_123;
         //v24 = v6->_screenspace_scale;
         v6->uScreenSpaceX = pViewport->uScreenCenterX
                           - ((signed int)((unsigned __int64)(v6->_screenspace_scale
-                                                           * (signed __int64)(fixpoint_mul(v6->y - pIndoorCamera->pos.y, v4)
-                                                                                        - fixpoint_mul(v6->x - pIndoorCamera->pos.x, v5))) >> 16) >> 16);
+                                                           * (signed __int64)(fixpoint_mul(v6->y - pODMRenderParams->vPartyPos.y, v4)
+                                                                                        - fixpoint_mul(v6->x - pODMRenderParams->vPartyPos.x, v5))) >> 16) >> 16);
         v6->uScreenSpaceY = pViewport->uScreenCenterY - (fixpoint_mul(v6->z, v6->_screenspace_scale) >> 16);
         v6->sZValue = _var_123;
       }
       //uIDb = (v41 - pIndoorCamera->pos.x) << 16;
       //v48 = (LODWORD(v39) - pIndoorCamera->pos.y) << 16;
-      v26 = fixpoint_mul(v6->y - pIndoorCamera->pos.y, v5);
+      v26 = fixpoint_mul(v6->y - pODMRenderParams->vPartyPos.y, v5);
       //v27 = v26 + ((unsigned __int64)(uIDb * (signed __int64)v4) >> 16);
-      X_4 = v26 + fixpoint_mul(v6->x - pIndoorCamera->pos.x, v4);
+      X_4 = v26 + fixpoint_mul(v6->x - pODMRenderParams->vPartyPos.x, v4);
       if ( X_4 < 0x40000 || X_4 > (pODMRenderParams->uPickDepth - 1000) << 16 )
         return 0;
       v17 = v6->z;
-      v16 = fixpoint_mul(v6->y - pIndoorCamera->pos.y, v4) - fixpoint_mul(v6->x - pIndoorCamera->pos.x, v5);
+      v16 = fixpoint_mul(v6->y - pODMRenderParams->vPartyPos.y, v4) - fixpoint_mul(v6->x - pODMRenderParams->vPartyPos.x, v5);
     }
     v40 = v17;
     v28 = abs(v16);
--- a/Render.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/Render.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -12,7 +12,6 @@
 #include "DecalBuilder.h"
 #include "ParticleEngine.h"
 #include "Render.h"
-#include "IndoorCamera.h"
 #include "Outdoor.h"
 #include "Party.h"
 #include "LOD.h"
@@ -517,7 +516,7 @@
       //v28 = v4;
       v36 = v4->uFlags;
       a6 = v4->uGlowRadius * object->field_22_glow_radius_multiplier;
-      v6 = stru_5C6E00->Atan2(object->vPosition.x - pIndoorCamera->pos.x, object->vPosition.y - pIndoorCamera->pos.y);
+      v6 = stru_5C6E00->Atan2(object->vPosition.x - pODMRenderParams->vPartyPos.x, object->vPosition.y - pODMRenderParams->vPartyPos.y);
       //LOWORD(v7) = object->uFacing;
       //v8 = v36;
             v9 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + object->uFacing - v6) >> 8) & 7;
@@ -543,15 +542,15 @@
               //LOBYTE(v11) = byte_4E94D3;
               pMobileLightsStack->AddLight(x, y, z, object->uSectorID, a6, 0xFFu, 0xFFu, 0xFFu, byte_4E94D3);
             }
-            v12 = (x - pIndoorCamera->pos.x) << 16;
-            if ( pIndoorCamera->sRotationX )
+            v12 = (x - pODMRenderParams->vPartyPos.x) << 16;
+            if (pODMRenderParams->rotation_x)
             {
-              v13 = (y - pIndoorCamera->pos.y) << 16;
+              v13 = (y - pODMRenderParams->vPartyPos.y) << 16;
               v30 = ((unsigned __int64)(v12 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16)
                   + ((unsigned __int64)(v13 * (signed __int64)pODMRenderParams->camera_rotation_y_int_sine) >> 16);
               v37 = (unsigned __int64)(v12 * (signed __int64)pODMRenderParams->camera_rotation_y_int_sine) >> 16;
               a6a = (unsigned __int64)(v13 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16;
-              v33 = (z - pIndoorCamera->pos.z) << 16;
+              v33 = (z - pODMRenderParams->vPartyPos.z) << 16;
               v14 = (unsigned __int64)(v30 * (signed __int64)pODMRenderParams->camera_rotation_x_int_cosine) >> 16;
               v15 = (unsigned __int64)(v33 * (signed __int64)pODMRenderParams->camera_rotation_x_int_sine) >> 16;
               v16 = v15 + v14;
@@ -567,17 +566,17 @@
             }
             else
             {
-              v34 = (y - pIndoorCamera->pos.y) << 16;
+              v34 = (y - pODMRenderParams->vPartyPos.y) << 16;
               v19 = (unsigned __int64)(v12 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16;
               v20 = (unsigned __int64)(v34 * (signed __int64)pODMRenderParams->camera_rotation_y_int_sine) >> 16;
               v16 = v20 + v19;
               v42 = v20 + v19;
               if ( v20 + v19 >= 262144 && v16 <= pODMRenderParams->shading_dist_mist << 16 )
               {
-                v21 = (unsigned __int64)(((x - pIndoorCamera->pos.x) << 16) * (signed __int64)pODMRenderParams->camera_rotation_y_int_sine) >> 16;
+                v21 = (unsigned __int64)(((x - pODMRenderParams->vPartyPos.x) << 16) * (signed __int64)pODMRenderParams->camera_rotation_y_int_sine) >> 16;
                 v17 = ((unsigned __int64)(v34 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16) - v21;
                 v40 = ((unsigned __int64)(v34 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16) - v21;
-                v18 = (z - pIndoorCamera->pos.z) << 16;
+                v18 = (z - pODMRenderParams->vPartyPos.z) << 16;
 LABEL_29:
                 v31 = v18;
                 v22 = abs(v17);
@@ -636,8 +635,6 @@
     //while ( v41 < (signed int)uNumSpriteObjects );
   }
 }
-// 4E94D3: using guessed type char byte_4E94D3;
-// 5187E4: using guessed type int uNumSpritesDrawnThisFrame;
 
 //----- (0049D9BC) --------------------------------------------------------
 signed int __stdcall RenderD3D__DeviceEnumerator(GUID *lpGUID, const char *lpDevDesc, const char *lpDriverName, RenderD3D__DevInfo *pOut)
@@ -999,8 +996,8 @@
           //v9 = v8;
           v42 = v8->uFlags;
           a5 = v8->uGlowRadius;
-          v10 = (unsigned __int16 *)stru_5C6E00->Atan2(decor->vPosition.x - pIndoorCamera->pos.x,
-                                                       decor->vPosition.y - pIndoorCamera->pos.y);
+          v10 = (unsigned __int16 *)stru_5C6E00->Atan2(decor->vPosition.x - pODMRenderParams->vPartyPos.x,
+                                                       decor->vPosition.y - pODMRenderParams->vPartyPos.y);
           v11 = *((int *)v0 + 2);
           v37 = v10;
           v12 = v42;
@@ -1043,16 +1040,16 @@
               v16,
               byte_4E94D0);
           }
-          v17 = (decor->vPosition.x - pIndoorCamera->pos.x) << 16;
-          if ( pIndoorCamera->sRotationX )
+          v17 = (decor->vPosition.x - pODMRenderParams->vPartyPos.x) << 16;
+          if (pODMRenderParams->rotation_x)
           {
-            v40 = (decor->vPosition.y - pIndoorCamera->pos.y) << 16;
+            v40 = (decor->vPosition.y - pODMRenderParams->vPartyPos.y) << 16;
             v18 = ((unsigned __int64)(v17 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16)
                 + ((unsigned __int64)(v40 * (signed __int64)pODMRenderParams->camera_rotation_y_int_sine) >> 16);
             v42 = v18;
             b = (unsigned __int64)(v17 * (signed __int64)pODMRenderParams->camera_rotation_y_int_sine) >> 16;
             a5 = (unsigned __int64)(v40 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16;
-            v40 = (decor->vPosition.z - pIndoorCamera->pos.z) << 16;
+            v40 = (decor->vPosition.z - pODMRenderParams->vPartyPos.z) << 16;
             v41 = (unsigned __int64)(v40 * (signed __int64)pODMRenderParams->camera_rotation_x_int_sine) >> 16;
             v19 = (unsigned __int64)(v18 * (signed __int64)pODMRenderParams->camera_rotation_x_int_cosine) >> 16;
             v20 = v19 + ((unsigned __int64)(v40 * (signed __int64)pODMRenderParams->camera_rotation_x_int_sine) >> 16);
@@ -1128,8 +1125,8 @@
           }
           else
           {
-            v42 = (decor->vPosition.x - pIndoorCamera->pos.x) << 16;
-            v40 = (decor->vPosition.y - pIndoorCamera->pos.y) << 16;
+            v42 = (decor->vPosition.x - pODMRenderParams->vPartyPos.x) << 16;
+            v40 = (decor->vPosition.y - pODMRenderParams->vPartyPos.y) << 16;
             b = (unsigned __int64)(v17 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16;
             a5 = (unsigned __int64)(v40 * (signed __int64)pODMRenderParams->camera_rotation_y_int_sine) >> 16;
             v20 = b + ((unsigned __int64)(v40 * (signed __int64)pODMRenderParams->camera_rotation_y_int_sine) >> 16);
@@ -1140,7 +1137,7 @@
               b = (unsigned __int64)(v40 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16;
               v21 = ((unsigned __int64)(v40 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16) - a5;
               v41 = ((unsigned __int64)(v40 * (signed __int64)pODMRenderParams->camera_rotation_y_int_cosine) >> 16) - a5;
-              v22 = (decor->vPosition.z - pIndoorCamera->pos.z) << 16;
+              v22 = (decor->vPosition.z - pODMRenderParams->vPartyPos.z) << 16;
               goto LABEL_30;
             }
           }
@@ -1171,8 +1168,6 @@
   }
     //while ( v35 < (signed int)uNumLevelDecorations );
 }
-// 4E94D0: using guessed type char byte_4E94D0;
-// 5187EC: using guessed type int uNumDecorationsDrawnThisFrame;
 
 //----- (0049D717) --------------------------------------------------------
 HRESULT __stdcall D3DZBufferFormatEnumerator(DDPIXELFORMAT *Src, DDPIXELFORMAT *Dst)
@@ -4920,7 +4915,8 @@
       }
     }
 
-    if (pIndoorCamera->flags & INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES || pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES)
+    //if (pIndoorCamera->flags & INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES || pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES)
+    if (pODMRenderParams->flags & ODM_RENDER_DRAW_TERRAIN_OUTLINES)
       pGame->pIndoorCameraD3D->debug_outline_d3d(d3d_vertex_buffer, uNumVertices, 0x00FFFFFF, 0.0);
   }
 // 4A26BC: could not find valid save-restore pair for esi
@@ -5125,14 +5121,14 @@
     pRenderer->DrawIndoorPolygon(v3, pFace, pBitmaps_LOD->pHardwareTextures[pFace->uBitmapID], v58, v57, -1, 0);
     return;
   }
-  HIDWORD(v69) = pIndoorCamera->sRotationX;
-  HIDWORD(v68) = pIndoorCamera->pos.z;
+  HIDWORD(v69) = pBLVRenderParams->sPartyRotX;
+  HIDWORD(v68) = pBLVRenderParams->vPartyPos.z;
   *(float *)&v74 = (double)pBLVRenderParams->uViewportCenterY;
   v70 = (signed __int64)((double)(pBLVRenderParams->field_40 * pBLVRenderParams->vPartyPos.z)
                        / (((double)pBLVRenderParams->field_40 + 16192.0)
                         * 65536.0)
                        + *(float *)&v74);
-  v5 = (double)pIndoorCamera->sRotationX * 0.0030664064;
+  v5 = (double)pBLVRenderParams->sPartyRotX * 0.0030664064;
   *(float *)&v75 = v5;
   v80 = cos(v5) * 16192.0;
   v6 = (signed __int64)(*(float *)&v74
--- a/UI/UICharacter.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/UI/UICharacter.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -12,7 +12,6 @@
 #include "..\Party.h"
 #include "..\AudioPlayer.h"
 #include "..\Render.h"
-#include "..\IndoorCamera.h"
 #include "..\LOD.h"
 #include "..\Viewport.h"
 #include "..\Time.h"
--- a/UI/UIHouses.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/UI/UIHouses.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -15,12 +15,12 @@
 #include "..\GUIFont.h"
 #include "..\Overlays.h"
 #include "..\Outdoor.h"
+#include "..\Outdoor_stuff.h"
 #include "..\AudioPlayer.h"
 #include "..\VideoPlayer.h"
 #include "..\Monsters.h"
 #include "..\Viewport.h"
 #include "..\Keyboard.h"
-#include "..\IndoorCamera.h"
 #include "..\MapInfo.h"
 #include "..\Log.h"
 #include "..\Game.h"
@@ -2069,7 +2069,11 @@
         }
         else
         {
-          pIndoorCamera->sRotationY = 0;
+          if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+            pODMRenderParams->rotation_y = 0;
+          else if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+            pBLVRenderParams->sPartyRotY = 0;
+
           pParty->uFlags |= 2u;
           pParty->vPosition.x = pTravel->arrival_x;
           pParty->vPosition.y = pTravel->arrival_y;
--- a/UI/UISaveLoad.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/UI/UISaveLoad.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -11,7 +11,6 @@
 #include "..\GUIWindow.h"
 #include "..\GUIFont.h"
 #include "..\Render.h"
-#include "..\IndoorCamera.h"
 #include "..\LOD.h"
 #include "..\SaveLoad.h"
 #include "..\texts.h"
--- a/Vis.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/Vis.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -3,11 +3,11 @@
 #include "BSPModel.h"
 #include "Game.h"
 #include "Actor.h"
-#include "IndoorCamera.h"
 #include "Outdoor_stuff.h"
 #include "Viewport.h"
 #include "Math.h"
 #include "Log.h"
+#include "ErrorHandling.h"
 
 #include "mm7_data.h"
 #include "MM7.h"
@@ -838,10 +838,10 @@
 
   if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
   {
-    if ( pRenderer->pRenderD3D )
+    //if ( pRenderer->pRenderD3D )
       v3 = pGame->pIndoorCameraD3D->fov;
-    else
-      v3 = pIndoorCamera->flt_1C_fov;
+    //else
+    //  v3 = pIndoorCamera->fov_rad;
   }
   else
   {
@@ -857,10 +857,10 @@
 
   if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
   {
-    if ( pRenderer->pRenderD3D )
+    //if ( pRenderer->pRenderD3D )
       v3 = pGame->pIndoorCameraD3D->fov;
-    else
-      v3 = pIndoorCamera->flt_1C_fov;
+    //else
+    //  v3 = pIndoorCamera->fov_rad;
   }
   else
   {
@@ -881,26 +881,41 @@
   int outz; // [sp+94h] [bp-Ch]@1
   int outy; // [sp+98h] [bp-8h]@1
 
-  pRotY = pIndoorCamera->sRotationY + UnprojectX(fMouseX);
-  pStartR.z = pIndoorCamera->pos.z;
-  pStartR.x = pIndoorCamera->pos.x;
-  pStartR.y = pIndoorCamera->pos.y;
-  pRotX = pIndoorCamera->sRotationX + UnprojectY(fMouseY);
+  if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+  {
+    pRotY = pBLVRenderParams->sPartyRotY + UnprojectX(fMouseX);
+    pStartR.z = pBLVRenderParams->vPartyPos.z;
+    pStartR.x = pBLVRenderParams->vPartyPos.x;
+    pStartR.y = pBLVRenderParams->vPartyPos.y;
+    pRotX = pBLVRenderParams->sPartyRotX + UnprojectY(fMouseY);
+    
+    v11[1].vWorldPosition.x = (double)pBLVRenderParams->vPartyPos.x;
+    v11[1].vWorldPosition.y = (double)pBLVRenderParams->vPartyPos.y;
+    v11[1].vWorldPosition.z = (double)pBLVRenderParams->vPartyPos.z;
+  }
+  else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+  {
+    pRotY = pODMRenderParams->rotation_y + UnprojectX(fMouseX);
+    pStartR.z = pODMRenderParams->vPartyPos.z;
+    pStartR.x = pODMRenderParams->vPartyPos.x;
+    pStartR.y = pODMRenderParams->vPartyPos.y;
+    pRotX = pODMRenderParams->rotation_x + UnprojectY(fMouseY);
+
+    v11[1].vWorldPosition.x = (double)pODMRenderParams->vPartyPos.x;
+    v11[1].vWorldPosition.y = (double)pODMRenderParams->vPartyPos.y;
+    v11[1].vWorldPosition.z = (double)pODMRenderParams->vPartyPos.z;
+  }
+  else Error("Invalid level type (%u)", uCurrentlyLoadedLevelType);
+
   pDepth = fixpoint_from_float(fPickDepth);
   Vec3_int_::Rotate(pDepth, pRotY, pRotX, pStartR, &outx, &outy, &outz);
 
-  v11[0].flt_2C = 0.0;
   v11[0].vWorldPosition.x = (double)outx;
   v11[0].vWorldPosition.y = (double)outy;
   v11[0].vWorldPosition.z = (double)outz;
 
-  v11[1].flt_2C = 0.0;
-  v11[1].vWorldPosition.x = (double)pIndoorCamera->pos.x;
-  v11[1].vWorldPosition.y = (double)pIndoorCamera->pos.y;
-  v11[1].vWorldPosition.z = (double)pIndoorCamera->pos.z;
-
-  memcpy(pRay, &v11[1], sizeof(RenderVertexSoft));
-  memcpy(&pRay[1], &v11[0], sizeof(RenderVertexSoft));
+  memcpy(pRay + 0, &v11[1], sizeof(RenderVertexSoft));
+  memcpy(pRay + 1, &v11[0], sizeof(RenderVertexSoft));
 }
 
 //----- (004C2551) --------------------------------------------------------
--- a/_deleted.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/_deleted.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -12987,7 +12987,6 @@
 }
 
 
-/*
 //  143
 #pragma pack(push, 1)
 struct Span
@@ -13049,7 +13048,157 @@
 
 extern Edge stru_80C9A4;
 extern Edge stru_80C9D8;
-*/
+
+
+
+#define INDOOR_CAMERA_DRAW_SW_OUTLINES 1
+#define INDOOR_CAMERA_DRAW_D3D_OUTLINES 2
+#define INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES 4
+//  157
+#pragma pack(push, 1)
+struct IndoorCamera
+{
+  //----- (0042391F) --------------------------------------------------------
+  IndoorCamera()
+  {
+    sRotationX = 0;
+    sRotationY = 0;
+    fov_rad = 2000.0f;
+    fov_rad_inv = 32.768002f;
+
+    flags = 0;
+  }
+  void Initialize(int degFov, unsigned int uViewportWidth, unsigned int uViewportHeight);
+  void Initialize2();
+  float ViewTransform_ODM(struct RenderVertexSoft *a1);
+
+
+  Vec3_int_ pos;
+  unsigned int uMapGridCellX;
+  unsigned int uMapGridCellZ;
+  int sRotationX;
+  int sRotationY;
+  float fov_rad;
+  float fov_rad_inv;
+  int field_24;
+  int field_28;
+  float fRotationYSine;
+  float fRotationYCosine;
+  float fRotationXSine;
+  float fRotationXCosine;
+  int _int_sine;
+  int _int_cosine;
+  int _int_sine_2;
+  int _int_cosine_2;
+  int flags;  // & INDOOR_CAMERA_DRAW_D3D_OUTLINES:  render terrain outlines in d3d
+};
+#pragma pack(pop)
+
+
+
+extern IndoorCamera *pIndoorCamera; // idb
+
+
+IndoorCamera *pIndoorCamera; // idb
+
+
+
+
+
+//----- (00481CCE) --------------------------------------------------------
+float IndoorCamera::ViewTransform_ODM(RenderVertexSoft *a1)
+{
+  float result; // eax@1
+  double vCamToVertexZ; // st7@1
+  double v3; // st6@1
+  double v4; // st5@1
+  double v5; // st4@1
+  float v6; // ST04_4@3
+  float v7; // [sp+0h] [bp-14h]@1
+  float v8; // [sp+8h] [bp-Ch]@1
+  float vCamToVertexX; // [sp+Ch] [bp-8h]@1
+  float vCamToVertexY; // [sp+10h] [bp-4h]@1
+
+  v8 = fRotationXCosine;
+  result = fRotationXSine;
+  v7 = fRotationXSine;
+  vCamToVertexX = a1->vWorldPosition.x - (double)pos.x;
+  vCamToVertexY = a1->vWorldPosition.y - (double)pos.y;
+  vCamToVertexZ = a1->vWorldPosition.z - (double)pos.z;
+  v3 = fRotationYCosine;
+  v4 = fRotationYSine;
+  v5 = vCamToVertexY * fRotationYSine + fRotationYCosine * vCamToVertexX;
+  if ( sRotationX )
+  {
+    v6 = vCamToVertexY * fRotationYSine + fRotationYCosine * vCamToVertexX;
+    a1->vWorldViewPosition.x = v5 * fRotationXCosine + fRotationXSine * vCamToVertexZ;
+    a1->vWorldViewPosition.y = v3 * vCamToVertexY - v4 * vCamToVertexX;
+    a1->vWorldViewPosition.z = v8 * vCamToVertexZ - v6 * v7;
+  }
+  else
+  {
+    a1->vWorldViewPosition.x = vCamToVertexY * fRotationYSine + fRotationYCosine * vCamToVertexX;
+    a1->vWorldViewPosition.y = v3 * vCamToVertexY - v4 * vCamToVertexX;
+    a1->vWorldViewPosition.z = vCamToVertexZ;
+  }
+  return result;
+}
+
+
+
+//----- (0042394D) --------------------------------------------------------
+void IndoorCamera::Initialize(int degFov, unsigned int uViewportWidth, unsigned int uViewportHeight)
+{
+  IndoorCamera *v4; // esi@1
+  double v5; // st7@1
+
+  v4 = this;
+  v5 = (double)(signed int)(signed __int64)((double)(signed int)uViewportWidth
+                                          * 0.5
+                                          / tan((double)(degFov >> 1) * 0.01745329)
+                                          + 0.5);
+  v4->fov_rad = v5;
+  v4->fov_rad_inv = 65536.0 / v5;
+}
+
+//----- (004239A7) --------------------------------------------------------
+void IndoorCamera::Initialize2()
+{
+  //IndoorCamera *v1; // esi@1
+  double v2; // st7@4
+  //double v3; // st7@6
+  //int v4; // eax@6
+  //int v5; // eax@6
+  //int v6; // ST04_4@6
+  //int v7; // eax@6
+  //int v8; // ST04_4@6
+
+  //v1 = this;
+  fRotationYSine = sin((3.141592653589793 + 3.141592653589793) * (double)sRotationY * 0.00048828125);
+  fRotationYCosine = cos((3.141592653589793 + 3.141592653589793) * (double)sRotationY * 0.00048828125);
+  if ( byte_4D864C && pGame->uFlags & 0x80 || uCurrentlyLoadedLevelType == LEVEL_Indoor)
+  {
+    fRotationXSine = sin((3.141592653589793 + 3.141592653589793) * (double)-sRotationX * 0.00048828125);
+    v2 = (3.141592653589793 + 3.141592653589793) * (double)-sRotationX;
+  }
+  else
+  {
+    fRotationXSine = sin((3.141592653589793 + 3.141592653589793) * (double)sRotationX * 0.00048828125);
+    v2 = (3.141592653589793 + 3.141592653589793) * (double)sRotationX;
+  }
+  //v3 = cos(v2 * 0.00048828125);
+  //v4 = sRotationY;
+  fRotationXCosine = cos(v2 * 0.00048828125);
+  //v5 = stru_5C6E00->SinCos(sRotationY - stru_5C6E00->uIntegerHalfPi);
+  //v6 = sRotationY;
+  _int_sine = stru_5C6E00->Sin(sRotationY);
+  _int_cosine = stru_5C6E00->Cos(sRotationY);
+  //v7 = stru_5C6E00->SinCos(sRotationX - stru_5C6E00->uIntegerHalfPi);
+  //v8 = sRotationX;
+  _int_sine_2 = stru_5C6E00->Sin(sRotationX);
+  _int_cosine_2 = stru_5C6E00->Cos(sRotationX);
+}
+// 4D864C: using guessed type char byte_4D864C;
 
 
 
--- a/mm7_2.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/mm7_2.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -31,7 +31,6 @@
 #include "AudioPlayer.h"
 #include "Outdoor.h"
 #include "Outdoor_stuff.h"
-#include "IndoorCamera.h"
 #include "Overlays.h"
 #include "Arcomage.h"
 #include "LOD.h"
@@ -3050,13 +3049,13 @@
   init_event_triggers();
 
   pGameLoadingUI_ProgressBar->Progress();
-
-  pIndoorCamera->pos.y = 0;
-  pIndoorCamera->pos.x = 0;
-  pIndoorCamera->pos.z = 100;
-  pIndoorCamera->sRotationY = 0;
-  pIndoorCamera->sRotationX = 0;
-  viewparams->bRedrawGameUI = 1;
+  
+  pODMRenderParams->vPartyPos.x = 0;
+  pODMRenderParams->vPartyPos.y = 0;
+  pODMRenderParams->vPartyPos.z = 100;
+  pODMRenderParams->rotation_y = 0;
+  pODMRenderParams->rotation_x = 0;
+  viewparams->bRedrawGameUI = true;
   uLevel_StartingPointType = MapStartPoint_Party;
   pSprites_LOD->_461397();
   pPaletteManager->LockTestAll();
@@ -3822,9 +3821,9 @@
   pViewport->SetScreen(viewparams->uSomeX, viewparams->uSomeY, viewparams->uSomeZ, viewparams->uSomeW);
   pViewport->_4C02F8((signed __int64)(flt_6BE3A0 * 65536.0));
 
-  pIndoorCamera = new IndoorCamera;
-  pIndoorCamera->Initialize(65, viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X + 1,
-                                viewparams->uScreen_BttmR_Y - viewparams->uScreen_topL_Y + 1);
+  //pIndoorCamera = new IndoorCamera;
+  //pIndoorCamera->Initialize(65, viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X + 1,
+  //                              viewparams->uScreen_BttmR_Y - viewparams->uScreen_topL_Y + 1);
 
   InitializeTurnBasedAnimations(&stru_50C198);
   pBitmaps_LOD->_inlined_sub1();
@@ -5023,7 +5022,7 @@
   assert(sizeof(BLVLightMM7) == 0x10);
   assert(sizeof(BLVDoor) == 0x50);
   assert(sizeof(IndoorLocation) == 0x690);
-  assert(sizeof(ODMRenderParams) == 0x74);
+  //assert(sizeof(ODMRenderParams) == 0x74);
   assert(sizeof(Mouse) == 0x114);
   assert(sizeof(Particle_sw) == 0x68);
   assert(sizeof(Particle) == 0x68);
@@ -5050,7 +5049,7 @@
   assert(sizeof(BspRenderer) == 0x53740);
   assert(sizeof(PaletteManager) == 0x267AF0);
   assert(sizeof(ViewingParams) == 0x26C);
-  assert(sizeof(IndoorCamera) == 0x50);
+  //assert(sizeof(IndoorCamera) == 0x50);
   assert(sizeof(Bloodsplat) == 0x28);
   assert(sizeof(BloodsplatContainer) == 0xA0C);
   assert(sizeof(TrailParticle) == 0x18);
--- a/mm7_3.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/mm7_3.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -23,7 +23,6 @@
 #include "AudioPlayer.h"
 #include "Outdoor.h"
 #include "Outdoor_stuff.h"
-#include "IndoorCamera.h"
 #include "Overlays.h"
 #include "LOD.h"
 #include "Actor.h"
@@ -4023,7 +4022,7 @@
   float v13; // ST24_4@13
   int v14; // esi@13
   char *v15; // esi@15
-  signed int v16; // eax@16
+  //signed int v16; // eax@16
   __int16 v17; // fps@16
   unsigned __int8 v18; // c2@16
   unsigned __int8 v19; // c3@16
@@ -4116,29 +4115,29 @@
     v31 = 3;
     do
     {
-      v40 = (double)stru_5C6E00->Cos(pIndoorCamera->sRotationX) * 0.0000152587890625;
-      v32 = (double)stru_5C6E00->Sin(pIndoorCamera->sRotationX) * 0.0000152587890625;
-      v34 = (double)stru_5C6E00->Cos(pIndoorCamera->sRotationY) * 0.0000152587890625;
-      v16 = stru_5C6E00->Sin(pIndoorCamera->sRotationY);
+      v40 = (double)stru_5C6E00->Cos(pODMRenderParams->rotation_x) * 0.0000152587890625;
+      v32 = (double)stru_5C6E00->Sin(pODMRenderParams->rotation_x) * 0.0000152587890625;
+      v34 = (double)stru_5C6E00->Cos(pODMRenderParams->rotation_y) * 0.0000152587890625;
+      v33 = (double)stru_5C6E00->Sin(pODMRenderParams->rotation_y) * 0.0000152587890625;
+      //v16 = stru_5C6E00->Sin(pODMRenderParams->rotation_y);
       LODWORD(v38) = *(int *)v15;
-      v33 = (double)v16 * 0.0000152587890625;
       //UNDEF(v17);
-      v20 = *((float *)v15 - 1) - (double)pIndoorCamera->pos.x;
+      v20 = *((float *)v15 - 1) - (double)pODMRenderParams->vPartyPos.x;
       //if ( v19 | v18 )
-	  if(pIndoorCamera->pos.x == 0)
+	  if (pODMRenderParams->vPartyPos.x == 0)
       {
         v27 = v20;
         LODWORD(v35) = *((int *)v15 + 1);
-        v28 = v38 - (double)pIndoorCamera->pos.y;
+        v28 = v38 - (double)pODMRenderParams->vPartyPos.y;
         v25 = v33 * v28 + v34 * v27;
         v26 = v34 * v28 - v33 * v27;
       }
       else
       {
         v21 = v20;
-        v22 = v38 - (double)pIndoorCamera->pos.y;
+        v22 = v38 - (double)pODMRenderParams->vPartyPos.y;
         v23 = v33 * v22 + v34 * v21;
-        v24 = *((float *)v15 + 1) - (double)pIndoorCamera->pos.z;
+        v24 = *((float *)v15 + 1) - (double)pODMRenderParams->vPartyPos.z;
         v25 = v32 * v24 + v40 * v23;
         v26 = v34 * v22 - v33 * v21;
         v35 = v40 * v24 - v32 * v23;
@@ -4711,15 +4710,15 @@
   angle = (signed int)(pODMRenderParams->uCameraFovInDegrees << 11) / 360 >> 1;
   //v14 = uModelID;
   v2 = &pOutdoor->pBModels[uModelID];
-  v3 = v2->vBoundingCenter.x - pIndoorCamera->pos.x;
-  v4 = v2->vBoundingCenter.y - pIndoorCamera->pos.y;
-  v5 = stru_5C6E00->Cos(pIndoorCamera->sRotationY);
-  v21 = stru_5C6E00->Sin(pIndoorCamera->sRotationY);
-  v18 = stru_5C6E00->Cos(pIndoorCamera->sRotationX);
-  stru_5C6E00->Sin(pIndoorCamera->sRotationX);
+  v3 = v2->vBoundingCenter.x - pODMRenderParams->vPartyPos.x;
+  v4 = v2->vBoundingCenter.y - pODMRenderParams->vPartyPos.y;
+  v5 = stru_5C6E00->Cos(pODMRenderParams->rotation_y);
+  v21 = stru_5C6E00->Sin(pODMRenderParams->rotation_y);
+  v18 = stru_5C6E00->Cos(pODMRenderParams->rotation_x);
+  stru_5C6E00->Sin(pODMRenderParams->rotation_x);
   v6 = v5;
   v17 = v3 * v5 + v4 * v21;
-  if ( pIndoorCamera->sRotationX )
+  if (pODMRenderParams->rotation_x)
     v17 = (unsigned __int64)(v17 * (signed __int64)v18) >> 16;
   v19 = v4 * v6 - v3 * v21;
   v7 = abs(v4);
@@ -5309,11 +5308,11 @@
     return;
   }
 
-  v30 = ((double)(pODMRenderParams->int_fov_rad * pIndoorCamera->pos.z)
+  v30 = ((double)(pODMRenderParams->int_fov_rad * pODMRenderParams->vPartyPos.z)
         / ((double)pODMRenderParams->int_fov_rad + 8192.0) + pViewport->uScreenCenterY);//184 изменяется при подъёме на высоту
   v38 = pViewport->uScreenCenterY - pODMRenderParams->int_fov_rad /
-       (pODMRenderParams->shading_dist_mist * cos(pIndoorCamera->sRotationX * 0.003066406352445483) + 0.0000001000000011686097) *
-       (pODMRenderParams->shading_dist_mist * -sin(pIndoorCamera->sRotationX * 0.003066406352445483) - pIndoorCamera->pos.z);//61 / 184 / 310 изменяется при наклоне камеры
+       (pODMRenderParams->shading_dist_mist * cos(pODMRenderParams->rotation_x * 0.003066406352445483) + 0.0000001000000011686097) *
+       (pODMRenderParams->shading_dist_mist * -sin(pODMRenderParams->rotation_x * 0.003066406352445483) - pODMRenderParams->vPartyPos.z);//61 / 184 / 310 изменяется при наклоне камеры
 
   pSkyPolygon.Create_48607B(&stru_8019C8);
   pSkyPolygon.ptr_38->_48694B_frustum_sky();//maybe creating skydome(возможно создание купола неба)
@@ -5326,9 +5325,9 @@
   pSkyPolygon.uNumVertices = 4;//количество вершин
 
   //centering(центруем)--наклон камеры ----------------------------------------//
-  pSkyPolygon.v_18.x = -stru_5C6E00->Sin(pIndoorCamera->sRotationX + 16);//-3216, вверх: -28020, вниз: 22078
+  pSkyPolygon.v_18.x = -stru_5C6E00->Sin(pODMRenderParams->rotation_x + 16);//-3216, вверх: -28020, вниз: 22078
   pSkyPolygon.v_18.y = 0;
-  pSkyPolygon.v_18.z = -stru_5C6E00->Cos(pIndoorCamera->sRotationX + 16);//-65457, вверх: -59244, вниз: -61705
+  pSkyPolygon.v_18.z = -stru_5C6E00->Cos(pODMRenderParams->rotation_x + 16);//-65457, вверх: -59244, вниз: -61705
   //---------------------------------------------------------------------------//
 
   pSkyPolygon.field_24 = 0x2000000;
@@ -5559,12 +5558,32 @@
   strcpy(Source, &pFilename[v7]);
   strcpy(pOutdoor->pLevelFilename, Source);
   pWeather->Initialize();
-  pIndoorCamera->sRotationY = pParty->sRotationY;
-  pIndoorCamera->sRotationX = pParty->sRotationX;
+  pODMRenderParams->rotation_y = pParty->sRotationY;
+  pODMRenderParams->rotation_x = pParty->sRotationX;
   pODMRenderParams->RotationToInts();
   pOutdoor->UpdateSunlightVectors();
-  pODMRenderParams->int_fov_rad = (signed __int64)pIndoorCamera->flt_1C_fov;
-  pODMRenderParams->int_fov_rad_inv = (signed __int64)pIndoorCamera->flt_20_inv_1C;
+
+  float fov_rad;
+  float fov_rad_inv;
+  //----- (0042394D) --------------------------------------------------------
+  //void IndoorCamera::Initialize(int degFov, unsigned int uViewportWidth, unsigned int uViewportHeight)
+  {
+    //pIndoorCamera->Initialize(65, viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X + 1,
+    //                              viewparams->uScreen_BttmR_Y - viewparams->uScreen_topL_Y + 1);
+
+    int degFov = 65;
+    int uViewportWidth = viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X + 1;
+    int uViewportHeight = viewparams->uScreen_BttmR_Y - viewparams->uScreen_topL_Y + 1;
+
+    double v5 = (double)(signed int)(signed __int64)((double)(signed int)uViewportWidth
+                                          * 0.5
+                                          / tan((double)(degFov >> 1) * 0.01745329)
+                                          + 0.5);
+    fov_rad = v5;
+    fov_rad_inv = 65536.0 / v5;
+  }
+  pODMRenderParams->int_fov_rad = (signed __int64)fov_rad;
+  pODMRenderParams->int_fov_rad_inv = (signed __int64)fov_rad_inv;
 
   for (int i = 0; i < 20000; ++i)
   {
@@ -6137,23 +6156,23 @@
   //v8 = -pIndoorCamera->pos.y;
   v9 = pODMRenderParams->camera_rotation_y_int_cosine;
   //v26 = -pIndoorCamera->pos.z;
-  v11 = pODMRenderParams->camera_rotation_y_int_cosine * -pIndoorCamera->pos.x + pODMRenderParams->camera_rotation_y_int_sine * -pIndoorCamera->pos.y;
-  v24 = pODMRenderParams->camera_rotation_y_int_cosine * -pIndoorCamera->pos.y - pODMRenderParams->camera_rotation_y_int_sine * -pIndoorCamera->pos.x;
-  if ( pIndoorCamera->sRotationX )
+  v11 = pODMRenderParams->camera_rotation_y_int_cosine * -pODMRenderParams->vPartyPos.x + pODMRenderParams->camera_rotation_y_int_sine * -pODMRenderParams->vPartyPos.y;
+  v24 = pODMRenderParams->camera_rotation_y_int_cosine * -pODMRenderParams->vPartyPos.y - pODMRenderParams->camera_rotation_y_int_sine * -pODMRenderParams->vPartyPos.x;
+  if (pODMRenderParams->rotation_x)
   {
     this->field_0_party_dir_x = fixpoint_sub0(v11, pODMRenderParams->camera_rotation_x_int_cosine) +
-                                fixpoint_sub0((-pIndoorCamera->pos.z) << 16, pODMRenderParams->camera_rotation_x_int_sine);
+                                fixpoint_sub0((-pODMRenderParams->vPartyPos.z) << 16, pODMRenderParams->camera_rotation_x_int_sine);
     this->field_4_party_dir_y = v24;
-    this->field_8_party_dir_z = fixpoint_sub0((-pIndoorCamera->pos.z) << 16, v25) - fixpoint_sub0(v11, v27);
+    this->field_8_party_dir_z = fixpoint_sub0((-pODMRenderParams->vPartyPos.z) << 16, v25) - fixpoint_sub0(v11, v27);
   }
   else
   {
     this->field_0_party_dir_x = v11;
     this->field_4_party_dir_y = v24;
-    this->field_8_party_dir_z = (-pIndoorCamera->pos.z) << 16;
-  }
-
-  if (pIndoorCamera->sRotationX)
+    this->field_8_party_dir_z = (-pODMRenderParams->vPartyPos.z) << 16;
+  }
+
+  if (pODMRenderParams->rotation_x)
   {
     v17 = fixpoint_sub0(a2, v9) + fixpoint_sub0(a3, v7);
 
@@ -6168,7 +6187,7 @@
     this->field_14 = a4;
   }
 
-  if (pIndoorCamera->sRotationX)
+  if (pODMRenderParams->rotation_x)
   {
     v19 = fixpoint_sub0(a5, v9) + fixpoint_sub0(a6, v7);
 
--- a/mm7_4.cpp	Tue Sep 17 14:10:41 2013 +0200
+++ b/mm7_4.cpp	Tue Sep 17 15:40:09 2013 +0200
@@ -20,7 +20,6 @@
 #include "AudioPlayer.h"
 #include "Outdoor.h"
 #include "Outdoor_stuff.h"
-#include "IndoorCamera.h"
 #include "LOD.h"
 #include "Actor.h"
 #include "Events.h"