diff ParticleEngine.cpp @ 45:bcc051713d20

BLV render & seffects
author Nomad
date Mon, 22 Oct 2012 20:45:14 +0200
parents 8b8875f5b359
children 5159d2e6f559
line wrap: on
line diff
--- a/ParticleEngine.cpp	Sun Oct 21 23:26:23 2012 +0600
+++ b/ParticleEngine.cpp	Mon Oct 22 20:45:14 2012 +0200
@@ -7,7 +7,6 @@
 #include "IndoorCamera.h"
 #include "Math.h"
 #include "LOD.h"
-#include "stru346.h"
 
 #include "mm7_data.h"
 
@@ -44,7 +43,7 @@
     v3 = (Particle *)this;
     do
     {
-      if ( !v3->bFree )
+      if ( !v3->uType )
         break;
       ++v2;
       ++v3;
@@ -57,7 +56,7 @@
       if ( v2 > this->uEndParticle )
         this->uEndParticle = v2;
       v4 = &this->pParticles[v2];
-      v4->bFree = a2->bFree;
+      v4->uType = a2->bFree;
       v4->x = a2->x;
       v4->y = a2->y;
       v4->z = a2->z;
@@ -70,8 +69,8 @@
       v5 = a2->uDiffuse;
       v4->uParticleColor = v5;
       v4->uLightColor = v5;
-      v6 = (v4->bFree & 4) == 0;
-      v4->field_20 = a2->field_20;
+      v6 = (v4->uType & 4) == 0;
+      v4->timeToLive = a2->timeToLive;
       v4->uTextureID = a2->uTextureID;
       v4->flt_28 = a2->flt_28;
       if ( v6 )
@@ -91,128 +90,100 @@
 //----- (0048ABF3) --------------------------------------------------------
 void ParticleEngine::Draw()
 {
-  ParticleEngine *v1; // esi@1
+  uTimeElapsed += pEventTimer->uTimeElapsed;
+  pLines.uNumLines = 0;
 
-  v1 = this;
-  v1->uTimeElapsed += pEventTimer->uTimeElapsed;
-  this->pLines.uNumLines = 0;
-  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
+  if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
     DrawParticles_BLV();
   else
     DrawParticles_ODM();
-  if ( pRenderer->pRenderD3D )
+
+  if (pRenderer->pRenderD3D)
   {
-    if ( v1->pLines.uNumLines )
+    if (pLines.uNumLines)
     {
       pRenderer->pRenderD3D->pDevice->SetTexture(0, 0);
       pRenderer->pRenderD3D->pDevice->DrawPrimitive(
         D3DPT_LINELIST,
-        452,
-        v1->pLines.pLineVertices,
-        v1->pLines.uNumLines,
-        16);
+        D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
+        pLines.pLineVertices,
+        pLines.uNumLines,
+        D3DDP_DONOTLIGHT);
     }
   }
 }
 
 //----- (0048AC65) --------------------------------------------------------
