From 64aaa26251a5eee5287752e35848c8cdf1de42c4 Mon Sep 17 00:00:00 2001
From: Nozomi Kodama <nozomi.kodama@yahoo.com>
Date: Tue, 16 Oct 2012 19:52:13 -1000
Subject: Fix the case out = in for D3DXSHRotateZ

---
 dlls/d3dx9_36/math.c |  152 +++++++++++++++++++++++++++++++-------------------
 1 file changed, 96 insertions(+), 56 deletions(-)

diff --git a/dlls/d3dx9_36/math.c b/dlls/d3dx9_36/math.c
index 73bca45..dd72b2d 100644
--- a/dlls/d3dx9_36/math.c
+++ b/dlls/d3dx9_36/math.c
@@ -2811,72 +2811,112 @@ FLOAT* WINAPI D3DXSHRotate(FLOAT *out, UINT order, CONST D3DXMATRIX *matrix, CON
     return out;
 }
 
-FLOAT * WINAPI D3DXSHRotateZ(FLOAT *out, UINT order, FLOAT angle, CONST FLOAT *in)
+static void multiply_mat_vec(UINT dim, CONST FLOAT *matrix, CONST FLOAT *in, FLOAT *out)
 {
-    FLOAT c1a, c2a, c3a, c4a, c5a, s1a, s2a, s3a, s4a, s5a;
+    UINT i, j;
+
+    for (i = 0; i < dim; i++)
+    {
+        out[i] = matrix[i * dim] * in[0];
+        for (j = 1; j < dim; j++)
+            out[i] += matrix[i * dim + j] * in[j];
+    }
+}
 
