diff mm7_3.cpp @ 168:ee11772d0ad2

New sky (turn on -new_sky console command) cube textures are stored in /daata/skybox/%name%_xn.tga %name%%_xp.tga %name%_zn.tga etc
author Nomad
date Thu, 14 Feb 2013 13:58:34 +0200
parents 8ab4484c22e0
children d1dde383af89
line wrap: on
line diff
--- a/mm7_3.cpp	Tue Feb 12 11:59:49 2013 +0200
+++ b/mm7_3.cpp	Thu Feb 14 13:58:34 2013 +0200
@@ -6993,7 +6993,7 @@
             memcpy(&array_50AC10[v28], &array_73D150[v28], sizeof(array_50AC10[v28]));
             ++v28;
             --v29;
-            array_50A2B0[v28 + 49].flt_20 = v30;
+            array_50A2B0[v28 + 49]._rhw = v30;
           }
           while ( v29 );
           pFace = v46;
@@ -7360,7 +7360,7 @@
             v32 = 1.0 / (*(float *)(v31 * 48 + 7590236) + 0.0000001);
             memcpy(&array_50AC10[v31], &array_73D150[v31], sizeof(array_50AC10[v31]));
             ++v31;
-            array_50A2B0[v31 + 49].flt_20 = v32;
+            array_50A2B0[v31 + 49]._rhw = v32;
             v84 = v12->sTextureDeltaU + *(short *)(v30 - 40);
             array_50A2B0[v31 + 49].u = (double)v84 * v28;
             v33 = v12->sTextureDeltaV + *(short *)v30;
@@ -7723,6 +7723,478 @@
   return result;
 }
 