-int ParticleEngine::UpdateParticles()
+void ParticleEngine::UpdateParticles()
 {
-  ParticleEngine *v1; // ebx@1
   unsigned int time; // edi@1
-  int v3; // eax@1
-  int v4; // esi@2
   int v5; // eax@3
   char v6; // sf@4
   float v7; // ST4C_4@11
   double v8; // st7@12
   int v9; // eax@12
   double v10; // st7@14
-  float v11; // ST4C_4@14
-  float v12; // ST3C_4@14
-  double v13; // ST20_8@14
-  float v14; // ST3C_4@14
-  double v15; // ST18_8@14
-  float v16; // ST3C_4@14
-  double v17; // ST10_8@14
-  signed int result; // eax@19
   signed int v19; // [sp+38h] [bp-14h]@1
   int v20; // [sp+3Ch] [bp-10h]@1
   unsigned int time_; // [sp+40h] [bp-Ch]@1
   int v22; // [sp+44h] [bp-8h]@12
-  int v23; // [sp+48h] [bp-4h]@1
 
   v20 = 0;
-  v1 = this;
   time = pMiscTimer->bPaused == 0 ? pEventTimer->uTimeElapsed : 0;
-  v3 = this->uStartParticle;
   v19 = 500;
   time_ = pMiscTimer->bPaused == 0 ? pEventTimer->uTimeElapsed : 0;
-  v23 = this->uStartParticle;
-  if ( v3 <= this->uEndParticle )
+
+  for (uint i = uStartParticle; i < uEndParticle; ++i)
   {
-    v4 = (int)((char *)&this->pParticles[v3].uParticleColor + 1);
-    do
-    {
-      v5 = *(int *)(v4 - 0x1D);
-      if ( v5 )
-      {
-        v6 = ((*(int *)(v4 + 3) - time) & 0x80000000u) != 0;
-        *(int *)(v4 + 3) -= time;
-        if ( v6 )
-        {
-          *(int *)(v4 - 0x1D) = 0;
-        }
+    auto p = pParticles + i;
+
+      v5 = p->uType;
+      if (!p->uType)
+        continue;
+
+        v6 = (p->timeToLive - time) < 0;
+        p->timeToLive -= time;
+        if (v6)
+          p->uType = 0;
         else
         {
           if ( BYTE1(v5) & 2 )
           {
-            *(int *)(v4 + 15) = *(int *)(v4 - 25);
-            *(int *)(v4 + 19) = *(int *)(v4 - 21);
-            *(int *)(v4 + 23) = *(int *)(v4 - 17);
+            p->_x = p->x;
+            p->_y = p->y;
+            p->_z = p->z;
           }
           if ( v5 & 1 )
-            *(float *)(v4 - 5) = *(float *)(v4 - 5) - (double)(signed int)time_ * 5.0;
+            p->flt_18 = p->flt_18 - (double)(signed int)time_ * 5.0;
           if ( v5 & 8 )
           {
             v7 = (double)(signed int)time_;
-            *(float *)(v4 - 25) = (double)(rand() % 5 - 2) * v7 * 0.0625 + *(float *)(v4 - 25);
-            *(float *)(v4 - 21) = (double)(rand() % 5 - 2) * v7 * 0.0625 + *(float *)(v4 - 21);
-            *(float *)(v4 - 17) = (double)(rand() % 5 + 4) * v7 * 0.0625 + *(float *)(v4 - 17);
+            *(float *)&p->x += (double)(rand() % 5 - 2) * v7 / 16.0f;
+            *(float *)&p->y += (double)(rand() % 5 - 2) * v7 / 16.0f;
+            *(float *)&p->z += (double)(rand() % 5 + 4) * v7 / 16.0f;
           }
-          v8 = (double)(signed int)time_ * 0.0078125;
-          v9 = (signed int)(time * *(int *)(v4 + 27)) / 16;
-          *(float *)(v4 - 25) = v8 * *(float *)(v4 - 13) + *(float *)(v4 - 25);
-          *(float *)(v4 - 21) = v8 * *(float *)(v4 - 9) + *(float *)(v4 - 21);
-          *(float *)(v4 - 17) = v8 * *(float *)(v4 - 5) + *(float *)(v4 - 17);
-          *(int *)(v4 + 31) += v9;
-          v22 = 2 * *(int *)(v4 + 3);
-          if ( 2 * *(int *)(v4 + 3) >= 255 )
+          v8 = (double)(signed int)time_ / 128.0f;
+          v9 = (signed int)(time * p->field_38) / 16;
+          *(float *)&p->x += v8 * p->flt_10;
+          *(float *)&p->y += v8 * p->flt_14;
+          *(float *)&p->z += v8 * p->flt_18;
+          p->_rotation += v9;
+          v22 = 2 * p->timeToLive;
+          if ( 2 * p->timeToLive >= 255 )
             v22 = 255;
           v10 = (double)v22 * 0.0039215689;
-          v11 = v10;
-          v12 = (double)*(char *)(v4 + 1) * v10;
-          v13 = v12 + 6.7553994e15;
-          v14 = (double)*(char *)v4 * v11;
-          v15 = v14 + 6.7553994e15;
-          v16 = (double)(*(int *)(v4 - 1) & 0xFF) * v11;
-          v17 = v16 + 6.7553994e15;
-          *(int *)(v4 + 71) = LODWORD(v17) | ((LODWORD(v15) | (LODWORD(v13) << 8)) << 8);
-          if ( v23 < v19 )
-            v19 = v23;
-          if ( v23 > v20 )
-            v20 = v23;
+          p->uLightColor = (uint)floorf(p->b + 0.5) |
+                           ((uint)floorf(p->g + 0.5) << 8) |
+                           ((uint)floorf(p->r + 0.5) << 16);
+          if ( i < v19 )
+            v19 = i;
+          if ( i > v20 )
+            v20 = i;
         }
-      }
-      ++v23;
-      v4 += 104;
-    }
-    while ( v23 <= v1->uEndParticle );
   }
-  v1->uEndParticle = v20;
-  result = v19;
-  v1->uStartParticle = v19;
-  return result;
+
+  uEndParticle = v20;
+  uStartParticle = v19;
 }
 
 //----- (0048AE74) --------------------------------------------------------
