1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* sproingies.c - 3D sproingies */
3
4 #if 0
5 static const char sccsid[] = "@(#)sproingies.c 5.00 2000/11/01 xlockmore";
6 #endif
7
8 /*-
9 * sproingies.c - Copyright 1996 by Ed Mackey, freely distributable.
10 *
11 * Permission to use, copy, modify, and distribute this software and its
12 * documentation for any purpose and without fee is hereby granted,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation.
16 *
17 * This file is provided AS IS with no warranties of any kind. The author
18 * shall have no liability with respect to the infringement of copyrights,
19 * trade secrets or any patents by this file or any part thereof. In no
20 * event will the author be liable for any lost revenue or profits or
21 * other special, indirect and consequential damages.
22 *
23 * Revision History:
24 * 01-Nov-2000: Allocation checks
25 * 07-Dec-1996: Written.
26 */
27
28 #ifdef STANDALONE
29 #define MODE_sproingies
30 #include "xlockmoreI.h" /* from the xscreensaver distribution */
31 #else /* !STANDALONE */
32 #include "xlock.h" /* from the xlockmore distribution */
33 #endif /* !STANDALONE */
34
35 #ifdef MODE_sproingies
36
37 #include <GL/gl.h>
38 #include "buildlwo.h"
39 #include "sproingies.h"
40
41 #define MAXSPROING 100
42 #define T_COUNT 40
43 #define BOOM_FRAME 50
44
45 struct sPosColor {
46 int x, y, z, frame, life;
47 GLfloat r, g, b;
48 };
49
50 typedef struct {
51 int rotx, roty, dist, wireframe, flatshade, groundlevel,
52 maxsproingies, mono;
53 int sframe, target_rx, target_ry, target_dist, target_count;
54 GLuint sproingies[6], TopsSides, SproingieBoom;
55 struct sPosColor *positions;
56 } sp_instance;
57
58 static sp_instance *si_list = (sp_instance *) NULL;
59 static int active_screens = 0;
60
61 extern struct lwo LWO_s1_1, LWO_s1_2, LWO_s1_3, LWO_s1_4;
62 extern struct lwo LWO_s1_5, LWO_s1_6, LWO_s1_b;
63
64 static int
myrand(int range)65 myrand(int range)
66 {
67 return ((int) (((float) range) * LRAND() / (MAXRAND)));
68 }
69
70 static GLuint
build_TopsSides(int wireframe)71 build_TopsSides(int wireframe)
72 {
73 GLuint dl_num;
74 GLfloat mat_color[4] =
75 {0.0, 0.0, 0.0, 1.0};
76
77 if ((dl_num = glGenLists(2)) == 0)
78 return (0); /* 0 means out of display lists. */
79
80 /* Surface: Tops */
81 glNewList(dl_num, GL_COMPILE);
82 if (glGetError() != GL_NO_ERROR) {
83 glDeleteLists(dl_num, 2);
84 return (0);
85 }
86 mat_color[0] = 0.392157;
87 mat_color[1] = 0.784314;
88 mat_color[2] = 0.941176;
89 if (wireframe)
90 glColor3fv(mat_color);
91 else {
92 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_color);
93 }
94 glEndList();
95
96 /* Surface: Sides */
97 glNewList(dl_num + 1, GL_COMPILE);
98 if (glGetError() != GL_NO_ERROR) {
99 glDeleteLists(dl_num, 2);
100 return (0);
101 }
102 mat_color[0] = 0.156863;
103 mat_color[1] = 0.156863;
104 mat_color[2] = 0.392157;
105 if (wireframe)
106 glColor3fv(mat_color);
107 else {
108 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_color);
109 }
110 glEndList();
111 return (dl_num);
112 }
113
114 static void
LayGround(int sx,int sy,int sz,int width,int height,sp_instance * si)115 LayGround(int sx, int sy, int sz, int width, int height, sp_instance * si)
116 {
117 int x, y, z, w, h;
118 GLenum begin_polygon;
119
120 if (si->wireframe)
121 begin_polygon = GL_LINE_LOOP;
122 else
123 begin_polygon = GL_POLYGON;
124
125 if (!si->wireframe) {
126 if (!si->mono)
127 glCallList(si->TopsSides); /* Render the tops */
128 glNormal3f(0.0, 1.0, 0.0);
129
130 for (h = 0; h < height; ++h) {
131 x = sx + h;
132 y = sy - (h << 1);
133 z = sz + h;
134 for (w = 0; w < width; ++w) {
135 glBegin(begin_polygon);
136 glVertex3i(x, y, z);
137 glVertex3i(x, y, z - 1);
138 glVertex3i(x + 1, y, z - 1);
139 glVertex3i(x + 1, y, z);
140 glEnd();
141 glBegin(begin_polygon);
142 glVertex3i(x + 1, y - 1, z);
143 glVertex3i(x + 1, y - 1, z - 1);
144 glVertex3i(x + 2, y - 1, z - 1);
145 glVertex3i(x + 2, y - 1, z);
146 glEnd();
147 ++x;
148 --z;
149 }
150 }
151 }
152 if (!si->mono)
153 glCallList(si->TopsSides + 1); /* Render the sides */
154 if (!si->wireframe)
155 glNormal3f(0.0, 0.0, 1.0);
156
157 for (h = 0; h < height; ++h) {
158 x = sx + h;
159 y = sy - (h << 1);
160 z = sz + h;
161 for (w = 0; w < width; ++w) {
162 glBegin(begin_polygon);
163 glVertex3i(x, y, z);
164 glVertex3i(x + 1, y, z);
165 glVertex3i(x + 1, y - 1, z);
166 glVertex3i(x, y - 1, z);
167 glEnd();
168 glBegin(begin_polygon);
169 glVertex3i(x + 1, y - 1, z);
170 glVertex3i(x + 2, y - 1, z);
171 glVertex3i(x + 2, y - 2, z);
172 glVertex3i(x + 1, y - 2, z);
173 /*-
174 * PURIFY 4.0.1 reports an uninitialized memory read on the next line when using
175 * MesaGL 2.2 and -mono. This has been fixed in MesaGL 2.3 and later. */
176 glEnd();
177 ++x;
178 --z;
179 }
180 }
181
182 /* Render the other sides */
183 if (!si->wireframe)
184 glNormal3f(1.0, 0.0, 0.0);
185
186 for (h = 0; h < height; ++h) {
187 x = sx + h;
188 y = sy - (h << 1);
189 z = sz + h;
190 for (w = 0; w < width; ++w) {
191 glBegin(begin_polygon);
192 glVertex3i(x + 1, y, z);
193 glVertex3i(x + 1, y, z - 1);
194 glVertex3i(x + 1, y - 1, z - 1);
195 glVertex3i(x + 1, y - 1, z);
196 glEnd();
197 glBegin(begin_polygon);
198 glVertex3i(x + 2, y - 1, z);
199 glVertex3i(x + 2, y - 1, z - 1);
200 glVertex3i(x + 2, y - 2, z - 1);
201 glVertex3i(x + 2, y - 2, z);
202 glEnd();
203 ++x;
204 --z;
205 }
206 }
207
208 if (si->wireframe) {
209 if (!si->mono)
210 glCallList(si->TopsSides); /* Render the tops */
211
212 for (h = 0; h < height; ++h) {
213 x = sx + h;
214 y = sy - (h << 1);
215 z = sz + h;
216 for (w = 0; w < width; ++w) {
217 glBegin(begin_polygon);
218 glVertex3i(x, y, z);
219 glVertex3i(x, y, z - 1);
220 glVertex3i(x + 1, y, z - 1);
221 glVertex3i(x + 1, y, z);
222 glEnd();
223 glBegin(begin_polygon);
224 glVertex3i(x + 1, y - 1, z);
225 glVertex3i(x + 1, y - 1, z - 1);
226 glVertex3i(x + 2, y - 1, z - 1);
227 glVertex3i(x + 2, y - 1, z);
228 glEnd();
229 ++x;
230 --z;
231 }
232 }
233 }
234 }
235
236 #define RESET_SPROINGIE (-30 + myrand(28))
237
238 static void
AdvanceSproingie(int t,sp_instance * si)239 AdvanceSproingie(int t, sp_instance * si)
240 {
241 int g_higher, g_back, t2;
242 struct sPosColor *thisSproingie = &(si->positions[t]);
243 struct sPosColor *S2 = &(si->positions[0]);
244
245 if (thisSproingie->life > 0) {
246 if ((++(thisSproingie->frame)) > 11) {
247 if (thisSproingie->frame >= BOOM_FRAME) {
248 if ((thisSproingie->r -= 0.08) < 0.0)
249 thisSproingie->r = 0.0;
250 if ((thisSproingie->g -= 0.08) < 0.0)
251 thisSproingie->g = 0.0;
252 if ((thisSproingie->b -= 0.08) < 0.0)
253 thisSproingie->b = 0.0;
254 if ((--(thisSproingie->life)) < 1) {
255 thisSproingie->life = RESET_SPROINGIE;
256 }
257 return;
258 }
259 thisSproingie->x += 1;
260 thisSproingie->y -= 2;
261 thisSproingie->z += 1;
262 thisSproingie->frame = 0;
263
264 for (t2 = 0; t2 < si->maxsproingies; ++t2) {
265 if ((t2 != t) && (thisSproingie->x == S2->x) &&
266 (thisSproingie->y == S2->y) && (thisSproingie->z == S2->z) &&
267 (S2->life > 10) && (S2->frame < 6)) {
268 #if 0
269 if (thisSproingie->life > S2->life) {
270 S2->life = 10;
271 } else {
272 #endif
273 if (thisSproingie->life > 10) {
274 thisSproingie->life = 10;
275 thisSproingie->frame = BOOM_FRAME;
276 if ((thisSproingie->r += 0.5) > 1.0)
277 thisSproingie->r = 1.0;
278 if ((thisSproingie->g += 0.5) > 1.0)
279 thisSproingie->g = 1.0;
280 if ((thisSproingie->b += 0.5) > 1.0)
281 thisSproingie->b = 1.0;
282 }
283 #if 0
284 }
285 #endif
286 }
287 ++S2;
288 }
289 }
290 if (!((thisSproingie->life == 10) &&
291 (thisSproingie->frame > 0) &&
292 (thisSproingie->frame < BOOM_FRAME))) {
293 if ((--(thisSproingie->life)) < 1) {
294 thisSproingie->life = RESET_SPROINGIE;
295 } else if (thisSproingie->life < 9) {
296 thisSproingie->frame -= 2;
297 }
298 } /* else wait here for frame 0 to come about. */
299 } else if (++(thisSproingie->life) >= 0) {
300 if (t > 1) {
301 g_higher = -3 + myrand(5);
302 g_back = -2 + myrand(5);
303 } else if (t == 1) {
304 g_higher = -2 + myrand(3);
305 g_back = -1 + myrand(3);
306 } else {
307 g_higher = -1;
308 g_back = 0;
309 }
310
311 thisSproingie->x = (-g_higher - g_back);
312 thisSproingie->y = (g_higher << 1);
313 thisSproingie->z = (g_back - g_higher);
314 thisSproingie->life = 40 + myrand(200);
315 thisSproingie->frame = -10;
316 thisSproingie->r = (GLfloat) (40 + myrand(200)) / 255.0;
317 thisSproingie->g = (GLfloat) (40 + myrand(200)) / 255.0;
318 thisSproingie->b = (GLfloat) (40 + myrand(200)) / 255.0;
319
320 for (t2 = 0; t2 < si->maxsproingies; ++t2) {
321 if ((t2 != t) && (thisSproingie->x == S2->x) &&
322 (thisSproingie->y == S2->y) && (thisSproingie->z == S2->z) &&
323 (S2->life > 10) && (S2->frame < 0)) {
324 /* If one is already being born, just wait. */
325 thisSproingie->life = -1;
326 }
327 ++S2;
328 }
329 }
330 }
331
332 static void
NextSproingie(int screen)333 NextSproingie(int screen)
334 {
335 sp_instance *si = &si_list[screen];
336 int ddx, t;
337 struct sPosColor *thisSproingie = &(si->positions[0]);
338
339 if (++si->sframe > 11) {
340 si->sframe = 0;
341 for (t = 0; t < si->maxsproingies; ++t) {
342 thisSproingie->x -= 1;
343 thisSproingie->y += 2;
344 thisSproingie->z -= 1;
345 ++thisSproingie;
346 }
347 }
348 for (t = 0; t < si->maxsproingies; ++t) {
349 AdvanceSproingie(t, si);
350 }
351
352 if (si->target_count < 0) { /* track to current target */
353 if (si->target_rx < si->rotx)
354 --si->rotx;
355 else if (si->target_rx > si->rotx)
356 ++si->rotx;
357
358 if (si->target_ry < si->roty)
359 --si->roty;
360 else if (si->target_ry > si->roty)
361 ++si->roty;
362
363 ddx = (si->target_dist - si->dist) / 8;
364 if (ddx)
365 si->dist += ddx;
366 else if (si->target_dist < si->dist)
367 --si->dist;
368 else if (si->target_dist > si->dist)
369 ++si->dist;
370
371 if ((si->target_rx == si->rotx) && (si->target_ry == si->roty) &&
372 (si->target_dist == si->dist)) {
373 si->target_count = T_COUNT;
374 if (si->target_dist <= 32)
375 si->target_count >>= 2;
376 }
377 } else if (--si->target_count < 0) { /* make up new target */
378 si->target_rx = myrand(100) - 35;
379 si->target_ry = -myrand(90);
380 si->target_dist = 32 << myrand(2); /* could be 32, 64, or 128, (previously or 256) */
381
382 if (si->target_dist >= si->dist) /* no duplicate distances */
383 si->target_dist <<= 1;
384 }
385 /* Otherwise just hang loose for a while here */
386 }
387
388 #ifdef __AUXFUNCS__
389 void
PrintEm(void)390 PrintEm(void)
391 {
392 int t, count = 0;
393
394 for (t = 0; t < maxsproingies; ++t) {
395 if (positions[t].life > 0)
396 ++count;
397 }
398 (void) printf("RotX: %d, RotY: %d, Dist: %d. Targets: X %d, Y %d, D %d. Visible: %d\n",
399 rotx, roty, dist, target_rx, target_ry, target_dist, count);
400 }
401
402 void
ResetEm(void)403 ResetEm(void)
404 {
405 int t;
406
407 for (t = 0; t < maxsproingies; ++t) {
408 positions[t].x = 0;
409 positions[t].y = 0;
410 positions[t].z = 0;
411 positions[t].life = -2;
412 positions[t].frame = 0;
413 }
414 }
415
416 void
distAdd(void)417 distAdd(void)
418 {
419 if (dist < (1 << 16 << 4))
420 dist <<= 1;
421 }
422
423 void
distSubtract(void)424 distSubtract(void)
425 {
426 if (dist > 1)
427 dist >>= 1;
428 }
429
430 void
rotxAdd(void)431 rotxAdd(void)
432 {
433 rotx = (rotx + 5) % 360;
434 }
435
436 void
rotxSubtract(void)437 rotxSubtract(void)
438 {
439 rotx = (rotx - 5) % 360;
440 }
441
442 void
rotyAdd(void)443 rotyAdd(void)
444 {
445 roty = (roty + 5) % 360;
446 }
447
448 void
rotySubtract(void)449 rotySubtract(void)
450 {
451 roty = (roty - 5) % 360;
452 }
453
454 void
rotxBAdd(void)455 rotxBAdd(void)
456 {
457 rotx = (rotx + 45) % 360;
458 }
459
460 void
rotxBSubtract(void)461 rotxBSubtract(void)
462 {
463 rotx = (rotx - 45) % 360;
464 }
465
466 void
rotyBAdd(void)467 rotyBAdd(void)
468 {
469 roty = (roty + 45) % 360;
470 }
471
472 void
rotyBSubtract(void)473 rotyBSubtract(void)
474 {
475 roty = (roty - 45) % 360;
476 }
477
478 #endif
479
480 static void
RenderSproingie(int t,sp_instance * si)481 RenderSproingie(int t, sp_instance * si)
482 {
483 GLfloat scale, pointsize, mat_color[4] =
484 {0.0, 0.0, 0.0, 1.0};
485 GLdouble clipplane[4] =
486 {0.0, 1.0, 0.0, 0.0};
487 struct sPosColor *thisSproingie = &(si->positions[t]);
488
489 if (thisSproingie->life < 1)
490 return;
491
492 glPushMatrix();
493
494 if (!si->mono) {
495 mat_color[0] = thisSproingie->r;
496 mat_color[1] = thisSproingie->g;
497 mat_color[2] = thisSproingie->b;
498 if (si->wireframe)
499 glColor3fv(mat_color);
500 else {
501 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_color);
502 }
503 }
504 if (thisSproingie->frame < 0) {
505 glEnable(GL_CLIP_PLANE0);
506 glTranslatef((GLfloat) (thisSproingie->x),
507 (GLfloat) (thisSproingie->y) +
508 ((GLfloat) (thisSproingie->frame) / 9.0),
509 (GLfloat) (thisSproingie->z));
510 clipplane[3] = ((GLdouble) (thisSproingie->frame) / 9.0) +
511 (si->wireframe ? 0.0 : 0.1);
512 glClipPlane(GL_CLIP_PLANE0, clipplane);
513 glCallList(si->sproingies[0]);
514 glDisable(GL_CLIP_PLANE0);
515 } else if (thisSproingie->frame >= BOOM_FRAME) {
516 glTranslatef((GLfloat) (thisSproingie->x) + 0.5,
517 (GLfloat) (thisSproingie->y) + 0.5,
518 (GLfloat) (thisSproingie->z) - 0.5);
519 scale = (GLfloat) (1 << (thisSproingie->frame - BOOM_FRAME));
520 glScalef(scale, scale, scale);
521 if (!si->wireframe) {
522 if (!si->mono)
523 glColor3fv(mat_color);
524 glDisable(GL_LIGHTING);
525 }
526 pointsize = (GLfloat) ((BOOM_FRAME + 8) - thisSproingie->frame) -
527 (si->dist / 64.0);
528 glPointSize((pointsize < 1.0) ? 1.0 : pointsize);
529 /*-
530 * PURIFY 4.0.1 reports an uninitialized memory read on the next line when using
531 * MesaGL 2.2. This has been tracked to MesaGL 2.2 src/points.c line 313. */
532 glCallList(si->SproingieBoom);
533 glPointSize(1.0);
534 if (!si->wireframe) {
535 glEnable(GL_LIGHTING);
536 }
537 } else if (thisSproingie->frame > 5) {
538 glTranslatef((GLfloat) (thisSproingie->x + 1),
539 (GLfloat) (thisSproingie->y - 1), (GLfloat) (thisSproingie->z - 1));
540 glRotatef((GLfloat) - 90.0, 0.0, 1.0, 0.0);
541 glCallList(si->sproingies[thisSproingie->frame - 6]);
542 } else {
543 glTranslatef((GLfloat) (thisSproingie->x), (GLfloat) (thisSproingie->y),
544 (GLfloat) (thisSproingie->z));
545 glCallList(si->sproingies[thisSproingie->frame]);
546 }
547
548 glPopMatrix();
549
550 }
551
552 static void
ComputeGround(sp_instance * si)553 ComputeGround(sp_instance * si)
554 {
555 int g_higher, g_back, g_width, g_height;
556
557 /* higher: x-1, y+2, z-1 */
558 /* back: x-1, y, z+1 */
559
560 if (si->groundlevel == 0) {
561 g_back = 2;
562 g_width = 5;
563 } else if (si->groundlevel == 1) {
564 g_back = 4;
565 g_width = 8;
566 } else {
567 g_back = 8;
568 g_width = 16;
569 }
570
571 if ((g_higher = si->dist >> 3) < 4)
572 g_higher = 4;
573 if (g_higher > 16)
574 g_higher = 16;
575 g_height = g_higher << 1;
576
577 if (si->rotx < -10)
578 g_higher += (g_higher >> 2);
579 else if (si->rotx > 10)
580 g_higher -= (g_higher >> 2);
581
582 #if 0
583 if (si->dist > 128) {
584 ++g_higher;
585 ++g_back;
586 g_back <<= 1;
587 } else if (si->dist > 64) {
588 ++g_higher;
589 ++g_back;
590 } else if (si->dist > 32) {
591 /* nothing special */
592 } else {
593 if (g_higher > 2) {
594 g_higher = g_back = 4;
595 }
596 }
597 #endif
598
599 /* startx, starty, startz, width, height */
600 LayGround((-g_higher - g_back), (g_higher << 1), (g_back - g_higher),
601 (g_width), (g_height), si);
602 }
603
604 void
DisplaySproingies(int screen)605 DisplaySproingies(int screen)
606 {
607 sp_instance *si = &si_list[screen];
608 int t;
609 GLfloat position[] =
610 {8.0, 5.0, -2.0, 0.1};
611
612 if (si->wireframe)
613 glClear(GL_COLOR_BUFFER_BIT);
614 else
615 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
616
617 glPushMatrix();
618 glTranslatef(0.0, 0.0, -(GLfloat) (si->dist) / 16.0); /* viewing transform */
619 glRotatef((GLfloat) si->rotx, 1.0, 0.0, 0.0);
620 glRotatef((GLfloat) si->roty, 0.0, 1.0, 0.0);
621
622 if (!si->wireframe)
623 glLightfv(GL_LIGHT0, GL_POSITION, position);
624
625 #if 0 /* Show light pos */
626 glPushMatrix();
627 glTranslatef(position[0], position[1], position[2]);
628 glColor3f(1.0, 1.0, 1.0);
629 if (!si->wireframe) {
630 glDisable(GL_LIGHTING);
631 }
632 glCallList(si->SproingieBoom);
633 if (!si->wireframe) {
634 glEnable(GL_LIGHTING);
635 }
636 glPopMatrix();
637 #endif
638
639 glTranslatef((GLfloat) si->sframe * (-1.0 / 12.0) - 0.75,
640 (GLfloat) si->sframe * (2.0 / 12.0) - 0.5,
641 (GLfloat) si->sframe * (-1.0 / 12.0) + 0.75);
642
643 if (si->wireframe)
644 ComputeGround(si);
645
646 for (t = 0; t < si->maxsproingies; ++t) {
647 RenderSproingie(t, si);
648 }
649
650 if (!si->wireframe)
651 ComputeGround(si);
652
653 glPopMatrix();
654 glFlush();
655
656 SproingieSwap();
657 }
658
659 void
NextSproingieDisplay(int screen)660 NextSproingieDisplay(int screen)
661 {
662 NextSproingie(screen);
663 DisplaySproingies(screen);
664 }
665
666 #if 0
667 #include <GL/glu.h>
668 void
669 ReshapeSproingies(int w, int h)
670 {
671 glViewport(0, 0, w, h);
672 glMatrixMode(GL_PROJECTION);
673 glLoadIdentity();
674 gluPerspective(65.0, (GLfloat) w / (GLfloat) h, 0.1, 2000.0); /* was 200000.0 */
675 glMatrixMode(GL_MODELVIEW);
676 glLoadIdentity();
677 }
678
679 #endif
680
681 void
CleanupSproingies(int screen)682 CleanupSproingies(int screen)
683 {
684 sp_instance *si = &si_list[screen];
685 int t;
686
687 for (t = 0; t < 6; ++t)
688 if (glIsList(si->sproingies[t])) {
689 glDeleteLists(si->sproingies[t], 1);
690 si->sproingies[t] = 0;
691 }
692 if (glIsList(si->TopsSides)) {
693 glDeleteLists(si->TopsSides, 2);
694 si->TopsSides = 0;
695 }
696 if (glIsList(si->SproingieBoom)) {
697 glDeleteLists(si->SproingieBoom, 1);
698 si->SproingieBoom = 0;
699 }
700 if (si->positions) {
701 --active_screens;
702 free((si->positions));
703 si->positions = (struct sPosColor *) NULL;
704 }
705 if ((active_screens == 0) && si_list) {
706 free((si_list));
707 si_list = (sp_instance *) NULL;
708 }
709 }
710
711 Bool
InitSproingies(int wfmode,int grnd,int mspr,int screen,int numscreens,int mono)712 InitSproingies(int wfmode, int grnd, int mspr, int screen, int numscreens,
713 int mono)
714 {
715 GLfloat ambient[] =
716 {0.2, 0.2, 0.2, 1.0};
717 GLfloat position[] =
718 {10.0, 1.0, 1.0, 10.0};
719 GLfloat mat_diffuse[] =
720 {0.6, 0.6, 0.6, 1.0};
721 GLfloat mat_specular[] =
722 {0.8, 0.8, 0.8, 1.0};
723 GLfloat mat_shininess[] =
724 {50.0};
725
726 sp_instance *si;
727 int t;
728
729 if (si_list == NULL) {
730 if ((si_list = (sp_instance *) calloc(numscreens,
731 sizeof (sp_instance))) == NULL)
732 return False;
733 }
734 si = &si_list[screen];
735
736 active_screens++;
737 CleanupSproingies(screen);
738
739 if (mspr < 0)
740 mspr = 0;
741 if (mspr >= MAXSPROING)
742 mspr = MAXSPROING - 1;
743
744 si->rotx = 0;
745 si->roty = -45;
746 si->dist = (16 << 2);
747 si->sframe = 0;
748 si->target_count = 0;
749 si->mono = mono;
750
751 si->wireframe = si->flatshade = 0;
752
753 if (wfmode == 2)
754 si->flatshade = 1;
755 else if (wfmode)
756 si->wireframe = 1;
757
758 si->groundlevel = grnd;
759 si->maxsproingies = mspr;
760
761 if (si->maxsproingies) {
762 if ((si->positions = (struct sPosColor *) calloc(si->maxsproingies,
763 sizeof (struct sPosColor))) == NULL) {
764 si->maxsproingies = 0;
765 CleanupSproingies(screen);
766 return False;
767 }
768 }
769 for (t = 0; t < si->maxsproingies; ++t) {
770 si->positions[t].x = 0;
771 si->positions[t].y = 0;
772 si->positions[t].z = 0;
773 si->positions[t].life = (-t * ((si->maxsproingies > 19) ? 1 : 4)) - 2;
774 si->positions[t].frame = 0;
775 }
776
777 #if 0 /* Test boom */
778 si->positions[0].x = 0;
779 si->positions[0].y = 0;
780 si->positions[0].z = 0;
781 si->positions[0].life = 10;
782 si->positions[0].frame = BOOM_FRAME;
783 si->positions[0].r = 0.656863;
784 si->positions[0].g = 1.0;
785 si->positions[0].b = 0.656863;
786 #endif
787
788 if (!(si->TopsSides = build_TopsSides(si->wireframe))) {
789 (void) fprintf(stderr, "build_TopsSides\n");
790 CleanupSproingies(screen);
791 return False;
792 }
793
794 if (!(si->sproingies[0] = BuildLWO(si->wireframe, &LWO_s1_1))) {
795 (void) fprintf(stderr, "BuildLWO - 1\n");
796 CleanupSproingies(screen);
797 return False;
798 }
799 if (!(si->sproingies[1] = BuildLWO(si->wireframe, &LWO_s1_2))) {
800 (void) fprintf(stderr, "BuildLWO - 2\n");
801 CleanupSproingies(screen);
802 return False;
803 }
804 if (!(si->sproingies[2] = BuildLWO(si->wireframe, &LWO_s1_3))) {
805 (void) fprintf(stderr, "BuildLWO - 3\n");
806 CleanupSproingies(screen);
807 return False;
808 }
809 if (!(si->sproingies[3] = BuildLWO(si->wireframe, &LWO_s1_4))) {
810 (void) fprintf(stderr, "BuildLWO - 4\n");
811 CleanupSproingies(screen);
812 return False;
813 }
814 if (!(si->sproingies[4] = BuildLWO(si->wireframe, &LWO_s1_5))) {
815 (void) fprintf(stderr, "BuildLWO - 5\n");
816 CleanupSproingies(screen);
817 return False;
818 }
819 if (!(si->sproingies[5] = BuildLWO(si->wireframe, &LWO_s1_6))) {
820 (void) fprintf(stderr, "BuildLWO - 6\n");
821 CleanupSproingies(screen);
822 return False;
823 }
824 if (!(si->SproingieBoom = BuildLWO(si->wireframe, &LWO_s1_b))) {
825 (void) fprintf(stderr, "BuildLWO - b\n");
826 CleanupSproingies(screen);
827 return False;
828 }
829
830 if (si->wireframe) {
831 glShadeModel(GL_FLAT);
832 glDisable(GL_LIGHTING);
833 } else {
834 if (si->flatshade) {
835 glShadeModel(GL_FLAT);
836 position[0] = 1.0;
837 position[3] = 0.0;
838 }
839 glEnable(GL_LIGHTING);
840 glEnable(GL_LIGHT0);
841 glDepthFunc(GL_LEQUAL);
842 glEnable(GL_DEPTH_TEST);
843
844 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
845 glLightfv(GL_LIGHT0, GL_POSITION, position);
846
847 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
848 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
849 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
850
851 /* glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); */
852 glCullFace(GL_BACK);
853 glEnable(GL_CULL_FACE);
854
855 glFrontFace(GL_CW);
856 /* glEnable(GL_NORMALIZE); */
857 }
858 return True;
859 }
860
861 #endif
862
863 /* End of sproingies.c */
864