particle: Ghidra decompilations, particle_sse.zig scaffold, bench

- Ghidra C decompilation of RenderParticleSprites (422 lines) and 5
  helper functions (calculateColorValues, matVec3Transform, etc.)
- particle_sse.zig with calcColorValues_SSE (10.7x bench but cache-miss
  bound in-game — needs inlining into full function replacement)
- Bench harness for calcColorValues with correctness check
- build.zig: particle_sse as separate ReleaseFast compilation unit
- colorDetour reverted to pass-through (SSE has no in-game effect due
  to L1 cache misses on scattered ColorCtx structs)
This commit is contained in:
MarcelineVQ
2026-03-23 21:56:57 -07:00
parent fec9ac9952
commit d205693dbb
6 changed files with 962 additions and 1 deletions
@@ -0,0 +1,422 @@
openjdk version "21.0.10" 2026-01-20
OpenJDK Runtime Environment (build 21.0.10+7)
OpenJDK 64-Bit Server VM (build 21.0.10+7, mixed mode)
// RenderParticleSprites @ 0x7B2A50
// Decompiled by Ghidra
/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */
undefined * __thiscall
RenderParticleSprites(ParticleSystemRenderer *this,float *particleData,float **vertexBuffers)
{
undefined *puVar1;
int loopIndex;
uint texLoopIndex;
float *particleDataPtr;
int nextLoopIndex;
undefined **textureOffsetPtr;
undefined **textureVPtr;
uint colorDeltaR;
float10 sinRotation;
float *rotMatrix_m00;
float *rotMatrix_m01;
float *rotMatrix_m02;
float *rotMatrix_m10;
float *rotMatrix_m11;
float *rotMatrix_m12;
float *rotMatrix_m20;
float *rotMatrix_m21;
float *rotMatrix_m22;
float *transformedVelocityVector;
float *transformedVertexZ;
float *negVelocityX;
float *transformedVertexX;
float *negVelocityZ;
float *negVelocityY;
uint *colorData1;
uint *colorData2;
float *textureU;
float *textureV;
float *particleTimeIndex;
float worldPosX;
float worldPosY;
float worldPosZ;
float *vertexX;
float *vertexY;
float *vertexZ;
uint *colorValue;
float *rotationAngle;
float spriteScale;
float *particleFlags;
float textureUIndex;
float textureVIndex;
float clampedParticleTime;
undefined *clampedTimePtr;
float10 cosRotation;
float cosValue;
float scaleFactor;
float tempFloat1;
float textureCoordV;
float velocityDirection;
float *vertexBuffer;
float **vertexBufferPtr;
float zDepth;
particleDataPtr = particleData;
colorDeltaR = 0;
/* Reading colorDeltaB+2 - likely wrong field mapping */
/* Reading texCoordBase1+2 - another +2 offset pattern */
if (((float)this->colorPaletteArray[2].renderFlags_source < StaticFloat1_0) ||
(*(float *)&this->colorPaletteArray[2].renderFlags_prefix !=
(float)COLLISION_PLANE_ZERO_THRESHOLD)) {
puVar1 = (undefined *)(this->colorPaletteArray[2].texCoordDelta2 * particleData[7]);
clampedTimePtr = COLLISION_PLANE_ZERO_THRESHOLD;
if (((float)COLLISION_PLANE_ZERO_THRESHOLD <= (float)puVar1) &&
(clampedTimePtr = puVar1, (float)_DAT_007ffe58 <= (float)puVar1)) {
clampedTimePtr = _DAT_007ffe58;
}
particleTimeIndex = (float *)((float)clampedTimePtr + _DAT_008029cc);
colorDeltaR = ((uint)particleTimeIndex >> 0xe) + ((uint)particleData >> 5) & 0x7f;
}
if (((float)this->colorPaletteArray[2].renderFlags_source < StaticFloat1_0) &&
((float)this->colorPaletteArray[2].renderFlags_source <
*(float *)(&g_particleDepthBuffer + colorDeltaR * 4))) {
return (undefined *)0x0;
}
colorValue = (uint *)0x0;
calculateParticleColorAndScale
((OrientationData *)
(this->orientationDataArray + (uint)*(byte *)(particleData + 3) * 0x60 + -0x12),
particleData[7],*(float *)((int)&this->colorPaletteArray[2].colorDeltaR + 2),
(byte *)&colorValue,(uint *)&colorData1,(uint *)&colorData2,&spriteScale);
loopIndex = UpdateLightingOffset();
if (*(int *)(loopIndex + 0x1c) == 1) {
colorValue = (uint *)CONCAT31(CONCAT21(CONCAT11((char)((uint)colorValue >> 0x18),
(char)colorValue),(char)((uint)colorValue >> 8))
,(char)((uint)colorValue >> 0x10));
rotationAngle = (float *)colorValue;
}
if (*(float *)&this->colorPaletteArray[2].renderFlags_prefix !=
(float)COLLISION_PLANE_ZERO_THRESHOLD) {
spriteScale = (*(float *)(&g_particleDepthBuffer + colorDeltaR * 4) *
*(float *)&this->colorPaletteArray[2].renderFlags_prefix +
*(float *)&this->colorPaletteArray[2].field_0x1e_source) * spriteScale;
}
colorDeltaR._0_2_ = this->colorPaletteArray[2].padding_06;
colorDeltaR._2_2_ = this->colorPaletteArray[2].texCoordDelta2_prefix;
if ((colorDeltaR & 0x200) != 0) {
spriteScale = spriteScale * *(float *)(this->colorPaletteArray[3].padding_50_53 + 2);
}
transformVector3ByMatrix4x4(&worldPosX,particleDataPtr,(float *)&g_worldMatrix);
vertexBufferPtr = vertexBuffers;
texLoopIndex._0_2_ = this->colorPaletteArray[2].padding_06;
texLoopIndex._2_2_ = this->colorPaletteArray[2].texCoordDelta2_prefix;
if ((texLoopIndex & 4) != 0) {
textureUIndex =
(float)(*(int *)(this->colorPaletteArray[1].final_padding + 6) - 1U & (uint)colorData1);
textureVIndex = 0.0;
textureU = (float *)((float)(uint)textureUIndex * this->textureScaleU);
textureV = (float *)((float)((int)colorData1 >> (SUB41(this->uvCoordinateScale,0) & 0x1f)) *
this->textureScaleV);
if (this->colorPaletteArray[1].texCoordBase1 == (float)COLLISION_PLANE_ZERO_THRESHOLD) {
if ((texLoopIndex & 0x2000) == 0) {
loopIndex = 0;
do {
vertexBuffer = *vertexBuffers;
nextLoopIndex = loopIndex + 8;
vertexX = (float *)(spriteScale * *(float *)((int)&g_billboardVertexOffsetsX + loopIndex)
+ worldPosX);
vertexY = (float *)(spriteScale * *(float *)((int)&g_billboardVertexOffsetsY + loopIndex)
+ worldPosY);
*vertexBuffer = (float)vertexX;
vertexBuffer[1] = (float)vertexY;
vertexZ = (float *)worldPosZ;
vertexBuffer[2] = worldPosZ;
vertexBuffer = vertexBuffers[1];
*vertexBuffer = (float)g_lightDirectionX;
vertexBuffer[1] = (float)g_lightDirectionY;
vertexBuffer[2] = (float)g_lightDirectionZ;
*vertexBuffers[2] = (float)colorValue;
vertexBuffer = vertexBuffers[3];
tempFloat1 = *(float *)((int)&g_spriteTextureOffsetsV + loopIndex);
textureCoordV = this->textureScaleV;
*vertexBuffer =
*(float *)((int)&g_spriteTextureOffsetsU + loopIndex) * this->textureScaleU +
(float)textureU;
vertexBuffer[1] = tempFloat1 * textureCoordV + (float)textureV;
vertexBuffers[8] = (float *)((int)vertexBuffers[8] + 1);
*vertexBuffers = (float *)((int)*vertexBuffers + (int)vertexBuffers[4]);
vertexBuffers[1] = (float *)((int)vertexBuffers[1] + (int)vertexBuffers[5]);
vertexBuffers[2] = (float *)((int)vertexBuffers[2] + (int)vertexBuffers[6]);
vertexBuffers[3] = (float *)((int)vertexBuffers[3] + (int)vertexBuffers[7]);
loopIndex = nextLoopIndex;
} while (nextLoopIndex != 0x20);
}
else {
vertexBuffers = (float **)0x4;
textureVPtr = &g_transformedVertex1_Z;
textureOffsetPtr = &g_spriteTextureOffsetsV;
do {
particleDataPtr = *vertexBufferPtr;
transformedVertexZ = (float *)(spriteScale * (float)*textureVPtr);
vertexX = (float *)(spriteScale * (float)textureVPtr[-2] + worldPosX);
vertexY = (float *)(spriteScale * (float)textureVPtr[-1] + worldPosY);
vertexZ = (float *)((float)transformedVertexZ + worldPosZ);
*particleDataPtr = (float)vertexX;
particleDataPtr[1] = (float)vertexY;
particleDataPtr[2] = (float)vertexZ;
particleDataPtr = vertexBufferPtr[1];
*particleDataPtr = (float)g_lightDirectionX;
particleDataPtr[1] = (float)g_lightDirectionY;
particleDataPtr[2] = (float)g_lightDirectionZ;
*vertexBufferPtr[2] = (float)colorValue;
particleDataPtr = vertexBufferPtr[3];
tempFloat1 = this->textureScaleV;
clampedParticleTime = (float)*textureOffsetPtr;
*particleDataPtr = (float)textureOffsetPtr[-1] * this->textureScaleU + (float)textureU;
particleDataPtr[1] = tempFloat1 * clampedParticleTime + (float)textureV;
vertexBufferPtr[8] = (float *)((int)vertexBufferPtr[8] + 1);
*vertexBufferPtr = (float *)((int)*vertexBufferPtr + (int)vertexBufferPtr[4]);
vertexBufferPtr[1] = (float *)((int)vertexBufferPtr[1] + (int)vertexBufferPtr[5]);
vertexBufferPtr[2] = (float *)((int)vertexBufferPtr[2] + (int)vertexBufferPtr[6]);
vertexBuffers = (float **)((int)vertexBuffers + -1);
vertexBufferPtr[3] = (float *)((int)vertexBufferPtr[3] + (int)vertexBufferPtr[7]);
textureVPtr = textureVPtr + 3;
textureOffsetPtr = textureOffsetPtr + 2;
particleDataPtr = particleData;
} while (vertexBuffers != (float **)0x0);
}
}
else {
rotationAngle = (float *)(this->colorPaletteArray[1].texCoordBase1 * particleDataPtr[7]);
if (((char)((ushort)(undefined2)texLoopIndex >> 8) < '\0') &&
(((uint)particleDataPtr & 0x20) != 0)) {
rotationAngle = (float *)-(float)rotationAngle;
}
if ((texLoopIndex & 0x2000) == 0) {
particleTimeIndex = (float *)&particleData;
cosRotation = (float10)fcos((float10)(float)rotationAngle);
sinRotation = (float10)fsin((float10)(float)rotationAngle);
colorDeltaR = 0;
do {
tempFloat1 = *(float *)((int)&g_billboardVertexOffsetsX + colorDeltaR);
textureCoordV = *(float *)((int)&g_billboardVertexOffsetsY + colorDeltaR);
texLoopIndex = colorDeltaR + 8;
**vertexBuffers =
(tempFloat1 * (float)cosRotation * spriteScale + worldPosX) -
textureCoordV * (float)sinRotation * spriteScale;
(*vertexBuffers)[1] =
textureCoordV * (float)cosRotation * spriteScale +
tempFloat1 * (float)sinRotation * spriteScale + worldPosY;
(*vertexBuffers)[2] = worldPosZ;
vertexBuffer = vertexBuffers[1];
*vertexBuffer = (float)g_lightDirectionX;
vertexBuffer[1] = (float)g_lightDirectionY;
vertexBuffer[2] = (float)g_lightDirectionZ;
*vertexBuffers[2] = (float)colorValue;
vertexBuffer = vertexBuffers[3];
tempFloat1 = *(float *)((int)&g_spriteTextureOffsetsV + colorDeltaR);
textureCoordV = this->textureScaleV;
*vertexBuffer =
*(float *)((int)&g_spriteTextureOffsetsU + colorDeltaR) * this->textureScaleU +
(float)textureU;
vertexBuffer[1] = tempFloat1 * textureCoordV + (float)textureV;
vertexBuffers[8] = (float *)((int)vertexBuffers[8] + 1);
*vertexBuffers = (float *)((int)*vertexBuffers + (int)vertexBuffers[4]);
vertexBuffers[1] = (float *)((int)vertexBuffers[1] + (int)vertexBuffers[5]);
vertexBuffers[2] = (float *)((int)vertexBuffers[2] + (int)vertexBuffers[6]);
vertexBuffers[3] = (float *)((int)vertexBuffers[3] + (int)vertexBuffers[7]);
colorDeltaR = texLoopIndex;
} while (texLoopIndex < 0x20);
}
else {
vertexBuffers = (float **)&g_spriteTextureOffsetsV;
textureVPtr = &g_transformedVertex1_Y;
particleTimeIndex = (float *)0x4;
do {
createAxisAngleRotationMatrix3x3
((float *)&rotMatrix_m00,
(float *)((int)&this->colorPaletteArray[4].renderFlags + 2),
(float)rotationAngle,'\x01');
particleDataPtr = *vertexBufferPtr;
transformedVertexZ =
(float *)((float)rotMatrix_m20 * (float)textureVPtr[-1] +
(float)rotMatrix_m22 * (float)textureVPtr[1] +
(float)rotMatrix_m21 * (float)*textureVPtr);
transformedVertexX =
(float *)(((float)rotMatrix_m02 * (float)textureVPtr[1] +
(float)rotMatrix_m01 * (float)*textureVPtr +
(float)rotMatrix_m00 * (float)textureVPtr[-1]) * spriteScale);
vertexX = (float *)((float)transformedVertexX + worldPosX);
vertexY = (float *)(((float)rotMatrix_m10 * (float)textureVPtr[-1] +
(float)rotMatrix_m12 * (float)textureVPtr[1] +
(float)rotMatrix_m11 * (float)*textureVPtr) * spriteScale + worldPosY)
;
vertexZ = (float *)((float)transformedVertexZ * spriteScale + worldPosZ);
*particleDataPtr = (float)vertexX;
particleDataPtr[1] = (float)vertexY;
particleDataPtr[2] = (float)vertexZ;
particleDataPtr = vertexBufferPtr[1];
*particleDataPtr = (float)g_lightDirectionX;
particleDataPtr[1] = (float)g_lightDirectionY;
particleDataPtr[2] = (float)g_lightDirectionZ;
*vertexBufferPtr[2] = (float)colorValue;
textureUIndex = (float)vertexBuffers[-1] * this->textureScaleU + (float)textureU;
textureVIndex = (float)*vertexBuffers * this->textureScaleV + (float)textureV;
particleDataPtr = vertexBufferPtr[3];
*particleDataPtr = textureUIndex;
particleDataPtr[1] = textureVIndex;
vertexBuffers = vertexBuffers + 2;
textureVPtr = textureVPtr + 3;
vertexBufferPtr[8] = (float *)((int)vertexBufferPtr[8] + 1);
*vertexBufferPtr = (float *)((int)*vertexBufferPtr + (int)vertexBufferPtr[4]);
vertexBufferPtr[1] = (float *)((int)vertexBufferPtr[1] + (int)vertexBufferPtr[5]);
vertexBufferPtr[2] = (float *)((int)vertexBufferPtr[2] + (int)vertexBufferPtr[6]);
particleTimeIndex = (float *)((int)particleTimeIndex + -1);
vertexBufferPtr[3] = (float *)((int)vertexBufferPtr[3] + (int)vertexBufferPtr[7]);
} while (particleTimeIndex != (float *)0x0);
particleTimeIndex = (float *)0x0;
particleDataPtr = particleData;
}
}
}
if ((this->colorPaletteArray[2].padding_06 & 8) != 0) {
textureUIndex =
(float)(*(int *)(this->colorPaletteArray[1].final_padding + 6) - 1U & (uint)colorData2);
textureVIndex = 0.0;
particleData = (float *)this->childSystemPointers;
vertexBuffers = (float **)((float)(uint)textureUIndex * this->textureScaleU);
negVelocityY = (float *)0x0;
rotationAngle =
(float *)((float)((int)colorData2 >> (SUB41(this->uvCoordinateScale,0) & 0x1f)) *
this->textureScaleV);
negVelocityX = (float *)-particleDataPtr[4];
transformedVertexX = (float *)-particleDataPtr[5];
negVelocityZ = (float *)-particleDataPtr[6];
if (((this->colorPaletteArray[2].texCoordDelta2_prefix & 1) != 0) &&
(particleDataPtr[7] < (float)particleData)) {
particleData = (float *)particleDataPtr[7];
}
particleDataPtr =
(float *)transformVector4ByMatrix4x4
((float *)&transformedVelocityVector,(float *)&negVelocityX,
(float *)&g_worldMatrix);
tempFloat1 = (float)particleData * *particleDataPtr;
textureCoordV = (float)particleData * particleDataPtr[1];
cosValue = tempFloat1 * tempFloat1 + textureCoordV * textureCoordV;
if (_DAT_0080c744 <= cosValue) {
vertexBuffer = *vertexBufferPtr;
velocityDirection = (float)particleData * particleDataPtr[2] + worldPosZ;
cosValue = spriteScale / SQRT(cosValue);
scaleFactor = tempFloat1 * cosValue;
cosValue = cosValue * textureCoordV;
*vertexBuffer = worldPosX - cosValue;
vertexBuffer[1] = scaleFactor + worldPosY;
vertexBuffer[2] = worldPosZ;
particleDataPtr = vertexBufferPtr[1];
*particleDataPtr = (float)g_lightDirectionX;
particleDataPtr[1] = (float)g_lightDirectionY;
particleDataPtr[2] = (float)g_lightDirectionZ;
*vertexBufferPtr[2] = (float)colorValue;
particleDataPtr = vertexBufferPtr[3];
zDepth = (float)g_spriteTextureOffsetsV * this->textureScaleV;
*particleDataPtr = (float)g_spriteTextureOffsetsU * this->textureScaleU + (float)vertexBuffers
;
particleDataPtr[1] = zDepth + (float)rotationAngle;
vertexBufferPtr[8] = (float *)((int)vertexBufferPtr[8] + 1);
particleDataPtr = (float *)((int)*vertexBufferPtr + (int)vertexBufferPtr[4]);
vertexBufferPtr[2] = (float *)((int)vertexBufferPtr[2] + (int)vertexBufferPtr[6]);
*vertexBufferPtr = particleDataPtr;
vertexBufferPtr[1] = (float *)((int)vertexBufferPtr[1] + (int)vertexBufferPtr[5]);
vertexBufferPtr[3] = (float *)((int)vertexBufferPtr[3] + (int)vertexBufferPtr[7]);
*particleDataPtr = worldPosX + cosValue;
particleDataPtr[1] = worldPosY - scaleFactor;
particleDataPtr[2] = worldPosZ;
particleDataPtr = vertexBufferPtr[1];
*particleDataPtr = (float)g_lightDirectionX;
particleDataPtr[1] = (float)g_lightDirectionY;
particleDataPtr[2] = (float)g_lightDirectionZ;
*vertexBufferPtr[2] = (float)colorValue;
particleDataPtr = vertexBufferPtr[3];
zDepth = (float)g_spriteTextureOffsetsV * this->textureScaleV;
*particleDataPtr = (float)g_spriteTextureOffsetsU * this->textureScaleU + (float)vertexBuffers
;
particleDataPtr[1] = zDepth + (float)rotationAngle;
vertexBufferPtr[8] = (float *)((int)vertexBufferPtr[8] + 1);
vertexBufferPtr[1] = (float *)((int)vertexBufferPtr[1] + (int)vertexBufferPtr[5]);
particleDataPtr = (float *)((int)*vertexBufferPtr + (int)vertexBufferPtr[4]);
*vertexBufferPtr = particleDataPtr;
vertexBufferPtr[3] = (float *)((int)vertexBufferPtr[3] + (int)vertexBufferPtr[7]);
vertexBufferPtr[2] = (float *)((int)vertexBufferPtr[2] + (int)vertexBufferPtr[6]);
*particleDataPtr = (tempFloat1 + worldPosX) - cosValue;
particleDataPtr[1] = textureCoordV + worldPosY + scaleFactor;
particleDataPtr[2] = velocityDirection;
particleDataPtr = vertexBufferPtr[1];
*particleDataPtr = (float)g_lightDirectionX;
particleDataPtr[1] = (float)g_lightDirectionY;
particleDataPtr[2] = (float)g_lightDirectionZ;
*vertexBufferPtr[2] = (float)colorValue;
particleDataPtr = vertexBufferPtr[3];
zDepth = _DAT_0087d748 * this->textureScaleV;
*particleDataPtr = _DAT_0087d744 * this->textureScaleU + (float)vertexBuffers;
particleDataPtr[1] = zDepth + (float)rotationAngle;
vertexBufferPtr[8] = (float *)((int)vertexBufferPtr[8] + 1);
particleDataPtr = (float *)((int)*vertexBufferPtr + (int)vertexBufferPtr[4]);
vertexBufferPtr[1] = (float *)((int)vertexBufferPtr[1] + (int)vertexBufferPtr[5]);
vertexBufferPtr[2] = (float *)((int)vertexBufferPtr[2] + (int)vertexBufferPtr[6]);
*vertexBufferPtr = particleDataPtr;
vertexBufferPtr[3] = (float *)((int)vertexBufferPtr[3] + (int)vertexBufferPtr[7]);
*particleDataPtr = tempFloat1 + worldPosX + cosValue;
particleDataPtr[1] = (textureCoordV + worldPosY) - scaleFactor;
particleDataPtr[2] = velocityDirection;
particleDataPtr = vertexBufferPtr[1];
*particleDataPtr = (float)g_lightDirectionX;
particleDataPtr[1] = (float)g_lightDirectionY;
particleDataPtr[2] = (float)g_lightDirectionZ;
*vertexBufferPtr[2] = (float)colorValue;
particleDataPtr = vertexBufferPtr[3];
tempFloat1 = _DAT_0087d750 * this->textureScaleV;
*particleDataPtr = _DAT_0087d74c * this->textureScaleU + (float)vertexBuffers;
particleDataPtr[1] = tempFloat1 + (float)rotationAngle;
*vertexBufferPtr = (float *)((int)*vertexBufferPtr + (int)vertexBufferPtr[4]);
vertexBufferPtr[8] = (float *)((int)vertexBufferPtr[8] + 1);
vertexBufferPtr[2] = (float *)((int)vertexBufferPtr[2] + (int)vertexBufferPtr[6]);
vertexBufferPtr[1] = (float *)((int)vertexBufferPtr[1] + (int)vertexBufferPtr[5]);
vertexBufferPtr[3] = (float *)((int)vertexBufferPtr[3] + (int)vertexBufferPtr[7]);
return (undefined *)0x1;
}
loopIndex = 0;
do {
particleDataPtr = *vertexBufferPtr;
nextLoopIndex = loopIndex + 8;
tempFloat1 = *(float *)((int)&g_billboardVertexOffsetsY + loopIndex);
*particleDataPtr =
spriteScale * *(float *)((int)&g_billboardVertexOffsetsX + loopIndex) + worldPosX;
particleDataPtr[1] = spriteScale * tempFloat1 + worldPosY;
particleDataPtr[2] = worldPosZ;
particleDataPtr = vertexBufferPtr[1];
*particleDataPtr = (float)g_lightDirectionX;
particleDataPtr[1] = (float)g_lightDirectionY;
particleDataPtr[2] = (float)g_lightDirectionZ;
*vertexBufferPtr[2] = (float)colorValue;
particleDataPtr = vertexBufferPtr[3];
tempFloat1 = *(float *)((int)&g_spriteTextureOffsetsV + loopIndex);
textureCoordV = this->textureScaleV;
*particleDataPtr =
*(float *)((int)&g_spriteTextureOffsetsU + loopIndex) * this->textureScaleU +
(float)vertexBuffers;
particleDataPtr[1] = tempFloat1 * textureCoordV + (float)rotationAngle;
vertexBufferPtr[8] = (float *)((int)vertexBufferPtr[8] + 1);
*vertexBufferPtr = (float *)((int)*vertexBufferPtr + (int)vertexBufferPtr[4]);
vertexBufferPtr[1] = (float *)((int)vertexBufferPtr[1] + (int)vertexBufferPtr[5]);
vertexBufferPtr[2] = (float *)((int)vertexBufferPtr[2] + (int)vertexBufferPtr[6]);
vertexBufferPtr[3] = (float *)((int)vertexBufferPtr[3] + (int)vertexBufferPtr[7]);
loopIndex = nextLoopIndex;
} while (nextLoopIndex != 0x20);
}
return (undefined *)0x1;
}
@@ -0,0 +1,241 @@
// ============================================================
// calculateColorValues @ 0x7B9B10
// ============================================================
/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */
void __thiscall
calculateParticleColorAndScale
(OrientationData *this,float particleTime,float colorDeltaG,byte *colorValueOut,
uint *colorData1Out,uint *colorData2Out,float *spriteScaleOut)
{
byte alphaChannelValue;
float10 extendedPrecisionTime;
undefined *tempVar;
float timeScaledFactor;
undefined *puVar1;
/* Calculates particle color values, texture coordinates, and scale based on
particle time and orientation data. Uses time-scaled interpolation between
base values and deltas. Handles both standard float and extended precision
calculations. */
/* Calculate normalized time factor: (current_time - base_time) * time_scale *
0.99 + 0.005 */
timeScaledFactor =
(particleTime - this->timeBase) * this->timeScale * _DAT_00808aac + _DAT_00807a3c;
/* Alpha channel: ((color_delta_alpha * time_factor + base_alpha) *
color_delta_g + 512) >> 14 */
colorValueOut[3] =
(byte)((uint)(((float)this->colorDelta_R * timeScaledFactor + (float)this->colorBase_A) *
colorDeltaG + _DAT_008029cc) >> 0xe);
/* Blue channel: (color_delta_blue * time_factor + base_blue + 512) >> 14 */
/* Green channel: (color_delta_green * time_factor + base_green + 512) >> 14 */
colorValueOut[2] =
(byte)((uint)((float)this->colorDelta_G * timeScaledFactor + (float)this->colorBase_B +
_DAT_008029cc) >> 0xe);
/* Red channel: (color_delta_red * time_factor + base_red + 512) >> 14 */
colorValueOut[1] =
(byte)((uint)((float)this->colorDelta_B * timeScaledFactor + (float)this->colorBase_G +
_DAT_008029cc) >> 0xe);
puVar1 = (undefined *)
((uint)((float)this->colorDelta_A * timeScaledFactor + (float)this->colorBase_R +
_DAT_008029cc) >> 0xe);
*colorValueOut = (byte)puVar1;
*spriteScaleOut = timeScaledFactor * this->scaleDelta + this->scaleBase;
if (*(int *)&this->field_0x50 == 0x3f800000) {
*colorData1Out =
(uint)((float)this->texData1_Delta * timeScaledFactor + (float)this->texData1_Base +
_DAT_008029cc) >> 0xe & 0xff;
colorData1Out =
(uint *)((float)this->texData2_Delta * timeScaledFactor + (float)this->texData2_Base +
_DAT_008029cc);
}
else {
extendedPrecisionTime = (float10)callIntrinsicDispatcher(puVar1);
*colorData1Out =
(uint)(float)((float10)this->texData1_Delta * extendedPrecisionTime +
(float10)this->texData1_Base + (float10)_DAT_008029cc) >> 0xe & 0xff;
colorData1Out =
(uint *)(float)((float10)this->texData2_Delta * extendedPrecisionTime +
(float10)this->texData2_Base + (float10)_DAT_008029cc);
}
*colorData2Out = (uint)colorData1Out >> 0xe & 0xff;
return;
}
// ============================================================
// matVec3Transform @ 0x7BCA80
// ============================================================
void __fastcall transformVector3ByMatrix4x4(float *param_1,float *param_2,float *param_3)
{
float fVar1;
float fVar2;
float fVar3;
float fVar4;
float fVar5;
float fVar6;
float fVar7;
float fVar8;
float fVar9;
float fVar10;
float fVar11;
float fVar12;
float fVar13;
float fVar14;
fVar1 = param_3[10];
fVar2 = param_2[2];
fVar3 = param_3[2];
fVar4 = *param_2;
fVar5 = param_3[6];
fVar6 = param_2[1];
fVar7 = param_3[0xe];
fVar8 = param_3[9];
fVar9 = param_2[2];
fVar10 = param_3[1];
fVar11 = *param_2;
fVar12 = param_3[5];
fVar13 = param_2[1];
fVar14 = param_3[0xd];
*param_1 = *param_2 * *param_3 + param_3[4] * param_2[1] + param_3[8] * param_2[2] + param_3[0xc];
param_1[1] = fVar12 * fVar13 + fVar10 * fVar11 + fVar8 * fVar9 + fVar14;
param_1[2] = fVar5 * fVar6 + fVar3 * fVar4 + fVar1 * fVar2 + fVar7;
return;
}
// ============================================================
// buildRotationFromAngle @ 0x7BE490
// ============================================================
float * __fastcall
createAxisAngleRotationMatrix3x3(float *param_1,float *param_2,float param_3,char param_4)
{
float fVar1;
float fVar2;
float10 fVar3;
float fVar4;
float fVar5;
float fVar6;
float10 fVar7;
undefined *local_1c;
undefined *local_18;
undefined *local_14;
undefined *local_10;
undefined *local_c;
undefined *local_8;
local_1c = (undefined *)*param_2;
local_18 = (undefined *)param_2[1];
local_14 = (undefined *)param_2[2];
if (param_4 == '\0') {
fVar1 = StaticFloat1_0 /
SQRT((float)local_1c * (float)local_1c +
(float)local_18 * (float)local_18 + (float)local_14 * (float)local_14);
local_1c = (undefined *)((float)local_1c * fVar1);
local_18 = (undefined *)((float)local_18 * fVar1);
local_14 = (undefined *)(fVar1 * (float)local_14);
}
fVar3 = (float10)fcos((float10)param_3);
fVar7 = (float10)fsin((float10)param_3);
fVar1 = (float)fVar3;
fVar2 = (float)fVar7;
fVar6 = StaticFloat1_0 - fVar1;
*param_1 = (float)local_1c * (float)local_1c * fVar6 + fVar1;
fVar4 = fVar6 * (float)local_18 * (float)local_1c;
param_1[1] = fVar4 + (float)local_14 * fVar2;
fVar5 = fVar6 * (float)local_14 * (float)local_1c;
param_1[2] = fVar5 - (float)local_18 * fVar2;
param_1[3] = fVar4 - (float)local_14 * fVar2;
param_1[4] = (float)local_18 * (float)local_18 * fVar6 + fVar1;
fVar4 = fVar6 * (float)local_14 * (float)local_18;
param_1[5] = (float)local_1c * fVar2 + fVar4;
param_1[6] = fVar5 + (float)local_18 * fVar2;
param_1[7] = fVar4 - (float)local_1c * fVar2;
param_1[8] = (float)local_14 * (float)local_14 * fVar6 + fVar1;
return param_1;
}
// ============================================================
// matVec3Transform2 @ 0x7BCB40
// ============================================================
void __fastcall transformVector4ByMatrix4x4(float *param_1,float *param_2,float *param_3)
{
float fVar1;
float fVar2;
float fVar3;
float fVar4;
float fVar5;
float fVar6;
float fVar7;
float fVar8;
float fVar9;
float fVar10;
float fVar11;
float fVar12;
float fVar13;
float fVar14;
float fVar15;
float fVar16;
float fVar17;
float fVar18;
float fVar19;
float fVar20;
float fVar21;
float fVar22;
float fVar23;
float fVar24;
fVar1 = param_3[0xf];
fVar2 = param_2[3];
fVar3 = param_3[3];
fVar4 = *param_2;
fVar5 = param_3[0xb];
fVar6 = param_2[2];
fVar7 = param_3[7];
fVar8 = param_2[1];
fVar9 = param_3[0xe];
fVar10 = param_2[3];
fVar11 = param_3[2];
fVar12 = *param_2;
fVar13 = param_3[10];
fVar14 = param_2[2];
fVar15 = param_3[6];
fVar16 = param_2[1];
fVar17 = param_3[0xd];
fVar18 = param_2[3];
fVar19 = param_3[1];
fVar20 = *param_2;
fVar21 = param_3[9];
fVar22 = param_2[2];
fVar23 = param_3[5];
fVar24 = param_2[1];
*param_1 = *param_2 * *param_3 +
param_3[4] * param_2[1] + param_3[8] * param_2[2] + param_3[0xc] * param_2[3];
param_1[1] = fVar23 * fVar24 + fVar21 * fVar22 + fVar19 * fVar20 + fVar17 * fVar18;
param_1[2] = fVar15 * fVar16 + fVar13 * fVar14 + fVar11 * fVar12 + fVar9 * fVar10;
param_1[3] = fVar7 * fVar8 + fVar5 * fVar6 + fVar3 * fVar4 + fVar1 * fVar2;
return;
}
// ============================================================
// setupRenderState @ 0x58A230
// ============================================================
void UpdateLightingOffset(void)
{
GetLightingOffset((int)CGxDeviceD3d__device);
return;
}