@@ -275,7 +246,7 @@
   int y; // [sp+4Ch] [bp-4h]@3
 
   pParticle = &this->pParticles[uParticleID];
-  if ( !pParticle->bFree )
+  if ( !pParticle->uType )
     return 0;
   uParticleID = LODWORD(pParticle->x);
   v56 = *(float *)&uParticleID + 6.7553994e15;
@@ -288,7 +259,7 @@
   {
     if ( pBLVRenderParams->sPartyRotX )
     {
-      if ( BYTE1(pParticle->bFree) & 2 )
+      if ( BYTE1(pParticle->uType) & 2 )
       {
         v11 = pParticle->_x + 6.7553994e15;
         uParticleID = (LODWORD(v11) - pBLVRenderParams->vPartyPos.x) << 16;
@@ -314,12 +285,12 @@
         LODWORD(v18) = pBLVRenderParams->uViewportCenterX
                      - ((signed int)((unsigned __int64)(v16 * (signed __int64)(a6 + v17)) >> 16) >> 16);
         v19 = pParticle->field_58;
-        pParticle->field_48 = v18;
+        pParticle->uScreenSpaceZ = v18;
         uParticleID = (unsigned __int64)(v19 * (signed __int64)(HIDWORD(v13) + HIDWORD(a5))) >> 16;
         v20 = pBLVRenderParams->uViewportCenterY
             - ((signed int)((unsigned __int64)(v19 * (signed __int64)(HIDWORD(v13) + HIDWORD(a5))) >> 16) >> 16);
-        pParticle->field_54 = v14;
-        pParticle->field_4C = v20;
+        pParticle->sZValue2 = v14;
+        pParticle->uScreenSpaceW = v20;
       }
       uParticleID = (x_int - pBLVRenderParams->vPartyPos.x) << 16;
       y = (LODWORD(y_int_) - pBLVRenderParams->vPartyPos.y) << 16;
@@ -340,7 +311,7 @@
     }
     else
     {
-      if ( BYTE1(pParticle->bFree) & 2 )
+      if ( BYTE1(pParticle->uType) & 2 )
       {
         v25 = pParticle->_x + 6.7553994e15;
         uParticleID = (LODWORD(v25) - pBLVRenderParams->vPartyPos.x) << 16;
@@ -363,11 +334,11 @@
         LODWORD(v33) = pBLVRenderParams->uViewportCenterX
                      - ((signed int)((unsigned __int64)(v31 * (signed __int64)(v28 + v32)) >> 16) >> 16);
         v34 = pParticle->field_58;
-        pParticle->field_48 = v33;
+        pParticle->uScreenSpaceZ = v33;
         v35 = pBLVRenderParams->uViewportCenterY
             - ((signed int)((unsigned __int64)(v34 * (signed __int64)v29) >> 16) >> 16);
-        pParticle->field_54 = v27;
-        pParticle->field_4C = v35;
+        pParticle->sZValue2 = v27;
+        pParticle->uScreenSpaceW = v35;
       }
       uParticleID = (x_int - pBLVRenderParams->vPartyPos.x) << 16;
       y = (LODWORD(y_int_) - pBLVRenderParams->vPartyPos.y) << 16;
@@ -433,7 +404,7 @@
   pParticle->field_58 = (unsigned __int64)(_48B561_mess_with_scaling_along_z(/*v9, */v8) * (signed __int64)pParticle->field_58) >> 16;
   v10 = uParticleID;
 LABEL_19:
-  pParticle->field_50 = v10;
+  pParticle->sZValue = v10;
   return 1;
 }
 
@@ -502,7 +473,7 @@
   v4 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY);
   v5 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY - stru_5C6E00->uIntegerHalfPi);
   v6 = &v2->pParticles[uID];
