Mercurial > mm7
diff ParticleEngine.cpp @ 0:9c0607679772
init
author | Ritor1 |
---|---|
date | Sat, 12 Jan 2013 09:45:18 +0600 |
parents | |
children | a9e9c6989d04 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ParticleEngine.cpp Sat Jan 12 09:45:18 2013 +0600 @@ -0,0 +1,846 @@ +#include "ParticleEngine.h" +#include "Time.h" +#include "Render.h" +#include "Viewport.h" +#include "Outdoor.h" +#include "Game.h" +#include "IndoorCamera.h" +#include "Math.h" +#include "LOD.h" + +#include "mm7_data.h" + +//----- (0048AAC5) -------------------------------------------------------- +ParticleEngine::ParticleEngine() +{ + for (uint i = 0; i < 500; ++i) + memset(&pParticles[i], 0, sizeof(pParticles[i])); + + ResetParticles(); +} + +//----- (0048AAF6) -------------------------------------------------------- +void ParticleEngine::ResetParticles() +{ + memset(pParticles, 0, 500 * sizeof(*pParticles)); + uStartParticle = 500; + uEndParticle = 0; + uTimeElapsed = 0; +} + +//----- (0048AB23) -------------------------------------------------------- +void ParticleEngine::AddParticle(Particle_ *a2) +{ + signed int v2; // eax@2 + Particle *v3; // edx@2 + Particle *v4; // esi@10 + int v5; // ecx@10 + char v6; // zf@10 + + if ( !pMiscTimer->bPaused ) + { + v2 = 0; + v3 = (Particle *)this; + do + { + if ( !v3->uType ) + break; + ++v2; + ++v3; + } + while ( v2 < 500 ); + if ( v2 < 500 ) + { + if ( v2 < this->uStartParticle ) + this->uStartParticle = v2; + if ( v2 > this->uEndParticle ) + this->uEndParticle = v2; + v4 = &this->pParticles[v2]; + v4->uType = a2->bFree; + v4->x = a2->x; + v4->y = a2->y; + v4->z = a2->z; + v4->_x = a2->x; + v4->_y = a2->y; + v4->_z = a2->z; + v4->flt_10 = a2->flt_10; + v4->flt_14 = a2->flt_14; + v4->flt_18 = a2->flt_18; + v5 = a2->uDiffuse; + v4->uParticleColor = v5; + v4->uLightColor = v5; + v6 = (v4->uType & 4) == 0; + v4->timeToLive = a2->timeToLive; + v4->uTextureID = a2->uTextureID; + v4->flt_28 = a2->flt_28; + if ( v6 ) + { + v4->field_38 = 0; + v4->_rotation = 0; + } + else + { + v4->field_38 = (unsigned __int8)rand() - 128; + v4->_rotation = rand(); + } + } + } +} + +//----- (0048ABF3) -------------------------------------------------------- +void ParticleEngine::Draw() +{ + uTimeElapsed += pEventTimer->uTimeElapsed; + pLines.uNumLines = 0; + + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + DrawParticles_BLV(); + else + DrawParticles_ODM(); + + if (pRenderer->pRenderD3D) + { + if (pLines.uNumLines) + { + pRenderer->pRenderD3D->pDevice->SetTexture(0, 0); + pRenderer->pRenderD3D->pDevice->DrawPrimitive( + D3DPT_LINELIST, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + pLines.pLineVertices, + pLines.uNumLines, + D3DDP_DONOTLIGHT); + } + } +} + +//----- (0048AC65) -------------------------------------------------------- +void ParticleEngine::UpdateParticles() +{ + unsigned int time; // edi@1 + 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 + 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 + + v20 = 0; + time = pMiscTimer->bPaused == 0 ? pEventTimer->uTimeElapsed : 0; + v19 = 500; + time_ = pMiscTimer->bPaused == 0 ? pEventTimer->uTimeElapsed : 0; + + for (uint i = uStartParticle; i < uEndParticle; ++i) + { + 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 ) + { + p->_x = p->x; + p->_y = p->y; + p->_z = p->z; + } + if ( v5 & 1 ) + p->flt_18 = p->flt_18 - (double)(signed int)time_ * 5.0; + if ( v5 & 8 ) + { + v7 = (double)(signed int)time_; + *(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_ / 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; + 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; + } + } + + uEndParticle = v20; + uStartParticle = v19; +} + +//----- (0048AE74) -------------------------------------------------------- +bool ParticleEngine::ViewProject_TrueIfStillVisible(unsigned int uParticleID) +{ + Particle *pParticle; // esi@1 + double v56; // ST28_8@2 + float v4; // eax@4 + double v5; // ST34_8@4 + signed __int64 v6; // qtt@4 + double v7; // st7@4 + float v8; // ST18_4@4 + int v9; // ecx@4 + int v10; // eax@4 + double v11; // ST44_8@7 + double v12; // ST4C_8@7 + double v13; // ST4C_8@7 + int v14; // ecx@7 + signed __int64 v15; // qtt@7 + int v16; // eax@7 + int v17; // edx@7 + float v18; // edx@7 + int v19; // eax@7 + int v20; // edx@7 + int v21; // ST50_4@8 + int v22; // ebx@8 + int v23; // ecx@10 + int v24; // edi@10 + double v25; // ST44_8@12 + double v26; // ST4C_8@12 + int v27; // edi@12 + int v28; // ST40_4@12 + int v29; // ecx@12 + signed __int64 v30; // qtt@12 + int v31; // eax@12 + int v32; // edx@12 + float v33; // edx@12 + int v34; // eax@12 + int v35; // ecx@12 + int v36; // ST38_4@13 + int v37; // ST30_4@15 + int v38; // eax@16 + signed __int64 v40; // qtt@18 + int v41; // eax@18 + int v42; // ecx@18 + int v43; // eax@18 + unsigned __int64 v44; // qax@18 + double v45; // st7@18 + int v46; // ecx@18 + float v47; // ST18_4@18 + unsigned __int64 v48; // qax@18 + double y_int_; // [sp+10h] [bp-40h]@2 + int a2; // [sp+18h] [bp-38h]@10 + int x_int; // [sp+20h] [bp-30h]@2 + double z_int_; // [sp+24h] [bp-2Ch]@2 + int z_int_4; // [sp+28h] [bp-28h]@8 + int z; // [sp+3Ch] [bp-14h]@3 + double a5; // [sp+40h] [bp-10h]@4 + int a6; // [sp+48h] [bp-8h]@4 + int y; // [sp+4Ch] [bp-4h]@3 + + pParticle = &this->pParticles[uParticleID]; + if ( !pParticle->uType ) + return 0; + uParticleID = LODWORD(pParticle->x); + v56 = *(float *)&uParticleID + 6.7553994e15; + x_int = LODWORD(v56); + uParticleID = LODWORD(pParticle->y); + y_int_ = *(float *)&uParticleID + 6.7553994e15; + uParticleID = LODWORD(pParticle->z); + z_int_ = *(float *)&uParticleID + 6.7553994e15; + if ( !pRenderer->pRenderD3D ) + { + if ( pBLVRenderParams->sPartyRotX ) + { + if ( BYTE1(pParticle->uType) & 2 ) + { + v11 = pParticle->_x + 6.7553994e15; + uParticleID = (LODWORD(v11) - pBLVRenderParams->vPartyPos.x) << 16; + v12 = pParticle->_y + 6.7553994e15; + y = (LODWORD(v12) - pBLVRenderParams->vPartyPos.y) << 16; + z = (unsigned __int64)(y * (signed __int64)pBLVRenderParams->sSineY) >> 16; + HIDWORD(a5) = ((unsigned __int64)((signed int)uParticleID * (signed __int64)pBLVRenderParams->sCosineY) >> 16) + - z; + a6 = (unsigned __int64)((signed int)uParticleID * (signed __int64)pBLVRenderParams->sSineY) >> 16; + v13 = pParticle->_z + 6.7553994e15; + uParticleID = (LODWORD(v13) - pBLVRenderParams->vPartyPos.z) << 16; + z = ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pBLVRenderParams->sCosineNegX) >> 16) + - ((unsigned __int64)((signed int)uParticleID * (signed __int64)pBLVRenderParams->sSineNegX) >> 16); + v14 = z; + HIDWORD(v13) = (unsigned __int64)(SHIDWORD(a5) * (signed __int64)pBLVRenderParams->sSineNegX) >> 16; + HIDWORD(a5) = (unsigned __int64)((signed int)uParticleID * (signed __int64)pBLVRenderParams->sCosineNegX) >> 16; + LODWORD(v15) = pBLVRenderParams->field_40 << 16; + HIDWORD(v15) = pBLVRenderParams->field_40 >> 16; + v16 = v15 / z; + v17 = (unsigned __int64)(y * (signed __int64)pBLVRenderParams->sCosineY) >> 16; + pParticle->field_58 = v16; + uParticleID = (unsigned __int64)(v16 * (signed __int64)(a6 + v17)) >> 16; + LODWORD(v18) = pBLVRenderParams->uViewportCenterX + - ((signed int)((unsigned __int64)(v16 * (signed __int64)(a6 + v17)) >> 16) >> 16); + v19 = pParticle->field_58; + 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->sZValue2 = v14; + pParticle->uScreenSpaceW = v20; + } + uParticleID = (x_int - pBLVRenderParams->vPartyPos.x) << 16; + y = (LODWORD(y_int_) - pBLVRenderParams->vPartyPos.y) << 16; + HIDWORD(a5) = ((unsigned __int64)((signed int)uParticleID * (signed __int64)pBLVRenderParams->sCosineY) >> 16) + - ((unsigned __int64)(y * (signed __int64)pBLVRenderParams->sSineY) >> 16); + a6 = (unsigned __int64)((signed int)uParticleID * (signed __int64)pBLVRenderParams->sSineY) >> 16; + HIDWORD(z_int_) = (unsigned __int64)(y * (signed __int64)pBLVRenderParams->sCosineY) >> 16; + uParticleID = (LODWORD(z_int_) - pBLVRenderParams->vPartyPos.z) << 16; + v21 = (unsigned __int64)((signed int)uParticleID * (signed __int64)pBLVRenderParams->sSineNegX) >> 16; + v22 = ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pBLVRenderParams->sCosineNegX) >> 16) - v21; + z = ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pBLVRenderParams->sCosineNegX) >> 16) - v21; + if ( v22 < (signed int)0x40000u || v22 > (signed int)0x1F400000u ) + return 0; + v23 = a6 + z_int_4; + a2 = a6 + z_int_4; + v24 = ((unsigned __int64)((signed int)uParticleID * (signed __int64)pBLVRenderParams->sCosineNegX) >> 16) + + ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pBLVRenderParams->sSineNegX) >> 16); + } + else + { + if ( BYTE1(pParticle->uType) & 2 ) + { + v25 = pParticle->_x + 6.7553994e15; + uParticleID = (LODWORD(v25) - pBLVRenderParams->vPartyPos.x) << 16; + v26 = pParticle->_y + 6.7553994e15; + y = (LODWORD(v26) - pBLVRenderParams->vPartyPos.y) << 16; + HIDWORD(v25) = (unsigned __int64)(y * (signed __int64)pBLVRenderParams->sSineY) >> 16; + v27 = ((unsigned __int64)((signed int)uParticleID * (signed __int64)pBLVRenderParams->sCosineY) >> 16) + - HIDWORD(v25); + z = ((unsigned __int64)((signed int)uParticleID * (signed __int64)pBLVRenderParams->sCosineY) >> 16) + - HIDWORD(v25); + v28 = (unsigned __int64)((signed int)uParticleID * (signed __int64)pBLVRenderParams->sSineY) >> 16; + a5 = pParticle->_z + 6.7553994e15; + v29 = (LODWORD(a5) - pBLVRenderParams->vPartyPos.z) << 16; + LODWORD(v30) = pBLVRenderParams->field_40 << 16; + HIDWORD(v30) = pBLVRenderParams->field_40 >> 16; + v31 = v30 / z; + v32 = (unsigned __int64)(y * (signed __int64)pBLVRenderParams->sCosineY) >> 16; + pParticle->field_58 = v31; + uParticleID = (unsigned __int64)(v31 * (signed __int64)(v28 + v32)) >> 16; + LODWORD(v33) = pBLVRenderParams->uViewportCenterX + - ((signed int)((unsigned __int64)(v31 * (signed __int64)(v28 + v32)) >> 16) >> 16); + v34 = pParticle->field_58; + pParticle->uScreenSpaceZ = v33; + v35 = pBLVRenderParams->uViewportCenterY + - ((signed int)((unsigned __int64)(v34 * (signed __int64)v29) >> 16) >> 16); + pParticle->sZValue2 = v27; + pParticle->uScreenSpaceW = v35; + } + uParticleID = (x_int - pBLVRenderParams->vPartyPos.x) << 16; + y = (LODWORD(y_int_) - pBLVRenderParams->vPartyPos.y) << 16; + v36 = (unsigned __int64)(y * (signed __int64)pBLVRenderParams->sSineY) >> 16; + v22 = ((unsigned __int64)((signed int)uParticleID * (signed __int64)pBLVRenderParams->sCosineY) >> 16) - v36; + z = ((unsigned __int64)((signed int)uParticleID * (signed __int64)pBLVRenderParams->sCosineY) >> 16) - v36; + if ( v22 < 262144 || v22 > 524288000 ) + return 0; + v37 = (unsigned __int64)((signed int)uParticleID * (signed __int64)pBLVRenderParams->sSineY) >> 16; + uParticleID = (unsigned __int64)(y * (signed __int64)pBLVRenderParams->sCosineY) >> 16; + v23 = v37 + ((unsigned __int64)(y * (signed __int64)pBLVRenderParams->sCosineY) >> 16); + a2 = v37 + ((unsigned __int64)(y * (signed __int64)pBLVRenderParams->sCosineY) >> 16); + v24 = (LODWORD(z_int_) - pBLVRenderParams->vPartyPos.z) << 16; + } + uParticleID = abs(v23); + v38 = abs(v22); + if ( v38 >= (signed int)uParticleID ) + { + LODWORD(v40) = pBLVRenderParams->field_40 << 16; + HIDWORD(v40) = pBLVRenderParams->field_40 >> 16; + v41 = v40 / z; + pParticle->field_58 = v41; + uParticleID = (unsigned __int64)(v41 * (signed __int64)a2) >> 16; + v42 = pBLVRenderParams->uViewportCenterX - ((signed int)((unsigned __int64)(v41 * (signed __int64)a2) >> 16) >> 16); + v43 = pParticle->field_58; + pParticle->uScreenSpaceX = v42; + v44 = v43 * (signed __int64)v24; + uParticleID = v44 >> 16; + v45 = pParticle->flt_28; + LODWORD(v44) = (signed int)(v44 >> 16) >> 16; + v46 = pBLVRenderParams->uViewportCenterY - v44; + pParticle->uScreenSpaceY = pBLVRenderParams->uViewportCenterY - v44; + v47 = v45; + v48 = _48B561_mess_with_scaling_along_z(/*v46, */v47) * (signed __int64)pParticle->field_58; + uParticleID = v48 >> 16; + pParticle->field_58 = v48 >> 16; + v10 = z; + goto LABEL_19; + } + return 0; + } + if ( !pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible( + x_int, + SLODWORD(y_int_), + COERCE_UNSIGNED_INT64(*(float *)&uParticleID + 6.7553994e15), + (signed int *)&uParticleID, + &y, + &z, + 1) ) + return 0; + pGame->pIndoorCameraD3D->Project(uParticleID, y, z, (int *)&a5 + 1, &a6); + pParticle->flt_5C = pGame->pIndoorCameraD3D->fov_x; + v4 = pParticle->flt_5C; + pParticle->flt_60 = pGame->pIndoorCameraD3D->fov_y; + v5 = v4 + 6.7553994e15; + LODWORD(v6) = 0; + HIDWORD(v6) = SLOWORD(v5); + v7 = pParticle->flt_28; + pParticle->field_58 = v6 / (signed int)uParticleID; + v8 = v7; + pParticle->uScreenSpaceX = HIDWORD(a5); + pParticle->uScreenSpaceY = a6; + pParticle->field_58 = (unsigned __int64)(_48B561_mess_with_scaling_along_z(/*v9, */v8) * (signed __int64)pParticle->field_58) >> 16; + v10 = uParticleID; +LABEL_19: + pParticle->sZValue = v10; + return 1; +} + + + + +//----- (0048B5B3) -------------------------------------------------------- +bool ParticleEngine::_48B5B3(unsigned int uID) +{ + ParticleEngine *v2; // ST18_4@1 + int v3; // ebx@1 + int v4; // edi@1 + int v5; // ecx@1 + Particle *v6; // esi@1 + double v7; // ST14_8@2 + double v8; // ST34_8@4 + double v9; // ST3C_8@4 + int v10; // ST50_4@4 + int v11; // ST44_4@4 + double v12; // ST48_8@4 + signed __int64 v13; // qtt@4 + int v14; // eax@4 + int v15; // ST28_4@4 + int v16; // edi@6 + int v17; // eax@6 + double v18; // ST2C_8@8 + double v19; // ST34_8@8 + int v20; // ST50_4@8 + double v21; // ST34_8@8 + signed __int64 v22; // qtt@8 + int v23; // eax@8 + int v24; // ST28_4@8 + int v25; // edx@8 + int v26; // edx@9 + int v27; // eax@9 + int v28; // ebx@12 + signed __int64 v29; // qtt@13 + int v30; // eax@13 + int v31; // ST1C_4@13 + double v32; // st7@13 + signed int v33; // eax@13 + int v34; // ecx@13 + float v35; // ST04_4@13 + int v36; // eax@13 + int v37; // esi@15 + double v39; // [sp+10h] [bp-40h]@2 + int v40; // [sp+14h] [bp-3Ch]@12 + int v41; // [sp+1Ch] [bp-34h]@2 + double v42; // [sp+20h] [bp-30h]@2 + int v43; // [sp+24h] [bp-2Ch]@5 + int v44; // [sp+2Ch] [bp-24h]@1 + int v45; // [sp+40h] [bp-10h]@5 + int X_4; // [sp+48h] [bp-8h]@5 + int v47; // [sp+4Ch] [bp-4h]@5 + int v48; // [sp+4Ch] [bp-4h]@9 + int uIDc; // [sp+58h] [bp+8h]@4 + int uIDd; // [sp+58h] [bp+8h]@4 + int uIDe; // [sp+58h] [bp+8h]@5 + int uIDa; // [sp+58h] [bp+8h]@5 + int uIDf; // [sp+58h] [bp+8h]@8 + int uIDb; // [sp+58h] [bp+8h]@9 + + v2 = this; + v3 = stru_5C6E00->SinCos(pIndoorCamera->sRotationX); + v44 = stru_5C6E00->SinCos(pIndoorCamera->sRotationX - stru_5C6E00->uIntegerHalfPi); + v4 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY); + v5 = stru_5C6E00->SinCos(pIndoorCamera->sRotationY - stru_5C6E00->uIntegerHalfPi); + v6 = &v2->pParticles[uID]; + if ( v6->uType ) + { + v7 = v6->x + 6.7553994e15; + v41 = LODWORD(v7); + v39 = v6->y + 6.7553994e15; + v42 = v6->z + 6.7553994e15; + if ( v3 ) + { + if ( BYTE1(v6->uType) & 2 ) + { + v8 = v6->_x + 6.7553994e15; + uIDc = (LODWORD(v8) - pIndoorCamera->pos.x) << 16; + v9 = v6->_y + 6.7553994e15; + v10 = (LODWORD(v9) - pIndoorCamera->pos.y) << 16; + v11 = ((unsigned __int64)(uIDc * (signed __int64)v4) >> 16) + + ((unsigned __int64)(v10 * (signed __int64)v5) >> 16); + HIDWORD(v8) = (unsigned __int64)(uIDc * (signed __int64)v5) >> 16; + v12 = v6->_z + 6.7553994e15; + uIDd = (LODWORD(v12) - pIndoorCamera->pos.z) << 16; + HIDWORD(v12) = ((unsigned __int64)(v11 * (signed __int64)v3) >> 16) + + ((unsigned __int64)(uIDd * (signed __int64)v44) >> 16); + LODWORD(v13) = 0; + HIDWORD(v13) = SLOWORD(pOutdoorCamera->int_fov_rad); + v14 = v13 / SHIDWORD(v12); + v6->field_58 = v14; + v15 = v6->field_58; + v6->uScreenSpaceX = pViewport->uScreenCenterX + - ((signed int)((unsigned __int64)(v14 + * (signed __int64)(signed int)(((unsigned __int64)(v10 * (signed __int64)v4) >> 16) + - HIDWORD(v8))) >> 16) >> 16); + v6->uScreenSpaceY = pViewport->uScreenCenterY + - ((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->sZValue = HIDWORD(v12); + } + uIDe = (v41 - pIndoorCamera->pos.x) << 16; + v47 = (LODWORD(v39) - pIndoorCamera->pos.y) << 16; + v45 = ((unsigned __int64)(uIDe * (signed __int64)v4) >> 16) + ((unsigned __int64)(v47 * (signed __int64)v5) >> 16); + HIDWORD(v42) = (unsigned __int64)(uIDe * (signed __int64)v5) >> 16; + uIDa = (LODWORD(v42) - pIndoorCamera->pos.z) << 16; + X_4 = ((unsigned __int64)(uIDa * (signed __int64)v44) >> 16) + + ((unsigned __int64)(v45 * (signed __int64)v3) >> 16); + if ( X_4 < 262144 ) + return 0; + v16 = ((unsigned __int64)(v47 * (signed __int64)v4) >> 16) - v43; + v17 = ((unsigned __int64)(uIDa * (signed __int64)v3) >> 16) + - ((unsigned __int64)(v45 * (signed __int64)v44) >> 16); + } + else + { + if ( BYTE1(v6->uType) & 2 ) + { + v18 = v6->_x + 6.7553994e15; + uIDf = (LODWORD(v18) - pIndoorCamera->pos.x) << 16; + v19 = v6->_y + 6.7553994e15; + v20 = (LODWORD(v19) - pIndoorCamera->pos.y) << 16; + v21 = v6->_z + 6.7553994e15; + LODWORD(v22) = 0; + HIDWORD(v22) = SLOWORD(pOutdoorCamera->int_fov_rad); + v23 = v22 + / (signed int)(((unsigned __int64)(v20 * (signed __int64)v5) >> 16) + + ((unsigned __int64)(uIDf * (signed __int64)v4) >> 16)); + v6->field_58 = v23; + v24 = v6->field_58; + v6->uScreenSpaceX = pViewport->uScreenCenterX + - ((signed int)((unsigned __int64)(v23 + * (signed __int64)(signed int)(((unsigned __int64)(v20 * (signed __int64)v4) >> 16) + - ((unsigned __int64)(uIDf * (signed __int64)v5) >> 16))) >> 16) >> 16); + v25 = pViewport->uScreenCenterY + - ((signed int)((unsigned __int64)(v24 * (signed __int64)SLODWORD(v21)) >> 16) >> 16); + v6->sZValue = ((unsigned __int64)(v20 * (signed __int64)v5) >> 16) + + ((unsigned __int64)(uIDf * (signed __int64)v4) >> 16); + v6->uScreenSpaceY = v25; + } + uIDb = (v41 - pIndoorCamera->pos.x) << 16; + v48 = (LODWORD(v39) - pIndoorCamera->pos.y) << 16; + v26 = (unsigned __int64)(v48 * (signed __int64)v5) >> 16; + v27 = v26 + ((unsigned __int64)(uIDb * (signed __int64)v4) >> 16); + X_4 = v26 + ((unsigned __int64)(uIDb * (signed __int64)v4) >> 16); + if ( v27 < 262144 || v27 > (pOutdoorCamera->uPickDepth - 1000) << 16 ) + return 0; + v17 = LODWORD(v42); + v16 = ((unsigned __int64)(v48 * (signed __int64)v4) >> 16) - ((unsigned __int64)(uIDb * (signed __int64)v5) >> 16); + } + v40 = v17; + v28 = abs(v16); + if ( abs(X_4) >= v28 ) + { + LODWORD(v29) = 0; + HIDWORD(v29) = SLOWORD(pOutdoorCamera->int_fov_rad); + v30 = v29 / X_4; + v6->field_58 = v30; + v31 = v6->field_58; + v6->uScreenSpaceX = pViewport->uScreenCenterX + - ((signed int)((unsigned __int64)(v30 * (signed __int64)v16) >> 16) >> 16); + v32 = v6->flt_28; + v33 = (signed int)((unsigned __int64)(v31 * (signed __int64)v40) >> 16) >> 16; + v34 = pViewport->uScreenCenterY - v33; + 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->sZValue = X_4; + v36 = v6->uScreenSpaceX; + if ( v36 >= (signed int)pViewport->uViewportX ) + { + if ( v36 < (signed int)pViewport->uViewportZ ) + { + v37 = v6->uScreenSpaceY; + if ( v37 >= (signed int)pViewport->uViewportY ) + { + if ( v37 < (signed int)pViewport->uViewportW ) + return 1; + } + } + } + } + } + return 0; +} + +//----- (0048BBA6) -------------------------------------------------------- +void ParticleEngine::DrawParticles_BLV() +{ + int v11; // eax@18 + int v12; // ecx@20 + int v13; // edx@20 + Particle *v14; // eax@28 + RenderBillboardTransform_local0 v15; // [sp+Ch] [bp-58h]@1 + + v15.uParentBillboardID = -1; + + for (uint i = uStartParticle; i < uEndParticle; ++i) + { + 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 (pRenderer->pRenderD3D) + { + if (p->uType & 0x0100) + { + 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) + { + 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); + } + } + 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); + } + } + } + } +} + +//----- (0048BEEF) -------------------------------------------------------- +void ParticleEngine::DrawParticles_ODM() +{ + ParticleEngine *v1; // esi@1 + int v2; // eax@1 + unsigned __int8 v3; // zf@1 + char v4; // sf@1 + unsigned __int8 v5; // of@1 + char *v7; // edi@2 + int v8; // eax@6 + signed int v9; // eax@8 + int v10; // eax@14 + int v11; // ecx@16 + int v12; // edx@16 + Particle *v13; // eax@24 + RenderBillboardTransform_local0 v14; // [sp+Ch] [bp-58h]@1 + int v15; // [sp+5Ch] [bp-8h]@9 + int v16; // [sp+60h] [bp-4h]@1 + + v14.uParentBillboardID = -1; + v1 = this; + v2 = this->uStartParticle; + v5 = __OFSUB__(v2, this->uEndParticle); + v3 = v2 == this->uEndParticle; + v4 = v2 - this->uEndParticle < 0; + v16 = this->uStartParticle; + if ( (unsigned __int8)(v4 ^ v5) | v3 ) + { + v7 = (char *)&this->pParticles[v2].sZValue + 2; + do + { + if ( *(int *)(v7 - 82) && v1->_48B5B3(v2) ) + { + if ( pRenderer->pRenderD3D ) + { + v8 = *(int *)(v7 - 82); + if ( BYTE1(v8) & 1 ) + { + v13 = &v1->pParticles[v16]; + v14.field_10 = v13->field_58 >> 2; + v14.field_14 = v13->field_58 >> 2; + v14.uScreenSpaceX = v13->uScreenSpaceX; + v14.uScreenSpaceY = v13->uScreenSpaceY; + v14.sZValue = v13->sZValue; + pRenderer->MakeParticleBillboardAndPush_ODM( + &v14, + 0, + v13->uLightColor, + v13->_rotation); + return; + } + if ( BYTE1(v8) & 2 ) + { + v9 = v1->pLines.uNumLines; + if ( v9 < 100 ) + { + v1->pLines.pLineVertices[2 * v9].pos.x = (double)*(signed int *)(v7 - 18); + v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].pos.y = (double)*(signed int *)(v7 - 14); + v15 = *(short *)v7; + v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].pos.z = 1.0 + - 1.0 + / ((double)v15 + * 1000.0 + / (double)pOutdoorCamera->shading_dist_mist); + v1->pLines.pLineVertices[2 * v1->pLines.uNumLines].rhw = 1.0; + 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].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; + v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].pos.z = 1.0 + - 1.0 + / ((double)v15 + * 1000.0 + / (double)pOutdoorCamera->shading_dist_mist); + v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].rhw = 1.0; + v1->pLines.pLineVertices[2 * v1->pLines.uNumLines + 1].diffuse = *(int *)(v7 + 18); + 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 - 81) & 4 ) + { + v14.field_10 = *(int *)(v7 + 6); + v14.field_14 = *(int *)(v7 + 6); + v14.uScreenSpaceX = *(int *)(v7 - 18); + v14.uScreenSpaceY = *(int *)(v7 - 14); + v14.sZValue = *(int *)(v7 - 2); + pRenderer->MakeParticleBillboardAndPush_ODM( + &v14, + pBitmaps_LOD->pHardwareTextures[*(int *)(v7 - 46)], + *(int *)(v7 + 18), + *(int *)(v7 - 22)); + } + if ( *(v7 - 81) & 8 ) + { + v14.field_10 = *(int *)(v7 + 6); + v14.field_14 = *(int *)(v7 + 6); + v14.uScreenSpaceX = *(int *)(v7 - 18); + v14.uScreenSpaceY = *(int *)(v7 - 14); + v14.sZValue = *(int *)(v7 - 2); + pRenderer->MakeParticleBillboardAndPush_ODM( + &v14, + pSprites_LOD->pHardwareSprites[*(int *)(v7 - 46)].pTexture, + *(int *)(v7 + 18), + *(int *)(v7 - 22)); + } + } + else + { + v10 = 13 * *(int *)(v7 + 6) >> 16; + if ( v10 > 30 ) + v10 = 30; + v11 = *(int *)(v7 - 18) - (v10 >> 1); + v12 = *(int *)(v7 - 14) - v10; + if ( v11 + v10 < (signed int)pViewport->uViewportX + || v11 >= (signed int)pViewport->uViewportZ + || *(int *)(v7 - 14) < (signed int)pViewport->uViewportY + || v12 >= (signed int)pViewport->uViewportW ) + { + ; + } + else + { + pRenderer->MakeParticleBillboardAndPush_BLV_Software(v11, v12, *(int *)(v7 - 2), *(int *)(v7 + 18), v10); + } + } + } + v7 += 104; + v2 = v16 + 1; + v5 = __OFSUB__(v16 + 1, v1->uEndParticle); + v3 = v16 + 1 == v1->uEndParticle; + v4 = v16++ + 1 - v1->uEndParticle < 0; + } + while ( (unsigned __int8)(v4 ^ v5) | v3 ); + } +} \ No newline at end of file