+
+
+unsigned short *LoadTgaTexture(const wchar_t *filename, int *out_width = nullptr, int *out_height = nullptr)
+{
+  #pragma pack(push, 1)
+    struct TGAHeader
+    {
+      unsigned char  tgaSkip;
+      unsigned char  colourmaptype;      // type of colour map 0=none, 1=has palette
+      unsigned char  tgaType;            // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
+
+      short colourmapstart;     // first colour map entry in palette
+      short colourmaplength;    // number of colours in palette
+      char  colourmapbits;      // number of bits per palette entry 15,16,24,32
+
+      //unsigned char  tgaDontCare2[9];
+      short xstart;             // image x origin
+      short ystart;             // image y origin
+
+      unsigned short tgaWidth;
+      unsigned short tgaHeight;
+      unsigned char  tgaBPP;
+
+      char  descriptor;         // image descriptor bits:   00vhaaaa
+        //      h horizontal flip
+        //      v vertical flip
+        //      a alpha bits
+    };
+  #pragma pack(pop)
+
+  if (out_width)
+    *out_width = 0;
+  if (out_height)
+    *out_height = 0;
+
+  DWORD w;
+  auto  file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
+  if (file == INVALID_HANDLE_VALUE)
+    return nullptr;
+
+  TGAHeader header;
+  ReadFile(file, &header, sizeof(header), &w, nullptr);
+  SetFilePointer(file, header.tgaSkip, nullptr, FILE_CURRENT);
+
+  if (header.tgaBPP != 24 || header.tgaType != 2)
+  {
+    CloseHandle(file);
+    return nullptr;
+  }
+
+  int imgSize = header.tgaWidth * header.tgaHeight * 3;
+  auto pixels = new unsigned char[imgSize];
+  ReadFile(file, pixels, imgSize, &w, nullptr);
+  CloseHandle(file);
+
+  if (w != imgSize)
+  {
+    delete [] pixels;
+    return nullptr;
+  }
+
+  if (out_width)
+    *out_width = header.tgaWidth;
+  if (out_height)
+    *out_height = header.tgaHeight;
+
+  auto pixels_16bit = new unsigned short[imgSize / 3];
+  for (int i = 0; i < imgSize / 3; ++i)
+  {
+    pixels_16bit[i] = (pixels[i * 3] / 8 & 0x1F) |
+                      ((pixels[i * 3 + 1] / 4 & 0x3F) << 5) |
+                      ((pixels[i * 3 + 2] / 8 & 0x1F) << 11);
+  }
+  delete [] pixels;
+  return pixels_16bit;
+}
+
+unsigned short *skybox_xn, *skybox_xp,
+              *skybox_yn, *skybox_yp,
+              *skybox_zn, *skybox_zp;
+int            skybox_width, skybox_height;
+IDirect3DTexture2   *skybox_texture;
+IDirectDrawSurface4 *skybox_surface;
+bool Skybox_Initialize(const wchar_t *skybox_name)
+{
+  wchar_t xn_filename[1024], xp_filename[1024],
+          yn_filename[1024], yp_filename[1024],
+          zn_filename[1024], zp_filename[1024];
+  swprintf(xn_filename, L"%s_xn.tga", skybox_name); swprintf(xp_filename, L"%s_xp.tga", skybox_name);
+  swprintf(yn_filename, L"%s_yn.tga", skybox_name); swprintf(yp_filename, L"%s_yp.tga", skybox_name);
+  swprintf(zn_filename, L"%s_zn.tga", skybox_name); swprintf(zp_filename, L"%s_zp.tga", skybox_name);
+
+  int xn_width, xn_height;
+  skybox_xn = LoadTgaTexture(xn_filename, &xn_width, &xn_height);
+  if (!skybox_xn)
+    return false;
+
+  int xp_width, xp_height;
+  skybox_xp = LoadTgaTexture(xp_filename, &xp_width, &xp_height);
+  if (!skybox_xp || xp_width != xn_width || xp_height != xn_height)
+  {
+    delete [] skybox_xn;
+    if (skybox_xp) delete [] skybox_xp;
+    return false;
+  }
+
+  int yn_width, yn_height;
+  skybox_yn = LoadTgaTexture(yn_filename, &yn_width, &yn_height);
+  if (!skybox_yn || yn_width != xn_width || yn_height != xn_height)
+  {
+    delete [] skybox_xn;
+    if (skybox_xp) delete [] skybox_xp;
+    if (skybox_yn) delete [] skybox_yn;
+    return false;
+  }
+
+  int yp_width, yp_height;
+  skybox_yp = LoadTgaTexture(yp_filename, &yp_width, &yp_height);
+  if (!skybox_yp || yp_width != xn_width || yp_height != xn_height)
+  {
+    delete [] skybox_xn;
+    if (skybox_xp) delete [] skybox_xp;
+    if (skybox_yn) delete [] skybox_yn;
+    if (skybox_yp) delete [] skybox_yp;
+    return false;
+  }
+
+  int zn_width, zn_height;
+  skybox_zn = LoadTgaTexture(zn_filename, &zn_width, &zn_height);
+  if (!skybox_zn || zn_width != xn_width || zn_height != xn_height)
+  {
+    delete [] skybox_xn;
+    if (skybox_xp) delete [] skybox_xp;
+    if (skybox_yn) delete [] skybox_yn;
+    if (skybox_yp) delete [] skybox_yp;
+    if (skybox_zn) delete [] skybox_zn;
+    return false;
+  }
+
+  int zp_width, zp_height;
+  skybox_zp = LoadTgaTexture(zp_filename, &zp_width, &zp_height);
+  if (!skybox_zp || zp_width != xn_width || zp_height != xn_height)
+  {
+    delete [] skybox_xn;
+    if (skybox_xp) delete [] skybox_xp;
+    if (skybox_yn) delete [] skybox_yn;
+    if (skybox_yp) delete [] skybox_yp;
+    if (skybox_zn) delete [] skybox_zn;
+    if (skybox_zp) delete [] skybox_zp;
+    return false;
+  }
+
+  skybox_width = xn_width;
+  skybox_height = xn_height;
+
+  
+  if (!pRenderer->pRenderD3D->CreateTexture(skybox_width, skybox_height, &skybox_surface, &skybox_texture,
+                                            false, false, pRenderer->uMinDeviceTextureDim))
+    return false;
+
+  return true;
+}
+
+
+struct vector
+{
+  float x, y, z;
+};
+struct matrix
+{
+  float m[4][4];
+};
+void VectorNormalize(vector *v)
+{
+  float invmag = 1.0f / sqrtf(v->x * v->x + v->y * v->y + v->z * v->z);
+  v->x *= invmag;
+  v->y *= invmag;
+  v->z *= invmag;
+}
+void MatrixRotationAxis(matrix *pout, CONST vector *pv, float angle)
+{
+  memset(pout, 0, sizeof(matrix));
+  pout->m[3][0] = 0;
+  pout->m[3][1] = 0;
+  pout->m[3][2] = 0;
+  pout->m[3][3] = 1;
+
+  vector v;
+  v.x = pv->x; v.y = pv->y; v.z = pv->z;
+  VectorNormalize(&v);
+
+    pout->m[0][0] = (1.0f - cos(angle)) * v.x * v.x + cos(angle);
+    pout->m[1][0] = (1.0f - cos(angle)) * v.x * v.y - sin(angle) * v.z;
+    pout->m[2][0] = (1.0f - cos(angle)) * v.x * v.z + sin(angle) * v.y;
+    pout->m[0][1] = (1.0f - cos(angle)) * v.y * v.x + sin(angle) * v.z;
+    pout->m[1][1] = (1.0f - cos(angle)) * v.y * v.y + cos(angle);
+    pout->m[2][1] = (1.0f - cos(angle)) * v.y * v.z - sin(angle) * v.x;
+    pout->m[0][2] = (1.0f - cos(angle)) * v.z * v.x - sin(angle) * v.y;
+   pout->m[1][2] = (1.0f - cos(angle)) * v.z * v.y + sin(angle) * v.x;
+    pout->m[2][2] = (1.0f - cos(angle)) * v.z * v.z + cos(angle);
+}
+void VectorTransform(const matrix *m, const vector *v, vector *out)
+{
+  out->x = m->m[0][0] * v->x + m->m[1][0] * v->y + m->m[2][0] * v->z + m->m[3][0];
+  out->y = m->m[0][1] * v->x + m->m[1][1] * v->y + m->m[2][1] * v->z + m->m[3][1];
+  out->z = m->m[0][2] * v->x + m->m[1][2] * v->y + m->m[2][2] * v->z + m->m[3][2];
+}
+
+
+bool DrawSkyD3D_Skybox()
+{
+  static bool initialized = false,
+              initialization_failed = false;
+  if (initialization_failed)
+    return false;
+  
+  static int last_camera_rot_y,
+             last_camera_rot_x;
+  if (!initialized)
+  {
+    if (!Skybox_Initialize(L"data/skybox/stars"))
+    {
+      initialization_failed = true;
+      return false;
+    }
+    initialized = true;
+
+    last_camera_rot_y = pParty->sRotationY + 1; // force update for the first run 
+    last_camera_rot_x = pParty->sRotationX + 1;
+  }
+
+  /*
+  r(y) = 
+cos y	0	sin y	0
+0	1	0	0
+-sin y	0	cos y	0
+0	0	0	1
+
+x cos y - z sin y
+y
+x sin y + z cos y
+1
+
+
+
+r(x) =     // should be r(right) actually
+1	0      	0	0
+0	cos x	-sin x	0
+0	sin x	cos x	0
+0	0	    0	1
+
+
+x
+y cos x + z sin x
+-y sin x + z cos x
+1
+
+  */
+
+  if (last_camera_rot_y == pParty->sRotationY &&
+      last_camera_rot_x == pParty->sRotationX)
+  {
+draw:
+    struct RenderVertexD3D3  v[6];
+
+    v[0].pos.x = pViewport->uScreenX;
+    v[0].pos.y = pViewport->uScreenY;
+    v[0].pos.z = 0.99989998;
+    v[0].rhw = 1;
+    v[0].diffuse = 0xFFFFFFFF;
+    v[0].specular = 0;
+    v[0].texcoord.x = 0;
+    v[0].texcoord.y = 0;
+    
+    v[1].pos.x = pViewport->uScreenX + pViewport->uScreenWidth;
+    v[1].pos.y = pViewport->uScreenY + pViewport->uScreenHeight;
+    v[1].pos.z = 0.99989998;
+    v[1].rhw = 1;
+    v[1].diffuse = 0xFFFFFFFF;
+    v[1].specular = 0;
+    v[1].texcoord.x = (float)pViewport->uScreenWidth / skybox_width;
+    v[1].texcoord.y = (float)pViewport->uScreenHeight / skybox_height;
+
+    v[2].pos.x = pViewport->uScreenX + pViewport->uScreenWidth;
+    v[2].pos.y = pViewport->uScreenY;
+    v[2].pos.z = 0.99989998;
+    v[2].rhw = 1;
+    v[2].diffuse = 0xFFFFFFFF;
+    v[2].specular = 0;
+    v[2].texcoord.x = (float)pViewport->uScreenWidth / skybox_width;
+    v[2].texcoord.y = 0;
+
+    memcpy(&v[3], &v[0], sizeof(*v));
+
+    v[4].pos.x = pViewport->uScreenX;
+    v[4].pos.y = pViewport->uScreenY + pViewport->uScreenHeight;
+    v[4].pos.z = 0.99989998;
+    v[4].rhw = 1;
+    v[4].diffuse = 0xFFFFFFFF;
+    v[4].specular = 0;
+    v[4].texcoord.x = 0;
+    v[4].texcoord.y = (float)pViewport->uScreenHeight / skybox_height;
+
+    memcpy(&v[5], &v[1], sizeof(*v));
+
+    pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
+    pRenderer->pRenderD3D->pDevice->SetTexture(0, skybox_texture);
+    pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v, 6, D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTLIGHT);
+    //pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v + 1, 3, D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTLIGHT);
+
+    return true;
+  }
+
+
+  DDSURFACEDESC2 desc;
+  desc.dwSize = sizeof(desc);
+  if (!pRenderer->LockSurface_DDraw4(skybox_surface, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY))
+    return false;
+  
+  last_camera_rot_y = pParty->sRotationY;
+  last_camera_rot_x = pParty->sRotationX;
+
+  float aspect = (float)pViewport->uScreenWidth / (float)pViewport->uScreenHeight;
+  float fov_x = 3.141592f * (pOutdoorCamera->uCameraFovInDegrees + 0) / 360.0f;
+  float fov_y = fov_x / aspect;
+
+  float ray_dx = fov_x / (float)pViewport->uScreenWidth,
+        ray_dy = fov_y / (float)pViewport->uScreenHeight;
+  float party_angle_x = 2 * 3.141592653589 * pParty->sRotationX / 2048.0,
+        party_angle_y = 2 * 3.141592653589 * pParty->sRotationY / 2048.0;
+  for (int y = 0; y < pViewport->uScreenHeight; ++y)
+    for (int x = 0; x < pViewport->uScreenWidth; ++x)
+    {
+      float angle_x = party_angle_x - (y - pViewport->uScreenHeight / 2) * ray_dy;
+      float angle_y = party_angle_y - (x - pViewport->uScreenWidth / 2) * ray_dx;
+
+      float _dir_x_ = 1,
+            _dir_y_ = 0,
+            _dir_z_ = 0;
+
+      float dir_x_ = _dir_x_ * cosf(angle_y);// - _dir_z_ * sinf(angle_y);  // rotation around y
+      //float dir_y_ = _dir_y_;
+      float dir_z_ = _dir_x_ * sinf(angle_y);// + _dir_z_ * cosf(angle_y);
+
+      //float dir_x =  dir_x_;                                               // rotation around x
+      //float dir_y =  /*dir_y_ * cosf(angle_x)*/ + dir_z_ * sinf(angle_x);
+      //float dir_z = /*-dir_y_ * sinf(angle_x)*/ + dir_z_ * cosf(angle_x);
+
+      vector right;                                            // rotate around right actually to avoid space distortion
+      right.x = /*dir_y * 0*/ - dir_z_ * 1;
+      right.y = /*dir_z_ * 0 - dir_x_ * */0;
+      right.z = dir_x_ * 1/* - dir_y_ * 0*/;
+      //VectorNormalize(&right);
+
+      matrix rightMatrix;
+      MatrixRotationAxis(&rightMatrix, &right, angle_x);
+
+      vector v1, v2;
+      v1.x = dir_x_; v1.y = 0; v1.z = dir_z_;
+      VectorTransform(&rightMatrix, &v1, &v2);
+
+      float dir_x = v2.x,
+            dir_y = v2.y,
+            dir_z = v2.z;
+
+      float abs_dir_x = fabsf(dir_x),
+            abs_dir_y = fabsf(dir_y),
+            abs_dir_z = fabsf(dir_z);
+
+      unsigned short color = (0x1F << 11) | (0x1F << 5) | (5);  //default to orange
+      if (abs_dir_x >= abs_dir_y)
+      {
+        if (abs_dir_x >= abs_dir_z)
+        {
+          if (dir_x >= 0)
+          {
+            float instersect_y = dir_y / (2.0f * dir_x); // plane equation for this side is x + 0.5 = 0
+            float instersect_z = dir_z / (2.0f * dir_x);
+
+            float u = 1.0f - (instersect_z + 0.5f),
+                  v = 1.0f - (instersect_y + 0.5f);
+            
+            int tx = u * (skybox_width - 1),
+                ty = v * (skybox_height - 1);
+
+            color = skybox_xp[ty * skybox_width + tx];
+            //color = ty * 0x1F / skybox_height;
+          }
+          else
+          {
+            float instersect_y = dir_y / (2.0f * dir_x);
+            float instersect_z = dir_z / (2.0f * dir_x);
+
+            float u = 1.0f - (instersect_z + 0.5f),
+                  v = instersect_y + 0.5f;
+            
+            int tx = u * (skybox_width - 1),
+                ty = v * (skybox_height - 1);
+
+            color = skybox_xn[ty * skybox_width + tx];
+            //color = tx * 0x1F / skybox_height;
+          }
+        }
+        else if (dir_z >= 0)
+          goto DIR_ZP;
+        else
+          goto DIR_ZN;
+      }
+      else if (abs_dir_y >= abs_dir_z)
+      {
+        if (dir_y >= 0)
+        {
+            float instersect_x = dir_x / (2.0f * dir_y);
+            float instersect_z = dir_z / (2.0f * dir_y);
+
+            float u = instersect_x + 0.5f,
+                  v = instersect_z + 0.5f;
+            
+            int tx = u * (skybox_width - 1),
+                ty = v * (skybox_height - 1);
+
+            color = skybox_yp[ty * skybox_width + tx];
+            //color = tx * 0x1F / skybox_height;
+        }
+        /*else   should never be seen i guess
+        {
+            __debugbreak();
+          // -y
+            //Log::Warning(L"(%03u, %03u): -y", x, y);
+        }*/
+      }
+      else if (dir_z >= 0)
+      {
+DIR_ZP:
+        // +z
+        float instersect_x = dir_x / (2.0f * dir_z);
+        float instersect_y = dir_y / (2.0f * dir_z);
+        //float intersect_z = 0.5f;
+
+        float u = instersect_x + 0.5f,
+              v = -instersect_y + 0.5f;
+
+        int tx = u * (skybox_width - 1),
+            ty = v * (skybox_height - 1);
+
+        color = skybox_zp[ty * skybox_width + tx];
+      }
+      else
+      {
+DIR_ZN:
+        // -z
+        float instersect_x = -dir_x / (2.0f * dir_z);
+        float instersect_y = -dir_y / (2.0f * dir_z);
+        //float intersect_z = -0.5f;
+
+        float u = 1.0f - instersect_x - 0.5f,
+              v = -instersect_y + 0.5f;
+
+        int tx = u * (skybox_width - 1),
+            ty = v * (skybox_height - 1);
+
+        color = skybox_zn[ty * skybox_width + tx];
+      }
+
+      //pRenderer->pTargetSurface[(pViewport->uScreenY + y) * pRenderer->uTargetSurfacePitch + pViewport->uScreenX + x] = color;
+      ((unsigned __int16 *)((char *)desc.lpSurface + y * desc.lPitch))[x] = color;
+    }
+    
+  ErrD3D((skybox_surface)->Unlock(0));
+  goto draw;
+}
+
 //----- (00479543) --------------------------------------------------------
 void Render::DrawSkyD3D()
 {
@@ -7767,6 +8239,13 @@
   int v38; // [sp+158h] [bp-Ch]@1
   int v39; // [sp+15Ch] [bp-8h]@4
   int v40; // [sp+160h] [bp-4h]@7
+  
+  extern bool new_sky;
+  if (new_sky)
+  {
+    if (DrawSkyD3D_Skybox())
+    return;
+  }
 
   v30 = ((double)(pOutdoorCamera->int_fov_rad * pIndoorCamera->pos.z)
         / ((double)pOutdoorCamera->int_fov_rad + 8192.0) + pViewport->uScreenCenterY);
@@ -7776,9 +8255,10 @@
   _this._48607B(&stru_8019C8);
   _this.ptr_38->_48694B();
   _this.uTileBitmapID = pOutdoor->uSky_TextureID;
-  _this.pTexture = (Texture *)(SLOWORD(pOutdoor->uSky_TextureID) != -1 ? (int)&pBitmaps_LOD->pTextures[SLOWORD(pOutdoor->uSky_TextureID)] : 0);
+  _this.pTexture = (Texture *)(SLOWORD(pOutdoor->uSky_TextureID) != -1 ? &pBitmaps_LOD->pTextures[SLOWORD(pOutdoor->uSky_TextureID)] : 0);
   if (pOutdoor->uSky_TextureID == -1)
     return;
+
   _this.field_58 = 0;
   _this.uNumVertices = 4;
   _this.v_18.x = -stru_5C6E00->SinCos(pIndoorCamera->sRotationX - stru_5C6E00->uIntegerHalfPi + 16);
@@ -7863,7 +8343,7 @@
       v36 = 224 * pMiscTimer->uTotalGameTimeElapsed + (signed int)((unsigned __int64)(v36 * v18) >> 16) / 8;
 
       array_50AC10[i].vWorldViewPosition.x = pOutdoorCamera->shading_dist_mist;
-      array_50AC10[i].flt_20 = 1.0 / (double)(v17 / 65536);
+      array_50AC10[i]._rhw = 1.0 / (double)(v17 / 65536);
       array_50AC10[i].u = (double)v35 / (65536.0 * pBitmaps_LOD->pTextures[pOutdoor->uSky_TextureID].uTextureWidth);
       array_50AC10[i].v = (double)v36 / (65536.0 * pBitmaps_LOD->pTextures[pOutdoor->uSky_TextureID].uTextureWidth);
     }