-  if ( v6->bFree )
+  if ( v6->uType )
   {
     v7 = v6->x + 6.7553994e15;
     v41 = LODWORD(v7);
@@ -510,7 +481,7 @@
     v42 = v6->z + 6.7553994e15;
     if ( v3 )
     {
-      if ( BYTE1(v6->bFree) & 2 )
+      if ( BYTE1(v6->uType) & 2 )
       {
         v8 = v6->_x + 6.7553994e15;
         uIDc = (LODWORD(v8) - pIndoorCamera->pos.x) << 16;
@@ -536,7 +507,7 @@
                           - ((signed int)((unsigned __int64)(v15
                                                            * (signed __int64)(signed int)(((unsigned __int64)(uIDd * (signed __int64)v3) >> 16)
                                                                                         - ((unsigned __int64)(v11 * (signed __int64)v44) >> 16))) >> 16) >> 16);
-        v6->field_50 = HIDWORD(v12);
+        v6->sZValue = HIDWORD(v12);
       }
       uIDe = (v41 - pIndoorCamera->pos.x) << 16;
       v47 = (LODWORD(v39) - pIndoorCamera->pos.y) << 16;
@@ -553,7 +524,7 @@
     }
     else
     {
-      if ( BYTE1(v6->bFree) & 2 )
+      if ( BYTE1(v6->uType) & 2 )
       {
         v18 = v6->_x + 6.7553994e15;
         uIDf = (LODWORD(v18) - pIndoorCamera->pos.x) << 16;
@@ -573,7 +544,7 @@
                                                                                         - ((unsigned __int64)(uIDf * (signed __int64)v5) >> 16))) >> 16) >> 16);
         v25 = pViewport->uScreenCenterY
             - ((signed int)((unsigned __int64)(v24 * (signed __int64)SLODWORD(v21)) >> 16) >> 16);
-        v6->field_50 = ((unsigned __int64)(v20 * (signed __int64)v5) >> 16)
+        v6->sZValue = ((unsigned __int64)(v20 * (signed __int64)v5) >> 16)
                      + ((unsigned __int64)(uIDf * (signed __int64)v4) >> 16);
         v6->uScreenSpaceY = v25;
       }
@@ -604,7 +575,7 @@
       v6->uScreenSpaceY = pViewport->uScreenCenterY - v33;
       v35 = v32;
       v6->field_58 = (unsigned __int64)(_48B561_mess_with_scaling_along_z(/*v34, */v35) * (signed __int64)v6->field_58) >> 16;
