Mercurial > mm7
diff Engine/Graphics/ParticleEngine.cpp @ 2496:5abd8fc8f1c6
for ITEM_ARTIFACT_LADYS_ESCORT
author | Ritor1 |
---|---|
date | Thu, 18 Sep 2014 17:38:54 +0600 |
parents | |
children | 68cdef6879a0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Graphics/ParticleEngine.cpp Thu Sep 18 17:38:54 2014 +0600 @@ -0,0 +1,768 @@ +#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> + +#define _CRT_SECURE_NO_WARNINGS +#include "ParticleEngine.h" +#include "Timer.h" +#include "Viewport.h" +#include "Outdoor.h" +#include "Game.h" +#include "OurMath.h" +#include "LOD.h" + +#include "Sprites.h" + +TrailParticleGenerator trail_particle_generator; + + +//----- (00440DF5) -------------------------------------------------------- +void TrailParticleGenerator::AddParticle(int x, int y, int z, int bgr16) +{ + particles[num_particles].x = x; + particles[num_particles].y = y; + particles[num_particles].z = z; + particles[num_particles].time_to_live = rand() % 64 + 256; + particles[num_particles].time_left = particles[num_particles].time_to_live; + particles[num_particles].bgr16 = bgr16; + + num_particles++; + assert(num_particles < 100); +} + +//----- (00440E91) -------------------------------------------------------- +void TrailParticleGenerator::GenerateTrailParticles(int x, int y, int z, int bgr16) +{ + for (int i = 0; i < 5 + rand() % 6; ++i) + AddParticle(rand() % 33 + x - 16, + rand() % 33 + y - 16, + rand() % 33 + z, bgr16); +} + +//----- (00440F07) -------------------------------------------------------- +void TrailParticleGenerator::UpdateParticles() +{ + for (uint i = 0; i < 100; ++i) + { + if (particles[i].time_left > 0) + { + particles[i].x += rand() % 5 + 4; + particles[i].y += rand() % 5 - 2; + particles[i].z += rand() % 5 - 2; + particles[i].time_left -= pEventTimer->uTimeElapsed; + } + } +} + +//----- (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_sw *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->type == ParticleType_Invalid) + 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->type = a2->type; + 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->r; + v4->flt_14 = a2->g; + v4->flt_18 = a2->b; + v5 = a2->uDiffuse; + v4->uParticleColor = v5; + v4->uLightColor_bgr = v5; + //v6 = (v4->uType & 4) == 0; + v4->timeToLive = a2->timeToLive; + v4->uTextureID = a2->uTextureID; + v4->flt_28 = a2->flt_28; + if (v4->type & ParticleType_Rotating) + { + v4->rotation_speed = (rand() % 256) - 128; + v4->angle = rand(); + } + else + { + v4->rotation_speed = 0; + v4->angle = 0; + } + } + } +} + +//----- (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->DrawLines(pLines.pLineVertices, 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) + { + Particle* p = &pParticles[i]; + + if (p->type == ParticleType_Invalid) + continue; + + if (p->timeToLive <= time) + { + p->timeToLive = 0; + p->type = ParticleType_Invalid; + continue; + } + p->timeToLive -= time; + + if (p->type & ParticleType_Line) + { + p->_x = p->x; + p->_y = p->y; + p->_z = p->z; + } + + if (p->type & ParticleType_1) + p->flt_18 = p->flt_18 - (double)(signed int)time_ * 5.0; + + if (p->type & ParticleType_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->rotation_speed) / 16; + + p->x += v8 * p->flt_10; + p->y += v8 * p->flt_14; + p->z += v8 * p->flt_18; + + p->angle += time * p->rotation_speed / 16; + v22 = 2 * p->timeToLive; + if (v22 >= 255 ) + v22 = 255; + //v10 = (double)v22 * 0.0039215689; + p->uLightColor_bgr = ((uint)floorf(p->b * (v22 / 255.0f) + 0.5) << 16) | + ((uint)floorf(p->g * (v22 / 255.0f) + 0.5) << 8) | + ((uint)floorf(p->r * (v22 / 255.0f) + 0.5) << 0); + if ( i < v19 ) + v19 = i; + if ( i > v20 ) + v20 = i; + } + + uEndParticle = v20; + uStartParticle = v19; +} + +//----- (0048AE74) -------------------------------------------------------- +bool ParticleEngine::ViewProject_TrueIfStillVisible_BLV(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 + int y_int_; // [sp+10h] [bp-40h]@2 +// int a2; // [sp+18h] [bp-38h]@10 + int x_int; // [sp+20h] [bp-30h]@2 + int 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->type == ParticleType_Invalid) + return 0; + //uParticleID = LODWORD(pParticle->x); + //v56 = *(float *)&uParticleID + 6.7553994e15; + x_int = floorf(pParticle->x + 0.5f); + //uParticleID = LODWORD(pParticle->y); + //y_int_ = *(float *)&uParticleID + 6.7553994e15; + y_int_ = floorf(pParticle->y + 0.5f); + //uParticleID = LODWORD(pParticle->z); + //z_int_ = *(float *)&uParticleID + 6.7553994e15; + z_int_ = floorf(pParticle->z + 0.5f); + /*if ( !pRenderer->pRenderD3D ) + { + if (pGame->pIndoorCameraD3D->sRotationX) + { + if (pParticle->type & ParticleType_Line) + { + //v11 = pParticle->_x + 6.7553994e15; + int _uParticleID = (int)(floorf(pParticle->_x + 0.5f) - pBLVRenderParams->vPartyPos.x) << 16; + //v12 = pParticle->_y + 6.7553994e15; + y = (int)(floorf(pParticle->_y + 0.5f) - pBLVRenderParams->vPartyPos.y) << 16; + z = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; + HIDWORD(a5) = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) + - z; + a6 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; + //v13 = pParticle->_z + 6.7553994e15; + _uParticleID = (int)(floorf(pParticle->_z + 0.5f) - pBLVRenderParams->vPartyPos.z) << 16; + z = ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_x) >> 16) + - ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_x) >> 16); + v14 = z; + HIDWORD(v13) = (unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_sine_x) >> 16; + HIDWORD(a5) = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_x) >> 16; + //LODWORD(v15) = pBLVRenderParams->field_40 << 16; + //HIDWORD(v15) = pBLVRenderParams->field_40 >> 16; + //v16 = v15 / z; + v16 = fixpoint_div(pBLVRenderParams->field_40, z); + v17 = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16; + pParticle->_screenspace_scale = 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->_screenspace_scale; + 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; + } + int _uParticleID = (x_int - pBLVRenderParams->vPartyPos.x) << 16; + y = (y_int_ - pBLVRenderParams->vPartyPos.y) << 16; + HIDWORD(a5) = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) + - ((unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16); + a6 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; + z_int_4 = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16; + _uParticleID = (z_int_ - pBLVRenderParams->vPartyPos.z) << 16; + v21 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_x) >> 16; + v22 = ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_x) >> 16) - v21; + z = ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_x) >> 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)pGame->pIndoorCameraD3D->int_cosine_x) >> 16) + + ((unsigned __int64)(SHIDWORD(a5) * (signed __int64)pGame->pIndoorCameraD3D->int_sine_x) >> 16); + } + else + { + if (pParticle->type & ParticleType_Line) + { + //v25 = pParticle->_x + 6.7553994e15; + int _uParticleID = ((int)floorf(pParticle->_x + 0.5f) - pBLVRenderParams->vPartyPos.x) << 16; + //v26 = pParticle->_y + 6.7553994e15; + y = ((int)floorf(pParticle->_y + 0.5f) - pBLVRenderParams->vPartyPos.y) << 16; + auto _hiword_v25 = (__int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; + v27 = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) - _hiword_v25; + z = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) - _hiword_v25; + v28 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; + //a5 = pParticle->_z + 6.7553994e15; + v29 = ((int)floorf(pParticle->_z + 0.5f) - pBLVRenderParams->vPartyPos.z) << 16; + //LODWORD(v30) = pBLVRenderParams->field_40 << 16; + //HIDWORD(v30) = pBLVRenderParams->field_40 >> 16; + //v31 = v30 / z; + v31 = fixpoint_div(pBLVRenderParams->field_40, z); + v32 = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16; + pParticle->_screenspace_scale = 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->_screenspace_scale; + pParticle->uScreenSpaceZ = v33; + v35 = pBLVRenderParams->uViewportCenterY - ((signed int)((unsigned __int64)(pParticle->_screenspace_scale * (signed __int64)v29) >> 16) >> 16); + pParticle->sZValue2 = v27; + pParticle->uScreenSpaceW = v35; + } + int _uParticleID = (x_int - pBLVRenderParams->vPartyPos.x) << 16; + y = (y_int_ - pBLVRenderParams->vPartyPos.y) << 16; + v36 = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; + v22 = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) - v36; + z = ((unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16) - v36; + if ( v22 < 262144 || v22 > 524288000 ) + return 0; + v37 = (unsigned __int64)((signed int)_uParticleID * (signed __int64)pGame->pIndoorCameraD3D->int_sine_y) >> 16; + _uParticleID = (unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16; + v23 = v37 + ((unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16); + a2 = v37 + ((unsigned __int64)(y * (signed __int64)pGame->pIndoorCameraD3D->int_cosine_y) >> 16); + v24 = (z_int_ - pBLVRenderParams->vPartyPos.z) << 16; + } + int _uParticleID = abs(v23); + v38 = abs(v22); + if ( v38 >= (signed int)_uParticleID ) + { + //LODWORD(v40) = pBLVRenderParams->field_40 << 16; + //HIDWORD(v40) = pBLVRenderParams->field_40 >> 16; + v41 = fixpoint_div(pBLVRenderParams->field_40, z); + pParticle->_screenspace_scale = v41; + _uParticleID = (unsigned __int64)(v41 * (signed __int64)a2) >> 16; + v42 = pBLVRenderParams->uViewportCenterX - ((signed int)((unsigned __int64)(v41 * (signed __int64)a2) >> 16) >> 16); + v43 = pParticle->_screenspace_scale; + pParticle->uScreenSpaceX = v42; + v44 = v43 * (signed __int64)v24; + //uParticleID = v44 >> 16; + LODWORD(v44) = (signed int)(v44 >> 16) >> 16; + pParticle->uScreenSpaceY = pBLVRenderParams->uViewportCenterY - v44; + pParticle->_screenspace_scale = fixpoint_mul(fixpoint_from_float(pParticle->flt_28), pParticle->_screenspace_scale); + pParticle->sZValue = z; + return true; + } + return false; + }*/ + + int x; + if ( !pGame->pIndoorCameraD3D->ApplyViewTransform_TrueIfStillVisible_BLV( + x_int, + y_int_, + z_int_, + &x, + &y, + &z, + 1) ) + return false; + pGame->pIndoorCameraD3D->Project(x, y, z, &pParticle->uScreenSpaceX, &pParticle->uScreenSpaceY); + 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) = floorf(pParticle->flt_5C + 0.5f); + //v7 = pParticle->flt_28; + //pParticle->_screenspace_scale = v6 / x; + //v8 = v7; + pParticle->_screenspace_scale = fixpoint_mul(fixpoint_from_float(pParticle->flt_28), v6 / x); + pParticle->sZValue = x; + return true; +} + + + + +//----- (0048B5B3) -------------------------------------------------------- +bool ParticleEngine::ViewProject_TrueIfStillVisible_ODM(unsigned int uID) +{ + int v3; // ebx@1 + int v4; // edi@1 + int v5; // ecx@1 + int v11; // ST44_4@4 + signed __int64 v13; // qtt@4 + int v16; // edi@6 + int v17; // eax@6 + signed __int64 v22; // qtt@8 + int v26; // edx@9 + int v28; // ebx@12 + signed __int64 v29; // qtt@13 + int v40; // [sp+14h] [bp-3Ch]@12 + int v44; // [sp+2Ch] [bp-24h]@1 + int v45; // [sp+40h] [bp-10h]@5 + int X_4; // [sp+48h] [bp-8h]@5 + + v3 = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX); + v44 = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX); + v4 = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY); + v5 = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); + + if (pParticles[uID].type == ParticleType_Invalid) + return false; + + if ( v3 ) + { + if (pParticles[uID].type & ParticleType_Line) + { + v11 = fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v4) + + fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v5); + long long _hidword_v12 = fixpoint_mul(v11, v3) + fixpoint_sub_unknown(pParticles[uID].z - pGame->pIndoorCameraD3D->vPartyPos.z, v44); + LODWORD(v13) = 0; + HIDWORD(v13) = SLOWORD(pODMRenderParams->int_fov_rad); + pParticles[uID]._screenspace_scale = v13 / _hidword_v12; + pParticles[uID].uScreenSpaceX = pViewport->uScreenCenterX + - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, (fixpoint_sub_unknown(pParticles[uID].y + - pGame->pIndoorCameraD3D->vPartyPos.y, v4) + - fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v5))) >> 16); + pParticles[uID].uScreenSpaceY = pViewport->uScreenCenterY + - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, (fixpoint_sub_unknown(pParticles[uID].z + - pGame->pIndoorCameraD3D->vPartyPos.z, v3) + - fixpoint_mul(v11, v44))) >> 16); + pParticles[uID].sZValue = _hidword_v12; + } + v45 = fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v4) + fixpoint_sub_unknown(pParticles[uID].y + - pGame->pIndoorCameraD3D->vPartyPos.y, v5); + X_4 = fixpoint_sub_unknown(pParticles[uID].z - pGame->pIndoorCameraD3D->vPartyPos.z, v44) + fixpoint_mul(v45, v3); + if ( X_4 < 0x40000 ) + return 0; + v16 = fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v4) + - fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v5); + v17 = fixpoint_sub_unknown(pParticles[uID].z - pGame->pIndoorCameraD3D->vPartyPos.z, v3) - fixpoint_mul(v45, v44); + } + else + { + if (pParticles[uID].type & ParticleType_Line) + { + LODWORD(v22) = 0; + HIDWORD(v22) = SLOWORD(pODMRenderParams->int_fov_rad); + long long _var_123 = fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v4) + + fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v5); + pParticles[uID]._screenspace_scale = v22 / _var_123; + pParticles[uID].uScreenSpaceX = pViewport->uScreenCenterX + - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, (fixpoint_sub_unknown(pParticles[uID].y + - pGame->pIndoorCameraD3D->vPartyPos.y, v4) + - fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v5))) >> 16); + pParticles[uID].uScreenSpaceY = pViewport->uScreenCenterY - (fixpoint_sub_unknown(pParticles[uID].z, pParticles[uID]._screenspace_scale) >> 16); + pParticles[uID].sZValue = _var_123; + } + v26 = fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v5); + X_4 = v26 + fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v4); + if ( X_4 < 0x40000 || X_4 > (pODMRenderParams->uPickDepth - 1000) << 16 ) + return 0; + v17 = pParticles[uID].z; + v16 = fixpoint_sub_unknown(pParticles[uID].y - pGame->pIndoorCameraD3D->vPartyPos.y, v4) + - fixpoint_sub_unknown(pParticles[uID].x - pGame->pIndoorCameraD3D->vPartyPos.x, v5); + } + v40 = v17; + v28 = abs(v16); + if ( abs(X_4) >= v28 ) + { + LODWORD(v29) = 0; + HIDWORD(v29) = SLOWORD(pODMRenderParams->int_fov_rad); + pParticles[uID]._screenspace_scale = v29 / X_4; + pParticles[uID].uScreenSpaceX = pViewport->uScreenCenterX - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, v16) >> 16); + pParticles[uID].uScreenSpaceY = pViewport->uScreenCenterY - ((signed int)fixpoint_mul(pParticles[uID]._screenspace_scale, v40) >> 16); + pParticles[uID]._screenspace_scale = fixpoint_mul(fixpoint_from_float(pParticles[uID].flt_28), pParticles[uID]._screenspace_scale); + pParticles[uID].sZValue = X_4; + if ( pParticles[uID].uScreenSpaceX >= (signed int)pViewport->uViewportTL_X + && pParticles[uID].uScreenSpaceX < (signed int)pViewport->uViewportBR_X + && pParticles[uID].uScreenSpaceY >= (signed int)pViewport->uViewportTL_Y + && pParticles[uID].uScreenSpaceY < (signed int)pViewport->uViewportBR_Y ) + return true; + } + return false; +} + +//----- (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.sParentBillboardID = -1; + + for (uint i = uStartParticle; i < uEndParticle; ++i) + { + Particle* p = &pParticles[i]; + + if (p->type == ParticleType_Invalid) + continue; + + if (!ViewProject_TrueIfStillVisible_BLV(i)) + continue; + + if (p->uScreenSpaceX >= pBLVRenderParams->uViewportX && + p->uScreenSpaceX < pBLVRenderParams->uViewportZ && + p->uScreenSpaceY >= pBLVRenderParams->uViewportY && + p->uScreenSpaceY < pBLVRenderParams->uViewportW) + { + /*if (!pRenderer->pRenderD3D) + { + __debugbreak(); + v11 = 13 * p->_screenspace_scale >> 16; + if ( v11 > 30 ) + v11 = 30; + v12 = p->uScreenSpaceY - v11; + v13 = p->uScreenSpaceX - (v11 >> 1); + if ( v13 + v11 < (signed int)pViewport->uViewportTL_X + || v13 >= (signed int)pViewport->uViewportBR_X + || v12 + v11 < (signed int)pViewport->uViewportTL_Y + || v12 >= (signed int)pViewport->uViewportBR_Y ) + { + ; + } + else + { + pRenderer->MakeParticleBillboardAndPush_BLV_Software(v13, v12, p->sZValue, p->uLightColor_bgr, v11); + } + } + else*/ + + if (p->type & ParticleType_Diffuse) + { + //v14 = &pParticles[i]; + v15._screenspace_x_scaler_packedfloat = p->_screenspace_scale / 4; + v15._screenspace_y_scaler_packedfloat = p->_screenspace_scale / 4; + v15.uScreenSpaceX = p->uScreenSpaceX; + v15.uScreenSpaceY = p->uScreenSpaceY; + v15.sZValue = p->sZValue; + pRenderer->MakeParticleBillboardAndPush_BLV(&v15, 0, p->uLightColor_bgr, p->angle); + return; + } + if (p->type & ParticleType_Line) + { + 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_bgr; + 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_bgr; + 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->type & ParticleType_Bitmap) + { + v15._screenspace_x_scaler_packedfloat = p->_screenspace_scale; + v15._screenspace_y_scaler_packedfloat = p->_screenspace_scale; + v15.uScreenSpaceX = p->uScreenSpaceX; + v15.uScreenSpaceY = p->uScreenSpaceY; + v15.sZValue = p->sZValue; + pRenderer->MakeParticleBillboardAndPush_BLV(&v15, pBitmaps_LOD->pHardwareTextures[p->uTextureID], p->uLightColor_bgr, p->angle); + } + if (p->type & ParticleType_Sprite) + { + v15._screenspace_x_scaler_packedfloat = p->_screenspace_scale; + v15._screenspace_y_scaler_packedfloat = p->_screenspace_scale; + v15.uScreenSpaceX = p->uScreenSpaceX; + v15.uScreenSpaceY = p->uScreenSpaceY; + v15.sZValue = p->sZValue; + pRenderer->MakeParticleBillboardAndPush_BLV(&v15, pSprites_LOD->pHardwareSprites[p->uTextureID].pTexture, p->uLightColor_bgr, p->angle); + } + } + } +} + +//----- (0048BEEF) -------------------------------------------------------- +void ParticleEngine::DrawParticles_ODM() +{ + ParticleEngine *pParticleEngine; // esi@1 + //int pParticleNum; // 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 pNumLines; // eax@8 +// int v10; // eax@14 +// int v11; // ecx@16 +// int v12; // edx@16 + //Particle *pParticle; // eax@24 + RenderBillboardTransform_local0 pBillboard; // [sp+Ch] [bp-58h]@1 + //int v15; // [sp+5Ch] [bp-8h]@9 +// int v16; // [sp+60h] [bp-4h]@1 + + pBillboard.sParentBillboardID = -1; + pParticleEngine = this; + //v2 = this->uStartParticle; + //v5 = v2 > this->uEndParticle;// v5 = __OFSUB__(v2, this->uEndParticle); + //v3 = v2 == this->uEndParticle; + //v4 = v2 - this->uEndParticle < 0; + //v16 = this->uStartParticle; + for (uint i = uStartParticle; i <= uEndParticle; ++i) + { + Particle* particle = &pParticles[i]; + if (particle->type == ParticleType_Invalid || !ViewProject_TrueIfStillVisible_ODM(i)) + continue; + + /*if ( !pRenderer->pRenderD3D ) + { + __debugbreak(); + v10 = 13 * particle->_screenspace_scale >> 16; + if ( v10 > 30 ) + v10 = 30; + v11 = particle->uScreenSpaceX - (v10 >> 1); + v12 = particle->uScreenSpaceY - v10; + if ( v11 + v10 < pViewport->uViewportTL_X + || v11 >= pViewport->uViewportBR_X + || particle->uScreenSpaceY < pViewport->uViewportTL_Y + || v12 >= (signed int)pViewport->uViewportBR_Y ) + { + ; + } + else + { + pRenderer->MakeParticleBillboardAndPush_BLV_Software(v11, v12, particle->sZValue, particle->uLightColor_bgr, v10); + } + } + else*/ + + //v8 = *(_DWORD *)(v7 - 82); + if (particle->type & ParticleType_Diffuse) + { + pBillboard._screenspace_x_scaler_packedfloat = particle->_screenspace_scale / 4; + pBillboard._screenspace_y_scaler_packedfloat = particle->_screenspace_scale / 4; + pBillboard.uScreenSpaceX = particle->uScreenSpaceX; + pBillboard.uScreenSpaceY = particle->uScreenSpaceY; + pBillboard.sZValue = particle->sZValue; + pRenderer->MakeParticleBillboardAndPush_ODM(&pBillboard, 0, particle->uLightColor_bgr, particle->angle); + return; + } + if (particle->type & ParticleType_Line) + { + if (pLines.uNumLines < 100) + { + pLines.pLineVertices[2 * pLines.uNumLines].pos.x = particle->uScreenSpaceX; + pLines.pLineVertices[2 * pLines.uNumLines].pos.y = particle->uScreenSpaceY; + pLines.pLineVertices[2 * pLines.uNumLines].pos.z = 1.0 - 1.0 / ((double)particle->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); + pLines.pLineVertices[2 * pLines.uNumLines].rhw = 1.0; + pLines.pLineVertices[2 * pLines.uNumLines].diffuse = particle->uLightColor_bgr; + 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 = particle->uScreenSpaceZ; + pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.y = particle->uScreenSpaceW; + pLines.pLineVertices[2 * pLines.uNumLines + 1].pos.z = 1.0 - 1.0 / ((double)particle->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); + pLines.pLineVertices[2 * pLines.uNumLines + 1].rhw = 1.0; + pLines.pLineVertices[2 * pLines.uNumLines + 1].diffuse = particle->uLightColor_bgr; + 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; + pLines.uNumLines++; + } + } + if (particle->type & ParticleType_Bitmap) + { + pBillboard._screenspace_x_scaler_packedfloat = particle->_screenspace_scale; + pBillboard._screenspace_y_scaler_packedfloat = particle->_screenspace_scale; + pBillboard.uScreenSpaceX = particle->uScreenSpaceX; + pBillboard.uScreenSpaceY = particle->uScreenSpaceY; + pBillboard.sZValue = particle->sZValue; + pRenderer->MakeParticleBillboardAndPush_ODM(&pBillboard, pBitmaps_LOD->pHardwareTextures[particle->uTextureID], particle->uLightColor_bgr, particle->angle); + } + if (particle->type & ParticleType_Sprite) + { + pBillboard._screenspace_x_scaler_packedfloat = particle->_screenspace_scale; + pBillboard._screenspace_y_scaler_packedfloat = particle->_screenspace_scale; + pBillboard.uScreenSpaceX = particle->uScreenSpaceX; + pBillboard.uScreenSpaceY = particle->uScreenSpaceY; + pBillboard.sZValue = particle->sZValue; + pRenderer->MakeParticleBillboardAndPush_ODM(&pBillboard, pSprites_LOD->pHardwareSprites[particle->uTextureID].pTexture, particle->uLightColor_bgr, particle->angle); + } + } +} \ No newline at end of file