2 * Copyright (C) 2003 Robert Kooima
4 * NEVERBALL is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
25 /*---------------------------------------------------------------------------*/
37 static struct part part_coin[PART_MAX_COIN];
38 static struct part part_goal[PART_MAX_GOAL];
39 static GLuint part_text;
40 static GLuint part_list;
42 /*---------------------------------------------------------------------------*/
46 static float rnd(float l, float h)
48 return l + (h - l) * rand() / RAND_MAX;
51 /*---------------------------------------------------------------------------*/
53 static GLfloat gcoltab[] = {0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f};
55 void part_reset(float h)
59 for (i = 0; i < PART_MAX_GOAL; i++)
61 float t = rnd(+0.1f, +1.0f);
62 float a = rnd(-1.0f * PI, +1.0f * PI);
63 float w = rnd(-2.0f * PI, +2.0f * PI);
67 part_goal[i].a = V_DEG(a);
68 part_goal[i].w = V_DEG(w);
70 part_goal[i].c[0] = gcoltab[k];
71 part_goal[i].c[1] = gcoltab[k+1];
72 part_goal[i].c[2] = gcoltab[k+2];
74 part_goal[i].p[0] = fsinf(a);
75 part_goal[i].p[1] = (1.f - t) * h;
76 part_goal[i].p[2] = fcosf(a);
78 part_goal[i].v[0] = 0.f;
79 part_goal[i].v[1] = 0.f;
80 part_goal[i].v[2] = 0.f;
82 part_coin[i].t = 0.0f;
86 void part_init(float h)
88 memset(part_coin, 0, PART_MAX_COIN * sizeof (struct part));
89 memset(part_goal, 0, PART_MAX_GOAL * sizeof (struct part));
91 part_text = make_image_from_file(NULL, NULL, NULL, NULL, IMG_PART);
92 part_list = glGenLists(1);
94 glNewList(part_list, GL_COMPILE);
98 glTexCoord2f(0.f, 0.f);
99 glVertex2f(-PART_SIZE, -PART_SIZE);
101 glTexCoord2f(1.f, 0.f);
102 glVertex2f(+PART_SIZE, -PART_SIZE);
104 glTexCoord2f(1.f, 1.f);
105 glVertex2f(+PART_SIZE, +PART_SIZE);
107 glTexCoord2f(0.f, 1.f);
108 glVertex2f(-PART_SIZE, +PART_SIZE);
119 if (glIsList(part_list))
120 glDeleteLists(part_list, 1);
122 if (glIsTexture(part_text))
123 glDeleteTextures(1, &part_text);
126 /*---------------------------------------------------------------------------*/
128 void part_burst(const float *p, const float *c)
132 for (i = 0; n < 10 && i < PART_MAX_COIN; i++)
133 if (part_coin[i].t <= 0.f)
135 float a = rnd(-1.0f * PI, +1.0f * PI);
136 float b = rnd(+0.3f * PI, +0.5f * PI);
137 float w = rnd(-4.0f * PI, +4.0f * PI);
139 part_coin[i].p[0] = p[0];
140 part_coin[i].p[1] = p[1];
141 part_coin[i].p[2] = p[2];
143 part_coin[i].v[0] = 4.f * fcosf(a) * fcosf(b);
144 part_coin[i].v[1] = 4.f * fsinf(b);
145 part_coin[i].v[2] = 4.f * fsinf(a) * fcosf(b);
147 part_coin[i].c[0] = c[0];
148 part_coin[i].c[1] = c[1];
149 part_coin[i].c[2] = c[2];
151 part_coin[i].t = 1.f;
152 part_coin[i].a = 0.f;
153 part_coin[i].w = V_DEG(w);
159 /*---------------------------------------------------------------------------*/
161 static void part_fall(struct part *part, int n, const float *g, float dt)
165 for (i = 0; i < n; i++)
170 part[i].v[0] += (g[0] * dt);
171 part[i].v[1] += (g[1] * dt);
172 part[i].v[2] += (g[2] * dt);
174 part[i].p[0] += (part[i].v[0] * dt);
175 part[i].p[1] += (part[i].v[1] * dt);
176 part[i].p[2] += (part[i].v[2] * dt);
180 static void part_spin(struct part *part, int n, const float *g, float dt)
184 for (i = 0; i < n; i++)
187 part[i].a += 30.f * dt;
189 part[i].p[0] = fsinf(V_RAD(part[i].a));
190 part[i].p[2] = fcosf(V_RAD(part[i].a));
194 void part_step(const float *g, float dt)
196 part_fall(part_coin, PART_MAX_COIN, g, dt);
199 part_fall(part_goal, PART_MAX_GOAL, g, dt);
201 part_spin(part_goal, PART_MAX_GOAL, g, dt);
204 /*---------------------------------------------------------------------------*/
206 static void part_draw(const float p[3], const float c[3],
207 float a, float r, float rx, float ry, float rz)
211 glTranslatef(r * p[0], p[1], r * p[2]);
212 glRotatef(ry, 0.f, 1.f, 0.f);
213 glRotatef(rx, 1.f, 0.f, 0.f);
214 glRotatef(rz, 0.f, 0.f, 1.f);
216 glColor4f(c[0], c[1], c[2], a);
218 glCallList(part_list);
223 void part_draw_coin(float rx, float ry)
225 float r = (float) SDL_GetTicks() / 1000.f;
228 glPushAttrib(GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT);
230 glDisable(GL_LIGHTING);
231 glEnable(GL_COLOR_MATERIAL);
233 glDepthMask(GL_FALSE);
234 glBindTexture(GL_TEXTURE_2D, part_text);
236 for (i = 0; i < PART_MAX_COIN; i++)
237 if (part_coin[i].t > 0.f)
238 part_draw(part_coin[i].p,
241 1.f, rx, ry, r * part_coin[i].w);
246 void part_draw_goal(float rx, float ry, float radius, float a, int spe)
248 float r = (float) SDL_GetTicks() / 1000.f;
250 GLfloat yel[3] = {1.0f, 1.0f, 0.0f};
252 glPushAttrib(GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT);
254 glDisable(GL_LIGHTING);
256 glEnable(GL_COLOR_MATERIAL);
258 glDepthMask(GL_FALSE);
259 glBindTexture(GL_TEXTURE_2D, part_text);
261 for (i = 0; i < PART_MAX_GOAL; i++)
262 if (part_goal[i].t > 0.f)
263 part_draw(part_goal[i].p,
264 spe ? part_goal[i].c : yel,
266 radius - 0.05f, rx, ry, r * part_goal[i].w);
271 /*---------------------------------------------------------------------------*/