@@ -7871,22 +8351,22 @@
      float t = (GetTickCount() % 96000) / 96000.0f;
 
  array_50AC10[0].vWorldViewPosition.x = pOutdoorCamera->shading_dist_mist;
- array_50AC10[0].flt_20 = 1;
+ array_50AC10[0]._rhw = 1;
  array_50AC10[0].u = 0;
  array_50AC10[0].v = 0 + t;
 
  array_50AC10[1].vWorldViewPosition.x = pOutdoorCamera->shading_dist_mist;
- array_50AC10[1].flt_20 = 1;
+ array_50AC10[1]._rhw = 1;
  array_50AC10[1].u = 0;
  array_50AC10[1].v = 1 + t;
  
  array_50AC10[2].vWorldViewPosition.x = pOutdoorCamera->shading_dist_mist;
- array_50AC10[2].flt_20 = 1;
+ array_50AC10[2]._rhw = 1;
  array_50AC10[2].u = 1;
  array_50AC10[2].v = 0 + t;
 
  array_50AC10[3].vWorldViewPosition.x = pOutdoorCamera->shading_dist_mist;
- array_50AC10[3].flt_20 = 1;
+ array_50AC10[3]._rhw = 1;
  array_50AC10[3].u = 1;
  array_50AC10[3].v = 1 + t;
  pRenderer->DrawStrip(_this.uNumVertices, &_this,
@@ -9294,7 +9774,7 @@
     v5 = uNumVertices;
     do
     {
-      v6 = v1 * array_507D30[v4].flt_20;
+      v6 = v1 * array_507D30[v4]._rhw;
       v7 = v6 * array_507D30[v4].vWorldViewPosition.y;
       memcpy(&array_50AC10[v4], &array_507D30[v4], sizeof(array_50AC10[v4]));
       array_50AC10[v4].vWorldViewProjX = v2 - v7;
@@ -18512,7 +18992,7 @@
   double v2; // st7@1
 
   v1 = 1.0 / (v->vWorldViewPosition.x + 0.0000001);
-  v->flt_20 = v1;
+  v->_rhw = v1;
   v2 = v1 * (double)pOutdoorCamera->int_fov_rad;
   v->vWorldViewProjX = (double)pViewport->uScreenCenterX - v2 * v->vWorldViewPosition.y;
   v->vWorldViewProjY = (double)pViewport->uScreenCenterY - v2 * v->vWorldViewPosition.z;