-      v6->field_50 = X_4;
+      v6->sZValue = X_4;
       v36 = v6->uScreenSpaceX;
       if ( v36 >= (signed int)pViewport->uViewportX )
       {
@@ -626,152 +597,110 @@
 //----- (0048BBA6) --------------------------------------------------------
 void ParticleEngine::DrawParticles_BLV()
 {
-  ParticleEngine *v1; // esi@1
-  int v2; // eax@1
-  unsigned __int8 v3; // zf@1
-  char v4; // sf@1
-  unsigned __int8 v5; // of@1
-  Render *v6; // ebx@2
-  char *v7; // edi@2
-  signed int v8; // ecx@7
-  int v9; // eax@10
-  signed int v10; // eax@12
   int v11; // eax@18
   int v12; // ecx@20
   int v13; // edx@20
   Particle *v14; // eax@28
   RenderBillboardTransform_local0 v15; // [sp+Ch] [bp-58h]@1
-  int v16; // [sp+5Ch] [bp-8h]@5
-  int v17; // [sp+60h] [bp-4h]@1
 
   v15.uParentBillboardID = -1;
-  v1 = this;
-  v2 = this->uStartParticle;
-  v5 = __OFSUB__(v2, this->uEndParticle);
-  v3 = v2 == this->uEndParticle;
-  v4 = v2 - this->uEndParticle < 0;
-  v17 = this->uStartParticle;
-  if ( (unsigned __int8)(v4 ^ v5) | v3 )
+
+  for (uint i = uStartParticle; i < uEndParticle; ++i)
   {
-    v6 = pRenderer;
-    v7 = (char *)&this->pParticles[v2].field_54 + 2;
-    do
+    auto p = pParticles + i;
+
+    if (!p->uType)
+      continue;
+
+    if (!ViewProject_TrueIfStillVisible(i))
+      continue;
+
+    if (p->uScreenSpaceX >= pBLVRenderParams->uViewportX &&
+        p->uScreenSpaceX < pBLVRenderParams->uViewportZ &&
+        p->uScreenSpaceY >= pBLVRenderParams->uViewportY &&
+        p->uScreenSpaceY < pBLVRenderParams->uViewportW)
     {
-      if ( *(int *)(v7 - 86) )
+      if (pRenderer->pRenderD3D)
       {
-        if ( v1->ViewProject_TrueIfStillVisible(v2) )
+        if (p->uType & 0x0100)
         {
-          v16 = *(int *)(v7 - 22);
-          if ( v16 >= (signed int)pBLVRenderParams->uViewportX )
+          v14 = &pParticles[i];
+          v15.field_10 = v14->field_58 / 4;
+          v15.field_14 = v14->field_58 / 4;
+          v15.uScreenSpaceX = v14->uScreenSpaceX;
+          v15.uScreenSpaceY = v14->uScreenSpaceY;
+          v15.sZValue = v14->sZValue;
+          pRenderer->MakeParticleBillboardAndPush_BLV(&v15, 0, v14->uLightColor, v14->_rotation);
+          return;
+        }
+        if (p->uType & 0x0200)
+        {
+          if (pLines.uNumLines < 100)
           {
-            if ( v16 < (signed int)pBLVRenderParams->uViewportZ )
-            {
-              v8 = *(int *)(v7 - 18);
-              if ( v8 >= (signed int)pBLVRenderParams->uViewportY )
-              {
-                if ( v8 < (signed int)pBLVRenderParams->uViewportW )
-                {
-                  if ( pRenderer->pRenderD3D )
-                  {
-                    v9 = *(int *)(v7 - 86);
-                    if ( BYTE1(v9) & 1 )
-                    {
-                      v14 = &v1->pParticles[v17];
-                      v15.field_10 = v14->field_58 >> 2;
-                      v15.field_14 = v14->field_58 >> 2;
-                      v15.field_8 = v14->uScreenSpaceX;
-                      v15.field_C = v14->uScreenSpaceY;
-                      v15.field_28 = v14->field_50;
-                      pRenderer->MakeParticleBillboardAndPush_BLV(&v15, 0, v14->uLightColor, v14->_rotation);
-                      return;
-                    }
-                    if ( BYTE1(v9) & 2 )
-                    {
-                      v10 = v1->pLines.uNumLines;
-                      if ( v10 < 100 )
-                      {
-                        v1->pLines.pLineVertices[2 * v10].pos.x = (double)v16;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].pos.y = (double)*(signed int *)(v7 - 18);
-                        v16 = *((short *)v7 - 2);
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].pos.z = 1.0
-                                                                                 - 1.0 / ((double)v16 * 0.061758894);
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].rhw = 1.0;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].diffuse = *(int *)(v7 + 14);
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].specular = 0;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].texcoord.x = 0.0;
-                        *((float *)&v1->pParticles[0].bFree + 16 * (v1->pLines.uNumLines + 813)) = 0.0;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].pos.x = (double)*(signed int *)(v7 - 14);
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].pos.y = (double)*(signed int *)(v7 - 10);
-                        v16 = *(short *)v7;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].pos.z = 1.0
-                                                                                     - 1.0 / ((double)v16 * 0.061758894);
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].rhw = 1.0;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].diffuse = *(int *)(v7 + 14);
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].specular = 0;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].texcoord.x = 0.0;
-                        v1->pLines.pLineVertices[2 * v1->pLines.uNumLines++ + 1].texcoord.y = 0.0;
-                      }
-                    }
-                    if ( *(v7 - 85) & 4 )
-                    {
-                      v15.field_10 = *(int *)(v7 + 2);
-                      v15.field_14 = *(int *)(v7 + 2);
-                      v15.field_8 = *(int *)(v7 - 22);
-                      v15.field_C = *(int *)(v7 - 18);
-                      v15.field_28 = *(int *)(v7 - 6);
-                      pRenderer->MakeParticleBillboardAndPush_BLV(
-                        &v15,
-                        pBitmaps_LOD->pHardwareTextures[*(int *)(v7 - 50)],
-                        *(int *)(v7 + 14),
-                        *(int *)(v7 - 26));
-                    }
-                    if ( *(v7 - 85) & 8 )
-                    {
-                      v15.field_10 = *(int *)(v7 + 2);
-                      v15.field_14 = *(int *)(v7 + 2);
-                      v15.field_8 = *(int *)(v7 - 22);
-                      v15.field_C = *(int *)(v7 - 18);
-                      v15.field_28 = *(int *)(v7 - 6);
-                      pRenderer->MakeParticleBillboardAndPush_BLV(
-                        &v15,
-                        pSprites_LOD->pHardwareSprites[*(int *)(v7 - 50)].pTexture,
-                        *(int *)(v7 + 14),
-                        *(int *)(v7 - 26));
-                    }
-                  }
-                  else
-                  {
-                    v11 = 13 * *(int *)(v7 + 2) >> 16;
-                    if ( v11 > 30 )
-                      v11 = 30;
-                    v12 = v8 - v11;
-                    v13 = v16 - (v11 >> 1);
-                    if ( v13 + v11 < (signed int)pViewport->uViewportX
-                      || v13 >= (signed int)pViewport->uViewportZ
-                      || v12 + v11 < (signed int)pViewport->uViewportY
-                      || v12 >= (signed int)pViewport->uViewportW )
-                    {
-                      v6 = pRenderer;
-                    }
-                    else
-                    {
-                      v6 = pRenderer;
-                      pRenderer->_4A48E4(v13, v12, *(int *)(v7 - 6), *(int *)(v7 + 14), v11);
-                    }
-                  }
-                }
-              }
-            }
+            pLines.pLineVertices[2 * pLines.uNumLines].pos.x = p->uScreenSpaceX;
+            pLines.pLineVertices[2 * pLines.uNumLines].pos.y = p->uScreenSpaceY;
+            pLines.pLineVertices[2 * pLines.uNumLines].pos.z = 1.0 - 1.0 / ((short)p->sZValue * 0.061758894);
+            pLines.pLineVertices[2 * pLines.uNumLines].rhw = 1.0;
+            pLines.pLineVertices[2 * pLines.uNumLines].diffuse = p->uLightColor;
+            pLines.pLineVertices[2 * pLines.uNumLines].specular = 0;
+            pLines.pLineVertices[2 * pLines.uNumLines].texcoord.x = 0.0;
+            pLines.pLineVertices[2 * pLines.uNumLines].texcoord.y = 0.0;
+
+            pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.x = p->uScreenSpaceZ;
+            pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.y = p->uScreenSpaceW;
+            pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.z = 1.0 - 1.0 / ((short)p->sZValue2 * 0.061758894);
+            pLines.pLineVertices[2 * pLines.uNumLines + 1].rhw = 1.0;
+            pLines.pLineVertices[2 * pLines.uNumLines + 1].diffuse = p->uLightColor;
+            pLines.pLineVertices[2 * pLines.uNumLines + 1].specular = 0;
+            pLines.pLineVertices[2 * pLines.uNumLines + 1].texcoord.x = 0.0;
+            pLines.pLineVertices[2 * pLines.uNumLines++ + 1].texcoord.y = 0.0;
           }
         }
