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 void part_reset(float h)
57 for (i = 0; i < PART_MAX_GOAL; i++)
59 float t = rnd(+0.1f, +1.0f);
60 float a = rnd(-1.0f * PI, +1.0f * PI);
61 float w = rnd(-2.0f * PI, +2.0f * PI);
64 part_goal[i].a = V_DEG(a);
65 part_goal[i].w = V_DEG(w);
67 part_goal[i].c[0] = 1.0f;
68 part_goal[i].c[1] = 1.0f;
69 part_goal[i].c[2] = 0.0f;
71 part_goal[i].p[0] = fsinf(a);
72 part_goal[i].p[1] = (1.f - t) * h;
73 part_goal[i].p[2] = fcosf(a);
75 part_goal[i].v[0] = 0.f;
76 part_goal[i].v[1] = 0.f;
77 part_goal[i].v[2] = 0.f;
79 part_coin[i].t = 0.0f;
83 void part_init(float h)
85 memset(part_coin, 0, PART_MAX_COIN * sizeof (struct part));
86 memset(part_goal, 0, PART_MAX_GOAL * sizeof (struct part));
88 part_text = make_image_from_file(IMG_PART);
89 part_list = glGenLists(1);
91 glNewList(part_list, GL_COMPILE);
95 glTexCoord2f(0.f, 0.f);
96 glVertex2f(-PART_SIZE, -PART_SIZE);
98 glTexCoord2f(1.f, 0.f);
99 glVertex2f(+PART_SIZE, -PART_SIZE);
101 glTexCoord2f(1.f, 1.f);
102 glVertex2f(+PART_SIZE, +PART_SIZE);
104 glTexCoord2f(0.f, 1.f);
105 glVertex2f(-PART_SIZE, +PART_SIZE);
116 if (glIsList(part_list))
117 glDeleteLists(part_list, 1);
119 if (glIsTexture(part_text))
120 glDeleteTextures(1, &part_text);
123 /*---------------------------------------------------------------------------*/
125 void part_burst(const float *p, const float *c)
129 for (i = 0; n < 10 && i < PART_MAX_COIN; i++)
130 if (part_coin[i].t <= 0.f)
132 float a = rnd(-1.0f * PI, +1.0f * PI);
133 float b = rnd(+0.3f * PI, +0.5f * PI);
134 float w = rnd(-4.0f * PI, +4.0f * PI);
136 part_coin[i].p[0] = p[0];
137 part_coin[i].p[1] = p[1];
138 part_coin[i].p[2] = p[2];
140 part_coin[i].v[0] = 4.f * fcosf(a) * fcosf(b);
141 part_coin[i].v[1] = 4.f * fsinf(b);
142 part_coin[i].v[2] = 4.f * fsinf(a) * fcosf(b);
144 part_coin[i].c[0] = c[0];
145 part_coin[i].c[1] = c[1];
146 part_coin[i].c[2] = c[2];
148 part_coin[i].t = 1.f;
149 part_coin[i].a = 0.f;
150 part_coin[i].w = V_DEG(w);
156 /*---------------------------------------------------------------------------*/
158 static void part_fall(struct part *part, int n, const float *g, float dt)
162 for (i = 0; i < n; i++)
167 part[i].v[0] += (g[0] * dt);
168 part[i].v[1] += (g[1] * dt);
169 part[i].v[2] += (g[2] * dt);
171 part[i].p[0] += (part[i].v[0] * dt);
172 part[i].p[1] += (part[i].v[1] * dt);
173 part[i].p[2] += (part[i].v[2] * dt);
177 static void part_spin(struct part *part, int n, const float *g, float dt)
181 for (i = 0; i < n; i++)
184 part[i].a += 30.f * dt;
186 part[i].p[0] = fsinf(V_RAD(part[i].a));
187 part[i].p[2] = fcosf(V_RAD(part[i].a));
191 void part_step(const float *g, float dt)
193 part_fall(part_coin, PART_MAX_COIN, g, dt);
196 part_fall(part_goal, PART_MAX_GOAL, g, dt);
198 part_spin(part_goal, PART_MAX_GOAL, g, dt);
201 /*---------------------------------------------------------------------------*/
203 static void part_draw(const float *M,
204 const float *p, float r, float rz)
208 glTranslatef(r * p[0], p[1], r * p[2]);
210 glRotatef(rz, 0.f, 0.f, 1.f);
212 glCallList(part_list);
217 void part_draw_coin(const float *M, float t)
221 glBindTexture(GL_TEXTURE_2D, part_text);
223 for (i = 0; i < PART_MAX_COIN; i++)
224 if (part_coin[i].t > 0.f)
226 glColor4f(part_coin[i].c[0],
231 part_draw(M, part_coin[i].p, 1.0f, t * part_coin[i].w);
235 void part_draw_goal(const float *M, float radius, float a, float t)
239 glBindTexture(GL_TEXTURE_2D, part_text);
241 glColor4f(1.0f, 1.0f, 0.0f, a);
243 for (i = 0; i < PART_MAX_GOAL; i++)
244 if (part_goal[i].t > 0.0f)
245 part_draw(M, part_goal[i].p, radius - 0.05f, t * part_goal[i].w);
248 /*---------------------------------------------------------------------------*/