/* -*- Mode: C; tab-width: 4 -*- */
/* sproingies.c - 3D sproingies */
-#if !defined( lint ) && !defined( SABER )
+#if 0
static const char sccsid[] = "@(#)sproingies.c 4.04 97/07/28 xlockmore";
-
#endif
/*-
* other special, indirect and consequential damages.
*
* Revision History:
- * 07-Dec-96: Written.
+ * See sproingiewrap.c
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
#ifdef STANDALONE
# include "xlockmoreI.h" /* from the xscreensaver distribution */
#else /* !STANDALONE */
#ifdef USE_GL
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include "buildlwo.h"
-
-#define MAXSPROING 100
-#define T_COUNT 40
-#define BOOM_FRAME 50
-
-struct sPosColor {
- int x, y, z, frame, life;
- GLfloat r, g, b;
-};
+#if !defined(HAVE_JWZGLES) && !defined(HAVE_COCOA)
+# include <GL/glu.h>
+#endif
-typedef struct {
- int rotx, roty, dist, wireframe, flatshade, groundlevel,
- maxsproingies, mono;
- int sframe, target_rx, target_ry, target_dist, target_count;
- GLuint sproingies[6], TopsSides, SproingieBoom;
- struct sPosColor *positions;
-} sp_instance;
+#include "gllist.h"
+#include "sproingies.h"
-static sp_instance *si_list = NULL;
-static int active_screens = 0;
+#define MAXSPROING 100
+#define TARGET_COUNT 40
+#define BOOM_FRAME 50
+#define NO_FRAME (-10)
+#define RESET_SPROINGIE_LIFE (-30 + myrand(28))
+#define NEW_SPROINGIE_LIFE (40 + myrand(200))
+#define JUMP_LEFT 0
+#define JUMP_RIGHT 1
-void SproingieSwap(void);
+#define FIRST_FRAME 0
+#define LAST_FRAME 5
+/*-
+ * The sproingies have six "real" frames, (s1_1 to s1_6) that show a
+ * sproingie jumping off a block, headed down and to the right.
+ * The frames are numbered from 0 (FIRST_FRAME) to 5 (LAST_FRAME).
+ *
+ * There are other frame numbers for special cases (e.g. BOOM_FRAME).
+ */
-extern struct lwo LWO_s1_1, LWO_s1_2, LWO_s1_3, LWO_s1_4;
-extern struct lwo LWO_s1_5, LWO_s1_6, LWO_s1_b;
+extern const struct gllist *s1_1;
+extern const struct gllist *s1_2;
+extern const struct gllist *s1_3;
+extern const struct gllist *s1_4;
+extern const struct gllist *s1_5;
+extern const struct gllist *s1_6;
+extern const struct gllist *s1_b;
static int
myrand(int range)
return ((int) (((float) range) * LRAND() / (MAXRAND)));
}
+static int smart_sproingies = 0;
+
static GLuint
build_TopsSides(int wireframe)
{
/* Surface: Sides */
glNewList(dl_num + 1, GL_COMPILE);
- mat_color[0] = 0.156863;
- mat_color[1] = 0.156863;
- mat_color[2] = 0.392157;
if (wireframe)
glColor3fv(mat_color);
else {
+ /* jwz: in wireframe mode, color tops and sides the same. */
+ mat_color[0] = 0.156863;
+ mat_color[1] = 0.156863;
+ mat_color[2] = 0.392157;
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_color);
}
glEndList();
}
}
-#define RESET_SPROINGIE (-30 + myrand(28))
-
static void
AdvanceSproingie(int t, sp_instance * si)
{
struct sPosColor *S2 = &(si->positions[0]);
if (thisSproingie->life > 0) {
- if ((++(thisSproingie->frame)) > 11) {
+ if ((++(thisSproingie->frame)) > LAST_FRAME) {
if (thisSproingie->frame >= BOOM_FRAME) {
if ((thisSproingie->r -= 0.08) < 0.0)
thisSproingie->r = 0.0;
if ((thisSproingie->b -= 0.08) < 0.0)
thisSproingie->b = 0.0;
if ((--(thisSproingie->life)) < 1) {
- thisSproingie->life = RESET_SPROINGIE;
+ thisSproingie->life = RESET_SPROINGIE_LIFE;
}
return;
}
- thisSproingie->x += 1;
- thisSproingie->y -= 2;
- thisSproingie->z += 1;
- thisSproingie->frame = 0;
+ thisSproingie->frame = FIRST_FRAME;
+ /* Check for collisions */
for (t2 = 0; t2 < si->maxsproingies; ++t2) {
if ((t2 != t) && (thisSproingie->x == S2->x) &&
(thisSproingie->y == S2->y) && (thisSproingie->z == S2->z) &&
- (S2->life > 10) && (S2->frame < 6)) {
+ (S2->life > 10) && (S2->frame < LAST_FRAME + 1)) {
#if 0
if (thisSproingie->life > S2->life) {
S2->life = 10;
++S2;
}
}
+ /* Time to disappear... */
if (!((thisSproingie->life == 10) &&
- (thisSproingie->frame > 0) &&
+ (thisSproingie->frame > FIRST_FRAME) &&
(thisSproingie->frame < BOOM_FRAME))) {
if ((--(thisSproingie->life)) < 1) {
- thisSproingie->life = RESET_SPROINGIE;
+ thisSproingie->life = RESET_SPROINGIE_LIFE;
} else if (thisSproingie->life < 9) {
thisSproingie->frame -= 2;
- }
- } /* else wait here for frame 0 to come about. */
+ }
+ } /* ... else wait here for frame FIRST_FRAME to come about. */
} else if (++(thisSproingie->life) >= 0) {
- if (t > 1) {
+ if (1 || t > 1) {
g_higher = -3 + myrand(5);
g_back = -2 + myrand(5);
} else if (t == 1) {
g_back = 0;
}
- thisSproingie->x = (-g_higher - g_back);
- thisSproingie->y = (g_higher << 1);
- thisSproingie->z = (g_back - g_higher);
- thisSproingie->life = 40 + myrand(200);
- thisSproingie->frame = -10;
- thisSproingie->r = (GLfloat) (40 + myrand(200)) / 255.0;
- thisSproingie->g = (GLfloat) (40 + myrand(200)) / 255.0;
- thisSproingie->b = (GLfloat) (40 + myrand(200)) / 255.0;
+ thisSproingie->x = (-g_higher - g_back);
+ thisSproingie->y = (g_higher << 1);
+ thisSproingie->z = (g_back - g_higher);
+ thisSproingie->life = NEW_SPROINGIE_LIFE;
+ thisSproingie->frame = NO_FRAME;
+ thisSproingie->r = (GLfloat) (40 + myrand(200)) / 255.0;
+ thisSproingie->g = (GLfloat) (40 + myrand(200)) / 255.0;
+ thisSproingie->b = (GLfloat) (40 + myrand(200)) / 255.0;
for (t2 = 0; t2 < si->maxsproingies; ++t2) {
if ((t2 != t) && (thisSproingie->x == S2->x) &&
(thisSproingie->y == S2->y) && (thisSproingie->z == S2->z) &&
- (S2->life > 10) && (S2->frame < 0)) {
- /* If one is already being born, just wait. */
+ (S2->life > 10) && (S2->frame < FIRST_FRAME)) {
+ /* If another is already on this place, wait. */
thisSproingie->life = -1;
}
++S2;
}
static void
-NextSproingie(int screen)
+NextSproingie(sp_instance *si)
{
- sp_instance *si = &si_list[screen];
int ddx, t;
struct sPosColor *thisSproingie = &(si->positions[0]);
+ /* Although the sproingies cycle has six frames, the blocks cycle */
+ /* has twelve. After a full cycle (12 frames), re-center positions */
+ /* of sproingies */
if (++si->sframe > 11) {
- si->sframe = 0;
+ si->sframe = FIRST_FRAME;
for (t = 0; t < si->maxsproingies; ++t) {
thisSproingie->x -= 1;
thisSproingie->y += 2;
++thisSproingie;
}
}
+
for (t = 0; t < si->maxsproingies; ++t) {
AdvanceSproingie(t, si);
}
if ((si->target_rx == si->rotx) && (si->target_ry == si->roty) &&
(si->target_dist == si->dist)) {
- si->target_count = T_COUNT;
+ si->target_count = TARGET_COUNT;
if (si->target_dist <= 32)
si->target_count >>= 2;
}
positions[t].y = 0;
positions[t].z = 0;
positions[t].life = -2;
- positions[t].frame = 0;
+ positions[t].frame = FIRST_FRAME;
}
}
roty = (roty - 45) % 360;
}
-#endif
+#endif /* __AUXFUNCS__ */
static void
RenderSproingie(int t, sp_instance * si)
{
GLfloat scale, pointsize, mat_color[4] =
{0.0, 0.0, 0.0, 1.0};
+#ifndef HAVE_JWZGLES
GLdouble clipplane[4] =
{0.0, 1.0, 0.0, 0.0};
+#endif
struct sPosColor *thisSproingie = &(si->positions[t]);
if (thisSproingie->life < 1)
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_color);
}
}
- if (thisSproingie->frame < 0) {
+
+ if (thisSproingie->frame < FIRST_FRAME) {
glEnable(GL_CLIP_PLANE0);
glTranslatef((GLfloat) (thisSproingie->x),
(GLfloat) (thisSproingie->y) +
((GLfloat) (thisSproingie->frame) / 9.0),
(GLfloat) (thisSproingie->z));
+
+#ifndef HAVE_JWZGLES
+ /* OpenGLES doesn't have this but it doesn't seem to matter */
clipplane[3] = ((GLdouble) (thisSproingie->frame) / 9.0) +
(si->wireframe ? 0.0 : 0.1);
glClipPlane(GL_CLIP_PLANE0, clipplane);
- glCallList(si->sproingies[0]);
+#endif
+
+/** glCallList(si->sproingies[0]);*/
+/**/ renderList(si->sproingies[0], si->wireframe);
glDisable(GL_CLIP_PLANE0);
} else if (thisSproingie->frame >= BOOM_FRAME) {
glTranslatef((GLfloat) (thisSproingie->x) + 0.5,
(GLfloat) (thisSproingie->y) + 0.5,
(GLfloat) (thisSproingie->z) - 0.5);
- scale = (GLfloat) (1 << (thisSproingie->frame - BOOM_FRAME));
+ {
+ int boom_scale = thisSproingie->frame - BOOM_FRAME;
+ if (boom_scale >= 31) boom_scale = 31;
+ scale = (GLfloat) (1 << boom_scale);
+ }
glScalef(scale, scale, scale);
if (!si->wireframe) {
if (!si->mono)
/*-
* PURIFY 4.0.1 reports an unitialized memory read on the next line when using
* MesaGL 2.2. This has been tracked to MesaGL 2.2 src/points.c line 313. */
- glCallList(si->SproingieBoom);
+/** glCallList(si->SproingieBoom);*/
+/**/ renderList(si->SproingieBoom, si->wireframe);
glPointSize(1.0);
if (!si->wireframe) {
glEnable(GL_LIGHTING);
}
- } else if (thisSproingie->frame > 5) {
- glTranslatef((GLfloat) (thisSproingie->x + 1),
- (GLfloat) (thisSproingie->y - 1), (GLfloat) (thisSproingie->z - 1));
- glRotatef((GLfloat) - 90.0, 0.0, 1.0, 0.0);
- glCallList(si->sproingies[thisSproingie->frame - 6]);
} else {
- glTranslatef((GLfloat) (thisSproingie->x), (GLfloat) (thisSproingie->y),
- (GLfloat) (thisSproingie->z));
- glCallList(si->sproingies[thisSproingie->frame]);
+ if (thisSproingie->direction == JUMP_LEFT) {
+ /* When the sproingie jumps to the left, the frames must be */
+ /* rotated and translated */
+ glTranslatef((GLfloat) (thisSproingie->x ),
+ (GLfloat) (thisSproingie->y ),
+ (GLfloat) (thisSproingie->z - 1));
+ glRotatef((GLfloat) - 90.0, 0.0, 1.0, 0.0);
+ if (thisSproingie->frame == LAST_FRAME) {
+ thisSproingie->x -= 0;
+ thisSproingie->y -= 1;
+ thisSproingie->z += 1;
+ }
+ } else {
+ glTranslatef((GLfloat) (thisSproingie->x),
+ (GLfloat) (thisSproingie->y),
+ (GLfloat) (thisSproingie->z));
+ glRotatef((GLfloat) - 0.0, 0.0, 1.0, 0.0);
+ if (thisSproingie->frame == LAST_FRAME) {
+ thisSproingie->x += 1;
+ thisSproingie->y -= 1;
+ thisSproingie->z -= 0;
+ }
+ }
+/* } */
+/** glCallList(si->sproingies[thisSproingie->frame]);*/
+/**/ renderList(si->sproingies[thisSproingie->frame], si->wireframe);
+
+ /* Every 6 frame cycle... */
+ if (thisSproingie->frame == LAST_FRAME) {
+ /* ...check if the sproingies have gone out of the bricks */
+ if (((thisSproingie->x - thisSproingie->z == 6) &&
+ (2*thisSproingie->x + thisSproingie->y == 6)) ||
+ ((thisSproingie->z - thisSproingie->x == 5) &&
+ (2*thisSproingie->x + thisSproingie->y == -5))) {
+ /* If they have, then they die */
+ if (thisSproingie->life > 0 && thisSproingie->frame < BOOM_FRAME && thisSproingie->frame > FIRST_FRAME) {
+ thisSproingie->frame = BOOM_FRAME;
+ }
+ } else {
+ /* If not, they choose a direction for the next hop */
+ if (smart_sproingies) {
+ if ((thisSproingie->x - thisSproingie->z == 5) &&
+ (2*thisSproingie->x + thisSproingie->y == 5)) {
+ thisSproingie->direction = JUMP_LEFT;
+ } else if ((thisSproingie->z - thisSproingie->x == 4) &&
+ (2*thisSproingie->x + thisSproingie->y == -4)) {
+ thisSproingie->direction = JUMP_RIGHT;
+ } else {
+ thisSproingie->direction = myrand(2);
+ }
+ } else {
+ thisSproingie->direction = myrand(2);
+ }
+ }
+ }
}
glPopMatrix();
}
void
-DisplaySproingies(int screen,int pause)
+DisplaySproingies(sp_instance *si)
{
- sp_instance *si = &si_list[screen];
int t;
GLfloat position[] =
{8.0, 5.0, -2.0, 0.1};
glPopMatrix();
glFlush();
-
- SproingieSwap();
}
void
-NextSproingieDisplay(int screen,int pause)
+NextSproingieDisplay(sp_instance *si)
{
- NextSproingie(screen);
- if (pause) usleep(pause);
- DisplaySproingies(screen,pause);
+ NextSproingie(si);
+/* if (pause) usleep(pause); don't do this! -jwz */
+ DisplaySproingies(si);
}
void
-ReshapeSproingies(int w, int h)
+ReshapeSproingies(int width, int height)
{
- glViewport(0, 0, w, h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(65.0, (GLfloat) w / (GLfloat) h, 0.1, 2000.0); /* was 200000.0 */
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
+ double h = (GLfloat) height / (GLfloat) width;
+ int y = 0;
+
+ if (width > height * 5) { /* tiny window: show middle */
+ height = width * 9/16;
+ y = -height/2;
+ h = height / (GLfloat) width;
+ }
+
+ glViewport(0, y, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(65.0, 1/h, 0.1, 2000.0); /* was 200000.0 */
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
}
void
-CleanupSproingies(int screen)
+CleanupSproingies(sp_instance *si)
{
- sp_instance *si = &si_list[screen];
- int t;
+ if (! si) return;
+/*
+ int t;
if (si->SproingieBoom) {
for (t = 0; t < 6; ++t)
glDeleteLists(si->sproingies[t], 1);
glDeleteLists(si->TopsSides, 2);
glDeleteLists(si->SproingieBoom, 1);
- --active_screens;
si->SproingieBoom = 0;
}
+*/
+ if (si->TopsSides) {
+ glDeleteLists(si->TopsSides, 2);
+ }
if (si->positions) {
(void) free((void *) (si->positions));
si->positions = NULL;
}
- if ((active_screens == 0) && si_list) {
- (void) free((void *) (si_list));
- si_list = NULL;
- }
}
void
-InitSproingies(int wfmode, int grnd, int mspr, int screen, int numscreens,
- int mono)
+InitSproingies(sp_instance *si, int wfmode, int grnd, int mspr, int smrtspr,
+ int mono)
{
GLfloat ambient[] =
{0.2, 0.2, 0.2, 1.0};
GLfloat mat_shininess[] =
{50.0};
- sp_instance *si;
int t;
- if (si_list == NULL) {
- if ((si_list = (sp_instance *) calloc(numscreens,
- sizeof (sp_instance))) == NULL)
- return;
- }
- si = &si_list[screen];
-
- active_screens++;
- CleanupSproingies(screen);
+ memset (si, 0, sizeof(*si));
if (mspr < 0)
mspr = 0;
if (mspr >= MAXSPROING)
mspr = MAXSPROING - 1;
+ smart_sproingies = smrtspr;
+
si->rotx = 0;
si->roty = -45;
si->dist = (16 << 2);
si->positions[t].y = 0;
si->positions[t].z = 0;
si->positions[t].life = (-t * ((si->maxsproingies > 19) ? 1 : 4)) - 2;
- si->positions[t].frame = 0;
+ si->positions[t].frame = FIRST_FRAME;
+ si->positions[t].direction = myrand(2);
}
#if 0 /* Test boom */
if (!(si->TopsSides = build_TopsSides(si->wireframe)))
(void) fprintf(stderr, "build_TopsSides\n");
-
+/*
if (!(si->sproingies[0] = BuildLWO(si->wireframe, &LWO_s1_1)))
(void) fprintf(stderr, "BuildLWO - 1\n");
if (!(si->sproingies[1] = BuildLWO(si->wireframe, &LWO_s1_2)))
if (!(si->SproingieBoom = BuildLWO(si->wireframe, &LWO_s1_b)))
(void) fprintf(stderr, "BuildLWO - b\n");
+*/
+ si->sproingies[0]=s1_1;
+ si->sproingies[1]=s1_2;
+ si->sproingies[2]=s1_3;
+ si->sproingies[3]=s1_4;
+ si->sproingies[4]=s1_5;
+ si->sproingies[5]=s1_6;
+ si->SproingieBoom=s1_b;
if (si->wireframe) {
glShadeModel(GL_FLAT);
}
}
-#endif
+#endif /* USE_GL */
/* End of sproingies.c */
+