mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-30 08:47:58 +03:00
373 lines
No EOL
8.5 KiB
C++
373 lines
No EOL
8.5 KiB
C++
#include "framework.h"
|
|
#include "effects\tomb4fx.h"
|
|
#include "lara.h"
|
|
#include "effects\effects.h"
|
|
#include "draw.h"
|
|
#include "setup.h"
|
|
#include "level.h"
|
|
#include "Sound\sound.h"
|
|
#include "effects\bubble.h"
|
|
#include "trmath.h"
|
|
#include "GameFlowScript.h"
|
|
#include "smoke.h"
|
|
#include "drip.h"
|
|
#include <effects.h>
|
|
#include "Renderer11.h"
|
|
#include <effects.h>
|
|
#include <draw.h>
|
|
|
|
using std::vector;
|
|
using TEN::Renderer::g_Renderer;
|
|
|
|
int LightningRandomSeed = 0x0D371F947;
|
|
float FloatSinCosTable[8192];
|
|
PHD_VECTOR LightningPos[6];
|
|
short LightningBuffer[1024];
|
|
|
|
void InitialiseFloatSinCosTable()
|
|
{
|
|
for (int i = 0; i < 8192; i++)
|
|
{
|
|
FloatSinCosTable[i] = sin(i * 0.000095873802f);
|
|
}
|
|
}
|
|
|
|
void UpdateLightning()
|
|
{
|
|
for (int i = 0; i < 16; i++)
|
|
{
|
|
ENERGY_ARC* arc = &EnergyArcs[i];
|
|
|
|
if (arc->life > 0)
|
|
{
|
|
arc->life -= 2;
|
|
if (arc->life)
|
|
{
|
|
int* positions = (int*)&arc->pos2;
|
|
for (int j = 0; j < 9; j++)
|
|
{
|
|
*positions += 2 * arc->interpolation[j];
|
|
arc->interpolation[j] = (signed char)(arc->interpolation[j] - (arc->interpolation[j] >> 4));
|
|
positions++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void TriggerLightning(PHD_VECTOR* src, PHD_VECTOR* dest, char amplitude, byte r, byte g, byte b, byte life, char flags, char width, char segments)
|
|
{
|
|
ENERGY_ARC* arc = NULL;
|
|
for (int i = 0; i < 16; i++)
|
|
{
|
|
if (EnergyArcs[i].life == 0)
|
|
{
|
|
arc = &EnergyArcs[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (arc == NULL)
|
|
return;
|
|
|
|
arc->pos1 = *src;
|
|
arc->pos2.x = (dest->x + 3 * src->x) >> 2;
|
|
arc->pos2.y = (dest->y + 3 * src->y) >> 2;
|
|
arc->pos2.z = (dest->z + 3 * src->z) >> 2;
|
|
arc->pos3.x = (src->x + 3 * dest->x) >> 2;
|
|
arc->pos3.y = (src->y + 3 * dest->y) >> 2;
|
|
arc->pos3.z = (src->z + 3 * dest->z) >> 2;
|
|
arc->pos4 = *dest;
|
|
|
|
for (int i = 0; i < 9; i++)
|
|
{
|
|
if (arc->flags & 2 || i < 6)
|
|
arc->interpolation[i] = ((byte)(GetRandomControl() % amplitude) - (byte)(amplitude >> 1));
|
|
else
|
|
arc->interpolation[i] = 0;
|
|
}
|
|
|
|
arc->flags = flags;
|
|
arc->r = r;
|
|
arc->g = g;
|
|
arc->b = b;
|
|
arc->life = life;
|
|
arc->segments = segments;
|
|
arc->amplitude = amplitude;
|
|
arc->width = width;
|
|
}
|
|
|
|
void DrawLightningNew()
|
|
{
|
|
/*Vector4 positions[32];
|
|
Vector3 transformed[32];
|
|
short clipBuffer[32];
|
|
byte r, g, b;
|
|
ENERGY_ARC_VBUFFER vbuffer[32];
|
|
|
|
for (int i = 0; i < 16; i++)
|
|
{
|
|
ENERGY_ARC* arc = &EnergyArcs[i];
|
|
|
|
if (arc->life)
|
|
{
|
|
float dx = arc->pos0.x - LaraItem->pos.xPos;
|
|
float dy = arc->pos0.y - LaraItem->pos.yPos;
|
|
float dz = arc->pos0.z - LaraItem->pos.zPos;
|
|
|
|
float x1 = arc->pos1.x - arc->pos0.x;
|
|
float y1 = arc->pos1.y - arc->pos0.y;
|
|
float z1 = arc->pos1.z - arc->pos0.z;
|
|
|
|
float x2 = arc->pos2.x - arc->pos0.x;
|
|
float y2 = arc->pos2.y - arc->pos0.y;
|
|
float z2 = arc->pos2.z - arc->pos0.z;
|
|
|
|
float x3 = arc->pos3.x - arc->pos0.x;
|
|
float y3 = arc->pos3.y - arc->pos0.y;
|
|
float z3 = arc->pos3.z - arc->pos0.z;
|
|
|
|
double factor = 0;
|
|
|
|
int seed = LightningRandomSeed;
|
|
|
|
for (int j = 0; j < 32; j++)
|
|
{
|
|
float rx = 0;
|
|
float ry = 0;
|
|
float rz = 0;
|
|
|
|
if (j > 0 && j < 31)
|
|
{
|
|
// random number generator
|
|
int rndX = 1103515245 * seed + 12345;
|
|
int rndY = 1103515245 * rndX + 12345;
|
|
int rndZ = 1103515245 * rndY + 12345;
|
|
|
|
float rx = (float)(((rndX >> 10) & 0xF) - 8);
|
|
float ry = (float)(((rndY >> 10) & 0xF) - 8);
|
|
float rz = (float)(((rndZ >> 10) & 0xF) - 8);
|
|
|
|
LightningRandomSeed = rndZ;
|
|
}
|
|
|
|
float x = (1.0 - factor) * SQUARE(factor) * 4.0;
|
|
float y = (2 * factor - 1.0) * SQUARE(factor);
|
|
float z = SQUARE(1.0 - factor) * factor * 4.0;
|
|
|
|
positions[j].x = x * x1 + y * x2 + z * x3 + 0.0 + rx + dx;
|
|
positions[j].y = x * y1 + y * y2 + z * y3 + 0.0 + ry + dy;
|
|
positions[j].z = x * z1 + y * z2 + z * z3 + 0.0 + rz + dz;
|
|
positions[j].w = 1.0;
|
|
|
|
factor += 0.03125f;
|
|
}
|
|
|
|
LightningRandomSeed = seed;
|
|
|
|
for (int j = 0; j < 32; j++)
|
|
{
|
|
Vector3 transformed = Vector4::Transform()
|
|
pPosY = *(pPosZ - 1);
|
|
pPosX = *(pPosZ - 2);
|
|
pPosY2 = pPosY;
|
|
v36 = transform_view._21 * pPosY;
|
|
v37 = 0;
|
|
tx = transform_view._31 * *pPosZ + v36 + transform_view._11 * pPosX + transform_view._41;
|
|
ty = transform_view._22 * pPosY2 + transform_view._12 * pPosX + transform_view._32 * *pPosZ + transform_view._42;
|
|
c_sz = transform_view._33 * *pPosZ
|
|
+ transform_view._23 * pPosY2
|
|
+ transform_view._13 * pPosX
|
|
+ transform_view._43;
|
|
if (c_sz < znear)
|
|
v37 = -128;
|
|
t_persp = f_persp / c_sz;
|
|
c_sx = t_persp * tx + f_centerx;
|
|
*(D3DTLVERTEX_cy - 1) = c_sx;
|
|
*D3DTLVERTEX_cy = t_persp * ty + f_centery;
|
|
D3DTLVERTEX_cy[1] = t_persp * f_oneopersp;
|
|
if (c_sx >= winX)
|
|
{
|
|
if ((double)phd_winxmax < *(D3DTLVERTEX_cy - 1))
|
|
v37 += 2;
|
|
}
|
|
else
|
|
{
|
|
++v37;
|
|
}
|
|
if (*D3DTLVERTEX_cy >= winY)
|
|
{
|
|
if ((double)phd_winymax < *D3DTLVERTEX_cy)
|
|
v37 += 8;
|
|
}
|
|
else
|
|
{
|
|
v37 += 4;
|
|
}
|
|
D3DTLVERTEX_cy[2] = c_sz;
|
|
*(_WORD*)someFlag = v37;
|
|
D3DTLVERTEX_cy[3] = tx;
|
|
D3DTLVERTEX_cy[4] = ty;
|
|
someFlag += 2;
|
|
pPosZ += 4;
|
|
D3DTLVERTEX_cy += 8;
|
|
--v32;
|
|
}
|
|
}
|
|
|
|
if (arc->life >= 16)
|
|
{
|
|
r = arc->r;
|
|
g = arc->g;
|
|
b = arc->b;
|
|
}
|
|
else
|
|
{
|
|
r = arc->r >> 4;
|
|
g = arc->g >> 4;
|
|
b = arc->b >> 4;
|
|
}
|
|
|
|
float length = 0.0;
|
|
float width = (float)(arc->width >> 1);
|
|
|
|
if (arc->flags & 8)
|
|
{
|
|
length = width * 0.125;
|
|
width = 0.0;
|
|
}
|
|
else if (arc->flags & 4)
|
|
{
|
|
length = -(width * 0.03125);
|
|
}
|
|
|
|
for (int j = 0; j < 32; j++)
|
|
{
|
|
short angle = -phd_atan(vbuffer);
|
|
float sinAngle = FloatSinCosTable[angle + 0x4000];
|
|
width = max(width, 0);
|
|
|
|
}
|
|
|
|
v45 = 0;
|
|
v46 = (float*)&v125;
|
|
do
|
|
{
|
|
v47 = -j_phd_atan((signed __int64)(v46[7] - *(v46 - 1)), (signed __int64)(v46[8] - *v46));
|
|
v48 = FloatSinCosTable[(unsigned __int16)(v47 + 0x4000)];
|
|
v49 = v88;
|
|
if (v88 <= 0.0)
|
|
v49 = 2.0;
|
|
v50 = flt_51D15C / v46[2] * v49;
|
|
v51 = (*v42 & 8) == 0;
|
|
*v86 = FloatSinCosTable[(unsigned __int16)v47] * v50;
|
|
v86[1] = v48 * v50;
|
|
v88 = v95 + v88;
|
|
if (!v51 && v45 == 8)
|
|
{
|
|
if (*v42 & 4)
|
|
v95 = (double)(unsigned __int8)(*(_BYTE*)(arc + 53) >> 1) * -0.035714287;
|
|
else
|
|
v95 = 0.0;
|
|
*v42 &= 0xF7u;
|
|
}
|
|
v46 += 8;
|
|
++v45;
|
|
v86 += 4;
|
|
} while (v45 < 32);
|
|
}
|
|
}*/
|
|
}
|
|
|
|
// It just works (tm)! Again, as spotcams Spline() :-)
|
|
int LSpline(int x, int* knots, int nk)
|
|
{
|
|
int64_t v3 = (x * (int64_t)(nk - 3)) * 65536 / 65536; // lmao?
|
|
int32_t v4 = (int32_t)v3 / 65536;
|
|
if (((int32_t)v3 / 65536) >= nk - 3)
|
|
v4 = nk - 4;
|
|
int32_t v5 = knots[3 * v4];
|
|
int32_t v6 = knots[3 * v4 + 6];
|
|
int32_t nka = knots[3 * v4 + 9] / 2;
|
|
int32_t v7 = knots[3 * v4 + 3];
|
|
return (int32_t)(v7
|
|
+ (int64_t)(uint64_t)(((int32_t)((~v5 / 2)
|
|
+ (v6 / 2)
|
|
+ (int64_t)(uint64_t)(((int32_t)(v5
|
|
+ (int64_t)(uint64_t)((((~v5 / 2)
|
|
+ nka
|
|
+ v7
|
|
+ (v7 / 2)
|
|
- (v6 / 2)
|
|
- v6)
|
|
* (int64_t)((int32_t)v3 - (v4 * 65536))) / 65536)
|
|
- 2 * v7
|
|
+ 2 * v6
|
|
- (v7 / 2)
|
|
- nka)
|
|
* (int64_t)((int32_t)v3 - (v4 * 65536))) / 65536))
|
|
* (int64_t)((int32_t)v3 - (v4 * 65536))) / 65536));
|
|
}
|
|
|
|
void CalcLightningSpline(PHD_VECTOR* pos, short* buffer, ENERGY_ARC* arc)
|
|
{
|
|
buffer[0] = pos->x;
|
|
buffer[1] = pos->y;
|
|
buffer[2] = pos->z;
|
|
|
|
buffer += 4;
|
|
|
|
if (arc->flags & 1)
|
|
{
|
|
int dp = 65536 / (3 * arc->segments - 1);
|
|
int x = dp;
|
|
|
|
if (3 * arc->segments - 2 > 0)
|
|
{
|
|
for (int i = 3 * arc->segments - 2; i > 0; i--)
|
|
{
|
|
short sx = LSpline(x, &pos->x, 6);
|
|
buffer[0] = sx + (GetRandomControl() & 0xF) - 8;
|
|
short sy = LSpline(x, &pos->y, 6);
|
|
buffer[1] = sy + (GetRandomControl() & 0xF) - 8;
|
|
short sz = LSpline(x, &pos->z, 6);
|
|
buffer[2] = sz + (GetRandomControl() & 0xF) - 8;
|
|
|
|
x += dp;
|
|
buffer += 4;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int segments = 3 * arc->segments - 1;
|
|
|
|
int dx = (pos[5].x - pos->x) / segments;
|
|
int dy = (pos[5].y - pos->y) / segments;
|
|
int dz = (pos[5].z - pos->z) / segments;
|
|
|
|
int x = dx + (GetRandomControl() % (2 * arc->amplitude)) - arc->amplitude + pos->x;
|
|
int y = dy + (GetRandomControl() % (2 * arc->amplitude)) - arc->amplitude + pos->y;
|
|
int z = dz + (GetRandomControl() % (2 * arc->amplitude)) - arc->amplitude + pos->z;
|
|
|
|
if (3 * arc->segments - 2 > 0)
|
|
{
|
|
for (int i = 3 * arc->segments - 2; i > 0; i--)
|
|
{
|
|
buffer[0] = x;
|
|
buffer[1] = y;
|
|
buffer[2] = z;
|
|
|
|
x += dx + GetRandomControl() % (2 * arc->amplitude) - arc->amplitude;
|
|
y += dy + GetRandomControl() % (2 * arc->amplitude) - arc->amplitude;
|
|
z += dz + GetRandomControl() % (2 * arc->amplitude) - arc->amplitude;
|
|
|
|
buffer += 4;
|
|
}
|
|
}
|
|
}
|
|
|
|
buffer[0] = pos[5].x;
|
|
buffer[1] = pos[5].y;
|
|
buffer[2] = pos[5].z;
|
|
} |