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(NULL
, NULL
, NULL
, NULL
, 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 p
[3], const float c
[3],
204 float a
, float r
, float rx
, float ry
, float rz
)
208 glTranslatef(r
* p
[0], p
[1], r
* p
[2]);
209 glRotatef(ry
, 0.f
, 1.f
, 0.f
);
210 glRotatef(rx
, 1.f
, 0.f
, 0.f
);
211 glRotatef(rz
, 0.f
, 0.f
, 1.f
);
213 glColor4f(c
[0], c
[1], c
[2], a
);
215 glCallList(part_list
);
220 void part_draw_coin(float rx
, float ry
)
222 float r
= (float) SDL_GetTicks() / 1000.f
;
225 glPushAttrib(GL_LIGHTING_BIT
| GL_DEPTH_BUFFER_BIT
);
227 glDisable(GL_LIGHTING
);
228 glEnable(GL_COLOR_MATERIAL
);
230 glDepthMask(GL_FALSE
);
231 glBindTexture(GL_TEXTURE_2D
, part_text
);
233 for (i
= 0; i
< PART_MAX_COIN
; i
++)
234 if (part_coin
[i
].t
> 0.f
)
235 part_draw(part_coin
[i
].p
,
238 1.f
, rx
, ry
, r
* part_coin
[i
].w
);
243 void part_draw_goal(float rx
, float ry
, float radius
, float a
)
245 float r
= (float) SDL_GetTicks() / 1000.f
;
248 glPushAttrib(GL_LIGHTING_BIT
| GL_DEPTH_BUFFER_BIT
);
250 glDisable(GL_LIGHTING
);
252 glEnable(GL_COLOR_MATERIAL
);
254 glDepthMask(GL_FALSE
);
255 glBindTexture(GL_TEXTURE_2D
, part_text
);
257 for (i
= 0; i
< PART_MAX_GOAL
; i
++)
258 if (part_goal
[i
].t
> 0.f
)
259 part_draw(part_goal
[i
].p
,
261 radius
- 0.05f
, rx
, ry
, r
* part_goal
[i
].w
);
266 /*---------------------------------------------------------------------------*/