+FLOAT * WINAPI D3DXSHRotateZ(FLOAT *out, UINT order, FLOAT angle, CONST FLOAT *in)
+{
+    FLOAT matrix[9] = { 0.0f, };
+ 
     TRACE("out %p, order %u, angle %f, in %p\n", out, order, angle, in);
 
-    c1a = cosf(angle);
-    s1a = sinf(angle);
     out[0] = in[0];
-    out[1] = c1a * in[1] + s1a * in[3];
-    out[2] = in[2];
-    out[3] = c1a * in[3] - s1a * in[1];
-    if (order <= D3DXSH_MINORDER)
-        return out;
 
-    c2a = cosf(2.0f * angle);
-    s2a = sinf(2.0f * angle);
-    out[4] = c2a * in[4] + s2a * in[8];
-    out[5] = c1a * in[5] + s1a * in[7];
-    out[6] = in[6];
-    out[7] = c1a * in[7] - s1a * in[5];
-    out[8] = c2a * in[8] - s2a * in[4];
-    if (order == 3)
-        return out;
+    matrix[0] = matrix[8] = cosf(angle);
+    matrix[2] = sinf(angle);
+    matrix[4] = 1.0f;
+    matrix[6] = -matrix[2];
 
-    c3a = cosf(3.0f * angle);
-    s3a = sinf(3.0f * angle);
-    out[9] = c3a * in[9] + s3a * in[15];
-    out[10] = c2a * in[10] + s2a * in[14];
-    out[11] = c1a * in[11] + s1a * in[13];
-    out[12] = in[12];
-    out[13] = c1a * in[13] - s1a * in[11];
-    out[14] = c2a * in[14] - s2a * in[10];
-    out[15] = c3a * in[15] - s3a * in[9];
-    if (order == 4)
-        return out;
+    multiply_mat_vec(3, matrix, &in[1], &out[1]);
 
-    c4a = cosf(4.0f * angle);
-    s4a = sinf(4.0f * angle);
-    out[16] = c4a * in[16] + s4a * in[24];
-    out[17] = c3a * in[17] + s3a * in[23];
-    out[18] = c2a * in[18] + s2a * in[22];
-    out[19] = c1a * in[19] + s1a * in[21];
-    out[20] = in[20];
-    out[21] = c1a * in[21] - s1a * in[19];
-    out[22] = c2a * in[22] - s2a * in[18];
-    out[23] = c3a * in[23] - s3a * in[17];
-    out[24] = c4a * in[24] - s4a * in[16];
-    if (order == 5)
-        return out;
+    if (order > 2)
+    {
+        FLOAT matrix[25] = { 0.0f, };
 
-    c5a = cosf(5.0f * angle);
-    s5a = sinf(5.0f * angle);
-    out[25] = c5a * in[25] + s5a * in[35];
-    out[26] = c4a * in[26] + s4a * in[34];
-    out[27] = c3a * in[27] + s3a * in[33];
-    out[28] = c2a * in[28] + s2a * in[32];
-    out[29] = c1a * in[29] + s1a * in[31];
-    out[30] = in[30];
-    out[31] = c1a * in[31] - s1a * in[29];
-    out[32] = c2a * in[32] - s2a * in[28];
-    out[33] = c3a * in[33] - s3a * in[27];
-    out[34] = c4a * in[34] - s4a * in[26];
-    out[35] = c5a * in[35] - s5a * in[25];
+        matrix[0] = matrix[24] = cosf(2.0f * angle);
+        matrix[4] = sinf(2.0f * angle);
+        matrix[6] = matrix[18] = cosf(angle);
+        matrix[8] = sinf(angle);
+        matrix[12] = 1.0f;
+        matrix[16] = -matrix[8];
+        matrix[20] = -matrix[4];
 
-    return out;
+        multiply_mat_vec(5, matrix, &in[4], &out[4]);
+    }
+
+    if (order > 3)
+    {
+        FLOAT matrix[49] = { 0.0f, };
+
+        matrix[0] = matrix[48] = cosf(3.0f * angle);
+        matrix[6] = sinf(3.0f * angle);
+        matrix[8] = matrix[40] = cosf(2.0f * angle);
+        matrix[12] = sinf(2.0f * angle);
+        matrix[16] = matrix[32] = cosf(angle);
+        matrix[18] = sinf(angle);
+        matrix[24] = 1.0f;
+        matrix[30] = -matrix[18];
+        matrix[36] = -matrix[12];
+        matrix[42] = -matrix[6];
+
+        multiply_mat_vec(7, matrix, &in[9], &out[9]);
+    }
+
+    if (order > 4)
+    {
+        FLOAT matrix[81] = { 0.0f, };
+
+        matrix[0] = matrix[80] = cosf(4.0f * angle);
+        matrix[8] = sinf(4.0f * angle);
+        matrix[10] = matrix[70] = cosf(3.0f * angle);
+        matrix[16] = sinf(3.0f * angle);
+        matrix[20] = matrix[60] = cosf(2.0f * angle);
+        matrix[24] = sinf(2.0f * angle);
+        matrix[30] = matrix[50] = cosf(angle);
+        matrix[32] = sinf(angle);
+        matrix[40] = 1.0f;
+        matrix[48] = -matrix[32];
+        matrix[56] = -matrix[24];
+        matrix[64] = -matrix[16];
+        matrix[72] = -matrix[8];
+
+        multiply_mat_vec(9, matrix, &in[16], &out[16]);
+    }
+
+    if (order > 5)
+    {
+        FLOAT matrix[121] = { 0.0f, };
+
+        matrix[0] = matrix[120] = cosf(5.0f * angle);
+        matrix[10] = sinf(5.0f * angle);
+        matrix[12] = matrix[108] = cosf(4.0f * angle);
+        matrix[20] = sinf(4.0f * angle);
+        matrix[24] = matrix[96] = cosf(3.0f * angle);
+        matrix[30] = sinf(3.0f * angle);
+        matrix[36] = matrix[84] = cosf(2.0f * angle);
+        matrix[40] = sinf(2.0f * angle);
+        matrix[48] = matrix[72] = cosf(angle);
+        matrix[50] = sinf(angle);
+        matrix[60] = 1.0f;
+        matrix[70] = -matrix[50];
+        matrix[80] = -matrix[40];
+        matrix[90] = -matrix[30];
+        matrix[100] = -matrix[20];
+        matrix[110] = -matrix[10];
+
+        multiply_mat_vec(11, matrix, &in[25], &out[25]);
+    }
+ 
+     return out;
 }
 
 FLOAT* WINAPI D3DXSHScale(FLOAT *out, UINT order, CONST FLOAT *a, CONST FLOAT scale)
-- 
1.7.9.5