+        if (p->uType & 0x0400)
+        {
+          v15.field_10 = p->field_58;
+          v15.field_14 = p->field_58;
+          v15.uScreenSpaceX = p->uScreenSpaceX;
+          v15.uScreenSpaceY = p->uScreenSpaceY;
+          v15.sZValue = p->sZValue;
+          pRenderer->MakeParticleBillboardAndPush_BLV(&v15,
+                        pBitmaps_LOD->pHardwareTextures[p->uTextureID],
+                        v14->uLightColor,
+                        p->_rotation);
+        }
+        if (p->uType & 0x0800)
+        {
+          v15.field_10 = p->field_58;
+          v15.field_14 = p->field_58;
+          v15.uScreenSpaceX = p->uScreenSpaceX;
+          v15.uScreenSpaceY = p->uScreenSpaceY;
+          v15.sZValue = p->sZValue;
+          pRenderer->MakeParticleBillboardAndPush_BLV(&v15,
+                        pSprites_LOD->pHardwareSprites[p->uTextureID].pTexture,
+                        v14->uLightColor,
+                        p->_rotation);
+        }
       }
-      v7 += 104;
-      v2 = v17 + 1;
-      v5 = __OFSUB__(v17 + 1, v1->uEndParticle);
-      v3 = v17 + 1 == v1->uEndParticle;
-      v4 = v17++ + 1 - v1->uEndParticle < 0;
+      else
+      {
+                    v11 = 13 * p->field_58 >> 16;
+                     if ( v11 > 30 )
+                       v11 = 30;
+                    v12 = p->uScreenSpaceY - v11;
+                    v13 = p->uScreenSpaceX - (v11 >> 1);
+                     if ( v13 + v11 < (signed int)pViewport->uViewportX
+                       || v13 >= (signed int)pViewport->uViewportZ
+                       || v12 + v11 < (signed int)pViewport->uViewportY
+                       || v12 >= (signed int)pViewport->uViewportW )
+                     {
+                      ;
+                     }
+                     else
+                     {
+                      pRenderer->MakeParticleBillboardAndPush_BLV_Software(v13, v12, p->sZValue, p->uLightColor, v11);
+                     }
+      }
     }
