/* thebox --- 3D bouncing balls that explode */
-#if !defined( lint ) && !defined( SABER )
+#if 0
static const char sccsid[] = "@(#)boxed.c 0.9 01/09/26 xlockmore";
-
#endif
/*-
*/
#ifdef STANDALONE
-# define PROGCLASS "boxed"
-# define HACK_INIT init_boxed
-# define HACK_DRAW draw_boxed
-# define HACK_RESHAPE reshape_boxed
-# define boxed_opts xlockmore_opts
-# define DEFAULTS "*delay: 20000 \n" \
- "*showFPS: False \n" \
-
-# include "xlockmore.h" /* from the xscreensaver distribution */
+# define PROGCLASS "boxed"
+# define HACK_INIT init_boxed
+# define HACK_DRAW draw_boxed
+# define HACK_RESHAPE reshape_boxed
+# define boxed_opts xlockmore_opts
+
+# define DEF_SPEED "0.5"
+# define DEFAULTS "*delay: 20000 \n" \
+ "*showFPS: False \n" \
+
+# include "xlockmore.h" /* from the xscreensaver distribution */
#else /* !STANDALONE */
-# include "xlock.h" /* from the xlockmore distribution */
+# include "xlock.h" /* from the xlockmore distribution */
#endif /* !STANDALONE */
#ifdef USE_GL
#undef countof
#define countof(x) (int)(sizeof((x))/sizeof((*x)))
#undef rnd
-#define rnd() ( ((float)random()) / ((float)RAND_MAX * 2.0) )
+#define rnd() (frand(1.0))
-/* #define DEF_PLANETARY "False"
+GLfloat speed; /* jwz -- overall speed factor applied to all motion */
-static int planetary;
static XrmOptionDescRec opts[] = {
- {"-planetary", ".gears.planetary", XrmoptionNoArg, (caddr_t) "true" },
- {"+planetary", ".gears.planetary", XrmoptionNoArg, (caddr_t) "false" },
+ {"-speed", ".boxed.speed", XrmoptionSepArg, 0},
};
static argtype vars[] = {
- {(caddr_t *) &planetary, "planetary", "Planetary", DEF_PLANETARY, t_Bool},
+ {&speed, "speed", "Speed", DEF_SPEED, t_Float},
};
-*/
-/* ModeSpecOpts boxed_opts = {countof(opts), opts, countof(vars), vars, NULL}; */
-
-ModeSpecOpt boxed_opts = {0, NULL, 0, NULL, NULL};
+ModeSpecOpt boxed_opts = {countof(opts), opts, countof(vars), vars, NULL};
#ifdef USE_MODULES
/* rendering defines */
+
/* box size */
#define BOX_SIZE 20.0f
#define CAMDISTANCE_SPEED 1.5
/* rendering the sphere */
-#define MESH_SIZE 5
+#define MESH_SIZE 10
#define SPHERE_VERTICES (2+MESH_SIZE*MESH_SIZE*2)
#define SPHERE_INDICES ((MESH_SIZE*4 + MESH_SIZE*4*(MESH_SIZE-1))*3)
ballman bman;
triman *tman;
GLXContext *glx_context;
- GLint listobjects;
- GLint gllists[3];
+ GLuint listobjects;
+ GLuint gllists[3];
Window window;
BOOL stop;
char *tex1;
} boxedstruct;
-#define GLL_PATTERN 1
-#define GLL_BALL 2
-#define GLL_BOX 3
+#define GLL_PATTERN 0
+#define GLL_BALL 1
+#define GLL_BOX 2
/*
**----------------------------------------------------------------------------
* create fresh ball
*/
-void createball(ball *newball) {
+void createball(ball *newball)
+{
float r=0.0f,g=0.0f,b=0.0f;
newball->loc.x = 5-10*rnd();
newball->loc.y = 35+20*rnd();
newball->loc.z = 5-10*rnd();
- newball->dir.x = 0.5f-rnd();
+ newball->dir.x = (0.5f-rnd()) * speed;
newball->dir.y = 0.0;
- newball->dir.z = 0.5-rnd();
+ newball->dir.z = (0.5-rnd()) * speed;
newball->offside = 0;
newball->bounced = FALSE;
newball->radius = BALLSIZE;
/* Update position of each ball */
-void updateballs(ballman *bman) {
+void updateballs(ballman *bman)
+{
register int b,j;
vectorf dvect,richting,relspeed,influence;
GLfloat squaredist;
for (b=0;b<bman->num_balls;b++) {
+ GLfloat gravity = 0.15f * speed;
+
/* apply gravity */
- bman->balls[b].dir.y -= 0.15f;
+ bman->balls[b].dir.y -= gravity;
/* apply movement */
addvectors(&bman->balls[b].loc,&bman->balls[b].loc,&bman->balls[b].dir);
/* boundary check */
* explode ball into triangles
*/
-void createtrisfromball(triman* tman, vectorf *spherev, GLint *spherei, int ind_num, ball *b) {
+void createtrisfromball(triman* tman, vectorf *spherev, GLint *spherei, int ind_num, ball *b)
+{
int pos;
float explosion;
float scale;
/* bereken nieuwe richting */
scalevector(&tman->tris[i].dir,&avgdir,explosion);
- dvect.x = 0.1f - 0.2f*rnd();
- dvect.y = 0.15f - 0.3f*rnd();
- dvect.z = 0.1f - 0.2f*rnd();
+ dvect.x = (0.1f - 0.2f*rnd());
+ dvect.y = (0.15f - 0.3f*rnd());
+ dvect.z = (0.1f - 0.2f*rnd());
addvectors(&tman->tris[i].dir,&tman->tris[i].dir,&dvect);
}
}
* update position of each tri
*/
-void updatetris(triman *t) {
+void updatetris(triman *t)
+{
int b;
-
+ GLfloat xd,zd;
+
for (b=0;b<t->num_tri;b++) {
/* apply gravity */
- t->tris[b].dir.y -= 0.1f;
+ t->tris[b].dir.y -= (0.1f * speed);
/* apply movement */
addvectors(&t->tris[b].loc,&t->tris[b].loc,&t->tris[b].dir);
/* boundary check */
(t->tris[b].loc.z < 100.0f)) { /* in veld */
t->tris[b].dir.y = -(t->tris[b].dir.y);
t->tris[b].loc.y = -t->tris[b].loc.y;
- scalevector(&t->tris[b].dir,&t->tris[b].dir,0.75f); /* dampening */
+ scalevector(&t->tris[b].dir,&t->tris[b].dir,0.80f); /* dampening */
}
else {
t->tris[b].far = TRUE;
}
}
- /* this should be replaced with code that determines
- * the correct wall the tri bounces in to. this code sucks.
- */
- if ((t->tris[b].loc.x > -21.0f) &
+ if ((t->tris[b].loc.x > -21.0f) &
(t->tris[b].loc.x < 21.0f) &
(t->tris[b].loc.z > -21.0f) &
(t->tris[b].loc.z < 21.0f)) { /* in box? */
+
+ xd = zd = 999.0f; /* big */
if ((t->tris[b].loc.x > -21.0f) &
(t->tris[b].loc.x < 0)) {
- t->tris[b].loc.x = -21.0f;
- t->tris[b].dir.x = -t->tris[b].dir.x;
+ xd = t->tris[b].loc.x + 21.0f;
}
if ((t->tris[b].loc.x < 21.0f) &
(t->tris[b].loc.x > 0)) {
- t->tris[b].loc.x = 21.0f;
- t->tris[b].dir.x = -t->tris[b].dir.x;
+ xd = 21.0f - t->tris[b].loc.x;
}
if ((t->tris[b].loc.z > -21.0f) &
(t->tris[b].loc.z < 0)) {
- t->tris[b].loc.z = -21.0f;
- t->tris[b].dir.z = -t->tris[b].dir.z;
+ zd = t->tris[b].loc.z + 21.0f;
}
if ((t->tris[b].loc.z < 21.0f) &
(t->tris[b].loc.z > 0)) {
- t->tris[b].loc.z = 21.0f;
- t->tris[b].dir.z = -t->tris[b].dir.z;
+ zd = 21.0f - t->tris[b].loc.z;
}
+ if (xd < zd) {
+ /* bounce x */
+ if (t->tris[b].dir.x < 0)
+ t->tris[b].loc.x += (21.0f - t->tris[b].loc.x);
+ else
+ t->tris[b].loc.x += (-21.0f - t->tris[b].loc.x);
+ t->tris[b].dir.x = -t->tris[b].dir.x;
+ } else {
+ /* bounce z */
+ if (t->tris[b].dir.z < 0)
+ t->tris[b].loc.z += (21.0f - t->tris[b].loc.z);
+ else
+ t->tris[b].loc.z += (-21.0f - t->tris[b].loc.z);
+ t->tris[b].dir.z = -t->tris[b].dir.z;
+ }
+
}
} /* end for b */
}
/*
* free memory allocated by a tri manager
*/
-void freetris(triman *t) {
+void freetris(triman *t)
+{
if (!t) return;
if (t->tris) free(t->tris);
if (t->vertices) free(t->vertices);
/*
*load defaults in config structure
*/
-void setdefaultconfig(boxed_config *config) {
+void setdefaultconfig(boxed_config *config)
+{
config->numballs = NUMBALLS;
config->textures = TRUE;
config->transparent = FALSE;
glMaterialfv(GL_FRONT, GL_EMISSION,col);
if (!gp->gllists[GLL_BALL]) {
- glNewList(gp->listobjects + GLL_BALL,GL_COMPILE_AND_EXECUTE);
+ glNewList(gp->listobjects + GLL_BALL,GL_COMPILE);
cnt = SPHERE_INDICES/3;
for (i=0; i<cnt; i++) {
pos = i * 3;
static void drawpattern(boxedstruct *boxed)
{
if (!boxed->gllists[GLL_PATTERN]) {
- glNewList(boxed->listobjects + GLL_PATTERN,GL_COMPILE_AND_EXECUTE);
-
+ glNewList(boxed->listobjects + GLL_PATTERN, GL_COMPILE);
+
glBegin(GL_LINE_STRIP);
glVertex3f(-25.0f, 0.0f, 35.0f);
glVertex3f(-15.0f, 0.0f, 35.0f);
glVertex3f(-15.0f, 0.0f, 5.0f);
glVertex3f(-5.0f, 0.0f, 15.0f);
glEnd();
+
glEndList();
boxed->gllists[GLL_PATTERN] = 1;
} else {
glCallList(boxed->listobjects + GLL_PATTERN);
}
+
}
gp->tic += 0.01f;
/* rotate camera around (0,0,0), looking at (0,0,0), up is (0,1,0) */
- dcam = CAMDISTANCE_MIN + (CAMDISTANCE_MAX - CAMDISTANCE_MIN) + (CAMDISTANCE_MAX - CAMDISTANCE_MIN)*cos(gp->tic/CAMDISTANCE_SPEED);
- v1.x = dcam * sin(gp->tic/gp->cam_x_speed);
- v1.z = dcam * cos(gp->tic/gp->cam_z_speed);
- v1.y = CAM_HEIGHT * sin(gp->tic/gp->cam_y_speed) + 1.02 * CAM_HEIGHT;
+ dcam = CAMDISTANCE_MIN + (CAMDISTANCE_MAX - CAMDISTANCE_MIN) + (CAMDISTANCE_MAX - CAMDISTANCE_MIN)*cos((gp->tic/CAMDISTANCE_SPEED) * speed);
+ v1.x = dcam * sin((gp->tic/gp->cam_x_speed) * speed);
+ v1.z = dcam * cos((gp->tic/gp->cam_z_speed) * speed);
+ v1.y = CAM_HEIGHT * sin((gp->tic/gp->cam_y_speed) * speed) + 1.02 * CAM_HEIGHT;
gluLookAt(v1.x,v1.y,v1.z,0.0,0.0,0.0,0.0,1.0,0.0);
glLightfv(GL_LIGHT0, GL_AMBIENT, l0_ambient);
gp->bman.balls[i].justcreated = FALSE;
freetris(&gp->tman[i]);
}
- if ((gp->bman.balls[i].bounced) & (gp->tman[i].vertices == NULL)) {
- createtrisfromball(&gp->tman[i],gp->spherev,gp->spherei,SPHERE_INDICES,&gp->bman.balls[i]);
- }
- if (gp->bman.balls[i].bounced) {
- updatetris(&gp->tman[i]);
+ if (gp->bman.balls[i].bounced) {
+ if (gp->tman[i].vertices == NULL) {
+ createtrisfromball(&gp->tman[i],gp->spherev,gp->spherei,SPHERE_INDICES,&gp->bman.balls[i]);
+ } else {
+ updatetris(&gp->tman[i]);
+ }
glDisable(GL_CULL_FACE);
drawtriman(&gp->tman[i]);
glEnable(GL_CULL_FACE);
GL_RGB, GL_UNSIGNED_BYTE, gp->tex1);
if (i)
{
- const char *s = gluErrorString (i);
+ const char *s = (char *) gluErrorString (i);
fprintf (stderr, "%s: error mipmapping texture: %s\n",
progname, (s ? s : "(unknown)"));
exit (1);
void
release_boxed(ModeInfo * mi)
{
+ int i;
+
if (boxed != NULL) {
int screen;
/* Display lists MUST be freed while their glXContext is current. */
glXMakeCurrent(MI_DISPLAY(mi), gp->window, *(gp->glx_context));
- /*if (glIsList(gp->gear1))
- glDeleteLists(gp->gear1, 1);
- if (glIsList(gp->gear2))
- glDeleteLists(gp->gear2, 1);
- if (glIsList(gp->gear3))
- glDeleteLists(gp->gear3, 1);
- if (glIsList(gp->gear_inner))
- glDeleteLists(gp->gear_inner, 1);
- if (glIsList(gp->gear_outer))
- glDeleteLists(gp->gear_outer, 1);
- */
+ if (glIsList(gp->listobjects))
+ glDeleteLists(gp->listobjects, 3);
- /* TODO
- * free all trimans
- * free all balls
- * free all sphere indices & vertices
- */
+ for (i=0;i<gp->bman.num_balls;i++) {
+ if (gp->bman.balls[i].bounced) freetris(&gp->tman[i]);
+ }
+ free (gp->bman.balls);
+ free (gp->tman);
+ free (gp->tex1);
+
}
}