1/*
2
3Copyright (c) 2002, Calum Robinson
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are met:
8
9* Redistributions of source code must retain the above copyright notice, this
10  list of conditions and the following disclaimer.
11
12* Redistributions in binary form must reproduce the above copyright notice,
13  this list of conditions and the following disclaimer in the documentation
14  and/or other materials provided with the distribution.
15
16* Neither the name of the author nor the names of its contributors may be used
17  to endorse or promote products derived from this software without specific
18  prior written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
24ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31*/
32
33
34#include "Spark.h"
35#include "Shared.h"
36
37
38#define BIGMYSTERY 1800.0
39#define MAXANGLES 16384
40
41#define fieldCoherence 0
42#define fieldSpeed 12.0f
43#define fieldRange 1000.0f
44
45
46void
47InitSpark(Spark* s)
48{
49	for (int i = 0; i < 3; i++)
50		s->position[i] = RandFlt(-100.0, 100.0);
51}
52
53
54void DrawSpark(flurry_info_t* info, Spark* s)
55{
56	const float black[4] = {0.0f, 0.0f, 0.0f, 1.0f};
57	float width;
58	float sx;
59	float sy;
60	float a;
61	float c = 0.0625f;
62	float screenx;
63	float screeny;
64	float w;
65	float z;
66	float scale;
67	width = 60000.0f * info->sys_glWidth / 1024.0f;
68
69	z = s->position[2];
70	sx = s->position[0] * info->sys_glWidth / z + info->sys_glWidth * 0.5f;
71	sy = s->position[1] * info->sys_glWidth / z + info->sys_glHeight * 0.5f;
72	w = width*4.0f / z;
73
74	screenx = sx;
75	screeny = sy;
76
77	glPushMatrix();
78	glTranslatef(screenx,screeny,0.0f);
79	scale = w/50.0f;
80	glScalef(scale,scale,0.0f);
81	for (int k = 0; k < 12; k++) {
82		a = ((float)(random() % 3600)) / 10.0f;
83		glRotatef(a,0.0f,0.0f,1.0f);
84		glBegin(GL_QUAD_STRIP);
85		glColor4fv(black);
86		glVertex2f(-3.0f,0.0f);
87		a = 2.0f + (float) (random() & 255) * c;
88		glVertex2f(-3.0f,a);
89		glColor4fv(s->color);
90		glVertex2f(0.0f,0.0f);
91		glColor4fv(black);
92		glVertex2f(0.0f,a);
93		glVertex2f(3.0f,0.0f);
94		glVertex2f(3.0f,a);
95		glEnd();
96	}
97
98	glPopMatrix();
99}
100
101
102void
103UpdateSparkColour(flurry_info_t* info, Spark* s)
104{
105	const float rotationsPerSecond = (float)(2.0 * M_PI * fieldSpeed
106		/ MAXANGLES);
107	double thisPointInRadians;
108	double thisAngle = info->fTime*rotationsPerSecond;
109	float cf;
110	float cycleTime = 20.0f;
111	float colorRot;
112	float redPhaseShift;
113	float greenPhaseShift;
114	float bluePhaseShift;
115	float baseRed;
116	float baseGreen;
117	float baseBlue;
118	float colorTime;
119
120	if (info->currentColorMode == rainbowColorMode)
121		cycleTime = 1.5f;
122	else if (info->currentColorMode == tiedyeColorMode)
123		cycleTime = 4.5f;
124	else if (info->currentColorMode == cyclicColorMode)
125		cycleTime = 20.0f;
126	else if (info->currentColorMode == slowCyclicColorMode)
127		cycleTime = 120.0f;
128
129	colorRot = (float)(2.0 * M_PI / cycleTime);
130	redPhaseShift = 0.0f; /* cycleTime * 0.0f / 3.0f */
131	greenPhaseShift = cycleTime / 3.0f;
132	bluePhaseShift = cycleTime * 2.0f / 3.0f;
133	colorTime = info->fTime;
134	if (info->currentColorMode == whiteColorMode) {
135		baseRed = 0.1875f;
136		baseGreen = 0.1875f;
137		baseBlue = 0.1875f;
138	} else if (info->currentColorMode == multiColorMode) {
139		baseRed = 0.0625f;
140		baseGreen = 0.0625f;
141		baseBlue = 0.0625f;
142	} else if (info->currentColorMode == darkColorMode) {
143		baseRed = 0.0f;
144		baseGreen = 0.0f;
145		baseBlue = 0.0f;
146	} else {
147		if (info->currentColorMode < slowCyclicColorMode)
148			colorTime = (info->currentColorMode / 6.0f) * cycleTime;
149		else
150			colorTime = info->fTime + info->randomSeed;
151
152		baseRed = 0.109375f
153			* ((float)cos((colorTime + redPhaseShift) * colorRot) + 1.0f);
154		baseGreen = 0.109375f
155			* ((float)cos((colorTime + greenPhaseShift) * colorRot) + 1.0f);
156		baseBlue = 0.109375f
157			* ((float)cos((colorTime + bluePhaseShift) * colorRot) + 1.0f);
158	}
159
160	cf = ((float)(cos(7.0 * ((info->fTime) * rotationsPerSecond))
161		+ cos(3.0 * ((info->fTime) * rotationsPerSecond))
162		+ cos(13.0 * ((info->fTime) * rotationsPerSecond))));
163	cf /= 6.0f;
164	cf += 2.0f;
165	thisPointInRadians = 2.0 * M_PI * (double) s->mystery / (double) BIGMYSTERY;
166
167	s->color[0] = baseRed + 0.0625f
168		* (0.5f + (float)cos((15.0 * (thisPointInRadians + 3.0*thisAngle)))
169		+ (float)sin((7.0 * (thisPointInRadians + thisAngle))));
170	s->color[1] = baseGreen + 0.0625f
171		* (0.5f + (float)sin(((thisPointInRadians) + thisAngle)));
172	s->color[2] = baseBlue + 0.0625f
173		* (0.5f + (float)cos((37.0 * (thisPointInRadians + thisAngle))));
174}
175
176
177void
178UpdateSpark(flurry_info_t* info, Spark* s)
179{
180	const float rotationsPerSecond = (float) (2.0*M_PI*fieldSpeed/MAXANGLES);
181	double thisPointInRadians;
182	double thisAngle = info->fTime*rotationsPerSecond;
183	float cf;
184	double tmpX1,tmpY1,tmpZ1;
185	double tmpX2,tmpY2,tmpZ2;
186	double tmpX3,tmpY3,tmpZ3;
187	double tmpX4,tmpY4,tmpZ4;
188	double rotation;
189	double cr;
190	double sr;
191	float cycleTime = 20.0f;
192	float colorRot;
193	float redPhaseShift;
194	float greenPhaseShift;
195	float bluePhaseShift;
196	float baseRed;
197	float baseGreen;
198	float baseBlue;
199	float colorTime;
200
201	float old[3];
202
203	if (info->currentColorMode == rainbowColorMode)
204		cycleTime = 1.5f;
205	else if (info->currentColorMode == tiedyeColorMode)
206		cycleTime = 4.5f;
207	else if (info->currentColorMode == cyclicColorMode)
208		cycleTime = 20.0f;
209	else if (info->currentColorMode == slowCyclicColorMode)
210		cycleTime = 120.0f;
211
212	colorRot = (float)(2.0 * M_PI / cycleTime);
213	redPhaseShift = 0.0f; /* cycleTime * 0.0f / 3.0f */
214	greenPhaseShift = cycleTime / 3.0f;
215	bluePhaseShift = cycleTime * 2.0f / 3.0f ;
216	colorTime = info->fTime;
217	if (info->currentColorMode == whiteColorMode) {
218		baseRed = 0.1875f;
219		baseGreen = 0.1875f;
220		baseBlue = 0.1875f;
221	} else if (info->currentColorMode == multiColorMode) {
222		baseRed = 0.0625f;
223		baseGreen = 0.0625f;
224		baseBlue = 0.0625f;
225	} else if (info->currentColorMode == darkColorMode) {
226		baseRed = 0.0f;
227		baseGreen = 0.0f;
228		baseBlue = 0.0f;
229	} else {
230		if (info->currentColorMode < slowCyclicColorMode)
231			colorTime = (info->currentColorMode / 6.0f) * cycleTime;
232		else
233			colorTime = info->fTime + info->randomSeed;
234
235		baseRed = 0.109375f
236			* ((float)cos((colorTime + redPhaseShift) * colorRot) + 1.0f);
237		baseGreen = 0.109375f
238			* ((float)cos((colorTime + greenPhaseShift) * colorRot) + 1.0f);
239		baseBlue = 0.109375f
240			* ((float)cos((colorTime + bluePhaseShift) * colorRot) + 1.0f);
241	}
242
243	for (int i = 0; i < 3; i++)
244		old[i] = s->position[i];
245
246	cf = ((float)cos(7.0 * ((info->fTime) * rotationsPerSecond)
247		+ (float)cos(3.0 * ((info->fTime) * rotationsPerSecond))
248		+ (float)cos(13.0 * ((info->fTime) * rotationsPerSecond))));
249	cf /= 6.0f;
250	cf += 2.0f;
251	thisPointInRadians = 2.0 * M_PI * (double)s->mystery / (double)BIGMYSTERY;
252
253	s->color[0] = baseRed + 0.0625f
254		* (0.5f + (float) cos((15.0 * (thisPointInRadians + 3.0*thisAngle)))
255		+ (float) sin((7.0 * (thisPointInRadians + thisAngle))));
256	s->color[1] = baseGreen + 0.0625f
257		* (0.5f + (float) sin(((thisPointInRadians) + thisAngle)));
258	s->color[2] = baseBlue + 0.0625f
259		* (0.5f + (float) cos((37.0 * (thisPointInRadians + thisAngle))));
260	s->position[0] = fieldRange * cf
261		* (float)cos(11.0 * (thisPointInRadians + (3.0*thisAngle)));
262	s->position[1] = fieldRange * cf *
263		(float) sin(12.0 * (thisPointInRadians + (4.0*thisAngle)));
264	s->position[2] = fieldRange *
265		(float) cos((23.0 * (thisPointInRadians + (12.0*thisAngle))));
266
267	rotation = thisAngle * 0.501 + 5.01 * (double)s->mystery
268		/ (double)BIGMYSTERY;
269	cr = cos(rotation);
270	sr = sin(rotation);
271	tmpX1 = s->position[0] * cr - s->position[1] * sr;
272	tmpY1 = s->position[1] * cr + s->position[0] * sr;
273	tmpZ1 = s->position[2];
274
275	tmpX2 = tmpX1 * cr - tmpZ1 * sr;
276	tmpY2 = tmpY1;
277	tmpZ2 = tmpZ1 * cr + tmpX1 * sr;
278
279	tmpX3 = tmpX2;
280	tmpY3 = tmpY2 * cr - tmpZ2 * sr;
281	tmpZ3 = tmpZ2 * cr + tmpY2 * sr + seraphDistance;
282
283	rotation = thisAngle * 2.501 + 85.01 * (double)s->mystery
284		/ (double)BIGMYSTERY;
285	cr = cos(rotation);
286	sr = sin(rotation);
287	tmpX4 = tmpX3 * cr - tmpY3 * sr;
288	tmpY4 = tmpY3 * cr + tmpX3 * sr;
289	tmpZ4 = tmpZ3;
290
291	s->position[0] = (float) tmpX4 + RandBell(5.0f*fieldCoherence);
292	s->position[1] = (float) tmpY4 + RandBell(5.0f*fieldCoherence);
293	s->position[2] = (float) tmpZ4 + RandBell(5.0f*fieldCoherence);
294
295	for (int i = 0;i < 3; i++)
296		s->delta[i] = (s->position[i] - old[i]) / info->fDeltaTime;
297}
298