-    while ( (unsigned __int8)(v4 ^ v5) | v3 );
   }
 }
 
@@ -783,7 +712,6 @@
   unsigned __int8 v3; // zf@1
   char v4; // sf@1
   unsigned __int8 v5; // of@1
-  Render *pRender; // ebx@2
   char *v7; // edi@2
   int v8; // eax@6
   signed int v9; // eax@8
@@ -791,7 +719,7 @@
   int v11; // ecx@16
   int v12; // edx@16
   Particle *v13; // eax@24
-  stru346 v14; // [sp+Ch] [bp-58h]@1
+  RenderBillboardTransform_local0 v14; // [sp+Ch] [bp-58h]@1
   int v15; // [sp+5Ch] [bp-8h]@9
   int v16; // [sp+60h] [bp-4h]@1
 
@@ -804,8 +732,7 @@
   v16 = this->uStartParticle;
   if ( (unsigned __int8)(v4 ^ v5) | v3 )
   {
-    pRender = pRenderer;
-    v7 = (char *)&this->pParticles[v2].field_50 + 2;
+    v7 = (char *)&this->pParticles[v2].sZValue + 2;
     do
     {
       if ( *(int *)(v7 - 82) && v1->_48B5B3(v2) )
@@ -818,11 +745,11 @@
             v13 = &v1->pParticles[v16];
             v14.field_10 = v13->field_58 >> 2;
             v14.field_14 = v13->field_58 >> 2;
-            v14.field_8 = v13->uScreenSpaceX;
-            v14.field_C = v13->uScreenSpaceY;
-            v14.field_28 = v13->field_50;
+            v14.uScreenSpaceX = v13->uScreenSpaceX;
+            v14.uScreenSpaceY = v13->uScreenSpaceY;
+            v14.sZValue = v13->sZValue;
             pRenderer->MakeParticleBillboardAndPush_ODM(
-              (RenderBillboardTransform_local0 *)&v14,
+              &v14,
               0,
               v13->uLightColor,
               v13->_rotation);
@@ -845,7 +772,7 @@
               v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].diffuse = *(int *)(v7 + 18);
               v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].specular = 0;
               v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].texcoord.x = 0.0;
-              *((float *)&v1->pParticles[0].bFree + 16 * (v1->pLines.uNumLines + 813)) = 0.0;
+              *((float *)&v1->pParticles[0].uType + 16 * (v1->pLines.uNumLines + 813)) = 0.0;
               v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].pos.x = (double)*(signed int *)(v7 - 10);
               v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].pos.y = (double)*(signed int *)(v7 - 6);
               v15 = *(short *)v7;
@@ -865,11 +792,11 @@
           {
             v14.field_10 = *(int *)(v7 + 6);
             v14.field_14 = *(int *)(v7 + 6);
-            v14.field_8 = *(int *)(v7 - 18);
-            v14.field_C = *(int *)(v7 - 14);
-            v14.field_28 = *(int *)(v7 - 2);
+            v14.uScreenSpaceX = *(int *)(v7 - 18);
+            v14.uScreenSpaceY = *(int *)(v7 - 14);
+            v14.sZValue = *(int *)(v7 - 2);
             pRenderer->MakeParticleBillboardAndPush_ODM(
-              (RenderBillboardTransform_local0 *)&v14,
+              &v14,
               pBitmaps_LOD->pHardwareTextures[*(int *)(v7 - 46)],
               *(int *)(v7 + 18),
               *(int *)(v7 - 22));
@@ -878,11 +805,11 @@
           {
             v14.field_10 = *(int *)(v7 + 6);
             v14.field_14 = *(int *)(v7 + 6);
-            v14.field_8 = *(int *)(v7 - 18);
-            v14.field_C = *(int *)(v7 - 14);
-            v14.field_28 = *(int *)(v7 - 2);
+            v14.uScreenSpaceX = *(int *)(v7 - 18);
+            v14.uScreenSpaceY = *(int *)(v7 - 14);
+            v14.sZValue = *(int *)(v7 - 2);
             pRenderer->MakeParticleBillboardAndPush_ODM(
-              (RenderBillboardTransform_local0 *)&v14,
+              &v14,
               pSprites_LOD->pHardwareSprites[*(int *)(v7 - 46)].pTexture,
               *(int *)(v7 + 18),
               *(int *)(v7 - 22));
@@ -900,12 +827,11 @@
             || *(int *)(v7 - 14) < (signed int)pViewport->uViewportY
             || v12 >= (signed int)pViewport->uViewportW )
           {
-            pRender = pRenderer;
+            ;
           }
           else
           {
-            pRender = pRenderer;
-            pRenderer->_4A48E4(v11, v12, *(int *)(v7 - 2), *(int *)(v7 + 18), v10);
+            pRenderer->MakeParticleBillboardAndPush_BLV_Software(v11, v12, *(int *)(v7 - 2), *(int *)(v7 + 18), v10);
           }
         }
       }