# include "config.h"
#endif
+#ifdef STANDALONE
+# include "xlockmoreI.h"
+#endif
+
/* HAVE_GLUT defined if we're building a standalone glsnake,
* and not defined if we're building as an xscreensaver hack */
#ifdef HAVE_GLUT
# include <GL/glut.h>
#else
-# include <GL/gl.h>
-# include <GL/glu.h>
+# ifdef HAVE_COCOA
+# include <OpenGL/gl.h>
+# include <OpenGL/glu.h>
+# define HAVE_GETTIMEOFDAY
+# else
+# include <GL/gl.h>
+# include <GL/glu.h>
+# endif
#endif
#include <stdio.h>
#endif
/* static variables */
-#ifndef HAVE_GLUT
-# include <X11/Intrinsic.h>
-#else
-/* xscreensaver boolean type */
-# define Bool int
-#endif
static GLfloat explode;
static long statictime;
static GLfloat angvel;
#ifndef HAVE_GLUT
-/* xscreensaver setup */
-extern XtAppContext app;
-
-#define PROGCLASS "glsnake"
-#define HACK_INIT glsnake_init
-#define HACK_DRAW glsnake_display
-#define HACK_RESHAPE glsnake_reshape
-#define sws_opts xlockmore_opts
+#define glsnake_init init_glsnake
+#define glsnake_display draw_glsnake
+#define glsnake_reshape reshape_glsnake
+#define refresh_glsnake 0
+#define release_glsnake 0
+#define glsnake_handle_event 0
/* xscreensaver defaults */
#define DEFAULTS "*delay: 30000 \n" \
{ "-statictime", ".statictime", XrmoptionSepArg, DEF_STATICTIME },
{ "-yangvel", ".yangvel", XrmoptionSepArg, DEF_YANGVEL },
{ "-zangvel", ".zangvel", XrmoptionSepArg, DEF_ZANGVEL },
- { "-altcolour", ".altcolour", XrmoptionNoArg, (caddr_t) "True" },
- { "-no-altcolour", ".altcolour", XrmoptionNoArg, (caddr_t) "False" },
- { "-titles", ".titles", XrmoptionNoArg, (caddr_t) "True" },
- { "-no-titles", ".titles", XrmoptionNoArg, (caddr_t) "False" },
+ { "-altcolour", ".altcolour", XrmoptionNoArg, "True" },
+ { "-no-altcolour", ".altcolour", XrmoptionNoArg, "False" },
+ { "-titles", ".titles", XrmoptionNoArg, "True" },
+ { "-no-titles", ".titles", XrmoptionNoArg, "False" },
{ "-zoom", ".zoom", XrmoptionSepArg, DEF_ZOOM },
- { "-wireframe", ".wireframe", XrmoptionNoArg, (caddr_t) "true" },
- { "-no-wireframe", ".wireframe", XrmoptionNoArg, (caddr_t) "false" },
- { "-transparent", ".transparent", XrmoptionNoArg, (caddr_t) "true" },
- { "-no-transparent", ".transparent", XrmoptionNoArg, (caddr_t) "false" },
+ { "-wireframe", ".wireframe", XrmoptionNoArg, "true" },
+ { "-no-wireframe", ".wireframe", XrmoptionNoArg, "false" },
+ { "-transparent", ".transparent", XrmoptionNoArg, "true" },
+ { "-no-transparent", ".transparent", XrmoptionNoArg, "false" },
};
static argtype vars[] = {
{&transparent, "transparent", "Transparent!", DEF_TRANSPARENT, t_Bool},
};
-ModeSpecOpt sws_opts = {(int)countof(opts), opts, (int)countof(vars), vars, NULL};
+ENTRYPOINT ModeSpecOpt glsnake_opts = {countof(opts), opts, countof(vars), vars, NULL};
#endif
struct model_s {
#define COLOUR_AUTHENTIC 3
#define COLOUR_ORIGLOGO 4
-float colour[][2][4] = {
+static const float colour[][2][4] = {
/* cyclic - green */
{ { 0.4, 0.8, 0.2, 0.6 },
{ 1.0, 1.0, 1.0, 0.6 } },
{ 46/255.0, 205/255.0, 227/255.0, 1.0 } }
};
-struct model_s model[] = {
+static const struct model_s model[] = {
#define STRAIGHT_MODEL 0
{ "straight",
{ ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
{ "Penis",
{ PIN, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, PIN, PIN, ZERO }
},
- { "PictureCommingSoon",
+ { "PictureComingSoon",
{ LEFT, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, ZERO, RIGHT, RIGHT, ZERO }
},
{ "Pitti",
},
};
-size_t models = sizeof(model) / sizeof(struct model_s);
+static size_t models = sizeof(model) / sizeof(struct model_s);
#define VOFFSET 0.045
#define RANDSIGN() ((random() & 1) ? 1 : -1)
/* the triangular prism what makes up the basic unit */
-float solid_prism_v[][3] = {
+static const float solid_prism_v[][3] = {
/* first corner, bottom left front */
{ VOFFSET, VOFFSET, 1.0 },
{ VOFFSET, 0.00, 1.0 - VOFFSET },
{ VOFFSET / M_SQRT1_2, 1.0 - VOFFSET * M_SQRT1_2, VOFFSET },
{ 0.0, 1.0 - VOFFSET / M_SQRT1_2, VOFFSET }};
-float solid_prism_n[][3] = {/* corners */
+static const float solid_prism_n[][3] = {/* corners */
{ -VOFFSET, -VOFFSET, VOFFSET },
{ VOFFSET, -VOFFSET, VOFFSET },
{ -VOFFSET, VOFFSET, VOFFSET },
{ -1.0, 0.0, 0.0 },
{ 0.0, 0.0, -1.0 }};
-float wire_prism_v[][3] = {{ 0.0, 0.0, 1.0 },
+static const float wire_prism_v[][3] = {{ 0.0, 0.0, 1.0 },
{ 1.0, 0.0, 1.0 },
{ 0.0, 1.0, 1.0 },
{ 0.0, 0.0, 0.0 },
{ 1.0, 0.0, 0.0 },
{ 0.0, 1.0, 0.0 }};
-float wire_prism_n[][3] = {{ 0.0, 0.0, 1.0},
+/*
+static const float wire_prism_n[][3] = {{ 0.0, 0.0, 1.0},
{ 0.0,-1.0, 0.0},
{ M_SQRT1_2, M_SQRT1_2, 0.0},
{-1.0, 0.0, 0.0},
{ 0.0, 0.0,-1.0}};
+*/
static struct glsnake_cfg * glc = NULL;
#ifdef HAVE_GLUT
#ifdef HAVE_GLUT
/* forward definitions for GLUT functions */
-void calc_rotation();
-inline void ui_mousedrag();
+static void calc_rotation();
+static inline void ui_mousedrag();
#endif
-GLfloat white_light[] = { 1.0, 1.0, 1.0, 1.0 };
-GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
-GLfloat mat_specular[] = { 0.1, 0.1, 0.1, 1.0 };
-GLfloat mat_shininess[] = { 20.0 };
+static const GLfloat white_light[] = { 1.0, 1.0, 1.0, 1.0 };
+static const GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
+static const GLfloat mat_specular[] = { 0.1, 0.1, 0.1, 1.0 };
+static const GLfloat mat_shininess[] = { 20.0 };
-void gl_init(
+static void gl_init(
#ifndef HAVE_GLUT
ModeInfo * mi
#endif
- ) {
+ )
+{
float light_pos[][3] = {{0.0, 10.0, 20.0}, {0.0, 20.0, -1.0}};
float light_dir[][3] = {{0.0, -10.0,-20.0}, {0.0,-20.0, 1.0}};
}
}
-void gettime(snaketime *t)
+static void gettime(snaketime *t)
{
#ifdef HAVE_GETTIMEOFDAY
#ifdef GETTIMEOFDAY_TWO_ARGS
#endif /* !HAVE_GETTIMEOFDAY */
}
-void start_morph(unsigned int model_index, int immediate);
+
+ENTRYPOINT void glsnake_reshape(
+#ifndef HAVE_GLUT
+ ModeInfo * mi,
+#endif
+ int w, int h);
+
+static void start_morph(struct glsnake_cfg *,
+ unsigned int model_index, int immediate);
/* wot initialises it */
-void glsnake_init(
+ENTRYPOINT void glsnake_init(
#ifndef HAVE_GLUT
ModeInfo * mi
#endif
-) {
+)
+{
#ifndef HAVE_GLUT
struct glsnake_cfg * bp;
bp->prev_colour = bp->next_colour = COLOUR_ACYCLIC;
bp->next_model = RAND(models);
bp->prev_model = START_MODEL;
- start_morph(bp->prev_model, 1);
+ start_morph(bp, bp->prev_model, 1);
/* set up a font for the labels */
#ifndef HAVE_GLUT
#endif
/* build a solid display list */
- glc->node_solid = glGenLists(1);
- glNewList(glc->node_solid, GL_COMPILE);
+ bp->node_solid = glGenLists(1);
+ glNewList(bp->node_solid, GL_COMPILE);
/* corners */
glBegin(GL_TRIANGLES);
glNormal3fv(solid_prism_n[0]);
glEndList();
/* build wire display list */
- glc->node_wire = glGenLists(1);
- glNewList(glc->node_wire, GL_COMPILE);
+ bp->node_wire = glGenLists(1);
+ glNewList(bp->node_wire, GL_COMPILE);
glBegin(GL_LINE_STRIP);
glVertex3fv(wire_prism_v[0]);
glVertex3fv(wire_prism_v[1]);
#endif
}
-void draw_title(
+static void draw_title(
#ifndef HAVE_GLUT
ModeInfo * mi
#endif
- ) {
+ )
+{
#ifndef HAVE_GLUT
struct glsnake_cfg * bp = &glc[MI_SCREEN(mi)];
#endif
glPushMatrix();
glLoadIdentity();
#ifdef HAVE_GLUT
- gluOrtho2D((GLdouble) 0., (GLdouble) glc->width, (GLdouble) 0., (GLdouble) glc->height);
+ gluOrtho2D((GLdouble) 0., (GLdouble) bp->width, (GLdouble) 0., (GLdouble) bp->height);
#else
gluOrtho2D((GLdouble) 0., (GLdouble) mi->xgwa.width, (GLdouble) 0., (GLdouble) mi->xgwa.height);
#endif
+
glColor4f(1.0, 1.0, 1.0, 1.0);
{
char interactstr[] = "interactive";
if (interactive)
s = interactstr;
else
- s = model[glc->next_model].name;
+ s = model[bp->next_model].name;
#ifdef HAVE_GLUT
{
unsigned int i = 0;
w = glutBitmapLength(GLUT_BITMAP_HELVETICA_12, (const unsigned char *) s);
- glRasterPos2f((GLfloat) (glc->width - w - 3), 4.0);
+ glRasterPos2f((GLfloat) (bp->width - w - 3), 4.0);
while (s[i] != '\0')
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, s[i++]);
}
}
/* apply the matrix to the origin and stick it in vec */
-void matmult_origin(float rotmat[16], float vec[4]) {
+static void matmult_origin(float rotmat[16], float vec[4])
+{
#if 1
vec[0] = 0.5 * rotmat[0] + 0.5 * rotmat[4] + 0.5 * rotmat [8] + 1 * rotmat[12];
vec[1] = 0.5 * rotmat[1] + 0.5 * rotmat[5] + 0.5 * rotmat [9] + 1 * rotmat[13];
}
/* wot gets called when the winder is resized */
-void glsnake_reshape(
+ENTRYPOINT void glsnake_reshape(
#ifndef HAVE_GLUT
ModeInfo * mi,
#endif
- int w, int h) {
+ int w, int h)
+{
glViewport(0, 0, (GLint) w, (GLint) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- gluPerspective(zoom, (GLdouble) w / (GLdouble) h, 0.05, 100.0);
+ /* jwz: 0.05 was too close (left black rectangles) */
+ gluPerspective(zoom, (GLdouble) w / (GLdouble) h, 1.0, 100.0);
gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glMatrixMode(GL_MODELVIEW);
/*gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);*/
glLoadIdentity();
#ifdef HAVE_GLUT
- glc->width = w;
- glc->height = h;
+ bp->width = w;
+ bp->height = h;
#endif
}
/* Returns the new dst_dir for the given src_dir and dst_dir */
-int cross_product(int src_dir, int dst_dir) {
+static int cross_product(int src_dir, int dst_dir)
+{
return X_MASK*(GETSCALAR(src_dir,Y_MASK) * GETSCALAR(dst_dir,Z_MASK) -
GETSCALAR(src_dir,Z_MASK) * GETSCALAR(dst_dir,Y_MASK))+
Y_MASK*(GETSCALAR(src_dir,Z_MASK) * GETSCALAR(dst_dir,X_MASK) -
* is_cyclic = true if last node connects back to first node
* last_turn = for cyclic snakes, specifes what the 24th turn would be
*/
-void calc_snake_metrics(void) {
+static void calc_snake_metrics(struct glsnake_cfg *bp)
+{
int srcDir, dstDir;
int i, x, y, z;
int prevSrcDir = -Y_MASK;
/* zero the grid */
memset(&grid, 0, sizeof(int) * 25*25*25);
- glc->is_legal = 1;
+ bp->is_legal = 1;
x = y = z = 12;
/* trace path of snake - and keep record for is_legal */
y += GETSCALAR(prevDstDir, Y_MASK);
z += GETSCALAR(prevDstDir, Z_MASK);
- switch ((int) model[glc->next_model].node[i]) {
+ switch ((int) model[bp->next_model].node[i]) {
case (int) (ZERO):
dstDir = -prevSrcDir;
break;
case (int) (RIGHT):
case (int) (LEFT):
dstDir = cross_product(prevSrcDir, prevDstDir);
- if (model[glc->next_model].node[i] == (int) (RIGHT))
+ if (model[bp->next_model].node[i] == (int) (RIGHT))
dstDir = -dstDir;
break;
default:
else if (grid[x][y][z] + srcDir + dstDir == 0)
grid[x][y][z] = 8;
else
- glc->is_legal = 0;
+ bp->is_legal = 0;
prevSrcDir = srcDir;
prevDstDir = dstDir;
}
/* determine if the snake is cyclic */
- glc->is_cyclic = (dstDir == Y_MASK && x == 12 && y == 11 && z == 12);
+ bp->is_cyclic = (dstDir == Y_MASK && x == 12 && y == 11 && z == 12);
/* determine last_turn */
- glc->last_turn = -1;
- if (glc->is_cyclic)
+ bp->last_turn = -1;
+ if (bp->is_cyclic)
switch (srcDir) {
- case -Z_MASK: glc->last_turn = ZERO; break;
- case Z_MASK: glc->last_turn = PIN; break;
- case X_MASK: glc->last_turn = LEFT; break;
- case -X_MASK: glc->last_turn = RIGHT; break;
+ case -Z_MASK: bp->last_turn = ZERO; break;
+ case Z_MASK: bp->last_turn = PIN; break;
+ case X_MASK: bp->last_turn = LEFT; break;
+ case -X_MASK: bp->last_turn = RIGHT; break;
}
}
/* work out how far through the current morph we are */
-float morph_percent(void) {
+static float morph_percent(struct glsnake_cfg *bp)
+{
float retval;
int i;
/* work out the maximum rotation this node has to go through
* from the previous to the next model, taking into account that
* the snake always morphs through the smaller angle */
- rot = fabs(model[glc->prev_model].node[i] -
- model[glc->next_model].node[i]);
+ rot = fabs(model[bp->prev_model].node[i] -
+ model[bp->next_model].node[i]);
if (rot > 180.0) rot = 180.0 - rot;
/* work out the difference between the current position and the
* target */
- ang_diff = fabs(glc->node[i] -
- model[glc->next_model].node[i]);
+ ang_diff = fabs(bp->node[i] -
+ model[bp->next_model].node[i]);
if (ang_diff > 180.0) ang_diff = 180.0 - ang_diff;
/* if it's the biggest so far, record it */
if (rot > rot_max) rot_max = rot;
return retval;
}
-void morph_colour(void) {
+static void morph_colour(struct glsnake_cfg *bp)
+{
float percent, compct; /* complement of percentage */
- percent = morph_percent();
+ percent = morph_percent(bp);
compct = 1.0 - percent;
- glc->colour[0][0] = colour[glc->prev_colour][0][0] * compct + colour[glc->next_colour][0][0] * percent;
- glc->colour[0][1] = colour[glc->prev_colour][0][1] * compct + colour[glc->next_colour][0][1] * percent;
- glc->colour[0][2] = colour[glc->prev_colour][0][2] * compct + colour[glc->next_colour][0][2] * percent;
- glc->colour[0][3] = colour[glc->prev_colour][0][3] * compct + colour[glc->next_colour][0][3] * percent;
+ bp->colour[0][0] = colour[bp->prev_colour][0][0] * compct + colour[bp->next_colour][0][0] * percent;
+ bp->colour[0][1] = colour[bp->prev_colour][0][1] * compct + colour[bp->next_colour][0][1] * percent;
+ bp->colour[0][2] = colour[bp->prev_colour][0][2] * compct + colour[bp->next_colour][0][2] * percent;
+ bp->colour[0][3] = colour[bp->prev_colour][0][3] * compct + colour[bp->next_colour][0][3] * percent;
- glc->colour[1][0] = colour[glc->prev_colour][1][0] * compct + colour[glc->next_colour][1][0] * percent;
- glc->colour[1][1] = colour[glc->prev_colour][1][1] * compct + colour[glc->next_colour][1][1] * percent;
- glc->colour[1][2] = colour[glc->prev_colour][1][2] * compct + colour[glc->next_colour][1][2] * percent;
- glc->colour[1][3] = colour[glc->prev_colour][1][3] * compct + colour[glc->next_colour][1][3] * percent;
+ bp->colour[1][0] = colour[bp->prev_colour][1][0] * compct + colour[bp->next_colour][1][0] * percent;
+ bp->colour[1][1] = colour[bp->prev_colour][1][1] * compct + colour[bp->next_colour][1][1] * percent;
+ bp->colour[1][2] = colour[bp->prev_colour][1][2] * compct + colour[bp->next_colour][1][2] * percent;
+ bp->colour[1][3] = colour[bp->prev_colour][1][3] * compct + colour[bp->next_colour][1][3] * percent;
}
/* Start morph process to this model */
-void start_morph(unsigned int model_index, int immediate) {
+static void start_morph(struct glsnake_cfg *bp,
+ unsigned int model_index, int immediate)
+{
/* if immediate, don't bother morphing, go straight to the next model */
if (immediate) {
int i;
for (i = 0; i < NODE_COUNT; i++)
- glc->node[i] = model[model_index].node[i];
+ bp->node[i] = model[model_index].node[i];
}
- glc->prev_model = glc->next_model;
- glc->next_model = model_index;
- glc->prev_colour = glc->next_colour;
+ bp->prev_model = bp->next_model;
+ bp->next_model = model_index;
+ bp->prev_colour = bp->next_colour;
- calc_snake_metrics();
- if (!glc->is_legal)
- glc->next_colour = COLOUR_INVALID;
+ calc_snake_metrics(bp);
+ if (!bp->is_legal)
+ bp->next_colour = COLOUR_INVALID;
else if (altcolour)
- glc->next_colour = COLOUR_AUTHENTIC;
- else if (glc->is_cyclic)
- glc->next_colour = COLOUR_CYCLIC;
+ bp->next_colour = COLOUR_AUTHENTIC;
+ else if (bp->is_cyclic)
+ bp->next_colour = COLOUR_CYCLIC;
else
- glc->next_colour = COLOUR_ACYCLIC;
+ bp->next_colour = COLOUR_ACYCLIC;
if (immediate) {
- glc->colour[0][0] = colour[glc->next_colour][0][0];
- glc->colour[0][1] = colour[glc->next_colour][0][1];
- glc->colour[0][2] = colour[glc->next_colour][0][2];
- glc->colour[0][3] = colour[glc->next_colour][0][3];
- glc->colour[1][0] = colour[glc->next_colour][1][0];
- glc->colour[1][1] = colour[glc->next_colour][1][1];
- glc->colour[1][2] = colour[glc->next_colour][1][2];
- glc->colour[1][3] = colour[glc->next_colour][1][3];
+ bp->colour[0][0] = colour[bp->next_colour][0][0];
+ bp->colour[0][1] = colour[bp->next_colour][0][1];
+ bp->colour[0][2] = colour[bp->next_colour][0][2];
+ bp->colour[0][3] = colour[bp->next_colour][0][3];
+ bp->colour[1][0] = colour[bp->next_colour][1][0];
+ bp->colour[1][1] = colour[bp->next_colour][1][1];
+ bp->colour[1][2] = colour[bp->next_colour][1][2];
+ bp->colour[1][3] = colour[bp->next_colour][1][3];
}
- glc->morphing = 1;
+ bp->morphing = 1;
- morph_colour();
+ morph_colour(bp);
}
+#if 0
/* Returns morph progress */
-float morph(long iter_msec) {
+static float morph(long iter_msec)
+{
/* work out the maximum angle for this iteration */
int still_morphing;
float iter_angle_max, largest_diff, largest_progress;
int i;
- if (glc->new_morph)
- glc->new_morph = 0;
+ if (bp->new_morph)
+ bp->new_morph = 0;
iter_angle_max = 90.0 * (angvel/1000.0) * iter_msec;
still_morphing = 0;
largest_diff = largest_progress = 0.0;
for (i = 0; i < NODE_COUNT; i++) {
- float curAngle = glc->node[i];
- float destAngle = model[glc->next_model].node[i];
+ float curAngle = bp->node[i];
+ float destAngle = model[bp->next_model].node[i];
if (curAngle != destAngle) {
still_morphing = 1;
if (fabs(curAngle-destAngle) <= iter_angle_max)
- glc->node[i] = destAngle;
+ bp->node[i] = destAngle;
else if (fmod(curAngle-destAngle+360,360) > 180)
- glc->node[i] = fmod(curAngle + iter_angle_max, 360);
+ bp->node[i] = fmod(curAngle + iter_angle_max, 360);
else
- glc->node[i] = fmod(curAngle+360 - iter_angle_max, 360);
- largest_diff = MAX(largest_diff, fabs(destAngle-glc->node[i]));
- largest_progress = MAX(largest_diff, fabs(glc->node[i] - model[glc->prev_model].node[i]));
+ bp->node[i] = fmod(curAngle+360 - iter_angle_max, 360);
+ largest_diff = MAX(largest_diff, fabs(destAngle-bp->node[i]));
+ largest_progress = MAX(largest_diff, fabs(bp->node[i] - model[bp->prev_model].node[i]));
}
}
return MIN(largest_diff / largest_progress, 1.0);
}
+#endif
+
#ifdef HAVE_GLUT
-void glsnake_idle();
+static void glsnake_idle();
-void restore_idle(int v __attribute__((__unused__)))
+static restore_idle(int v __attribute__((__unused__)))
{
glutIdleFunc(glsnake_idle);
}
#endif
-void quick_sleep(void)
+static void quick_sleep(void)
{
#ifdef HAVE_GLUT
/* By using glutTimerFunc we can keep responding to
#endif
}
-void glsnake_idle(
+static void glsnake_idle(
#ifndef HAVE_GLUT
struct glsnake_cfg * bp
#endif
- ) {
+ )
+{
/* time since last iteration */
long iter_msec;
/* time since the beginning of last morph */
int i;
/* Do nothing to the model if we are paused */
- if (glc->paused) {
+ if (bp->paused) {
/* Avoid busy waiting when nothing is changing */
quick_sleep();
#ifdef HAVE_GLUT
*/
gettime(¤t_time);
- iter_msec = (long) GETMSECS(current_time) - GETMSECS(glc->last_iteration) +
- ((long) GETSECS(current_time) - GETSECS(glc->last_iteration)) * 1000L;
+ iter_msec = (long) GETMSECS(current_time) - GETMSECS(bp->last_iteration) +
+ ((long) GETSECS(current_time) - GETSECS(bp->last_iteration)) * 1000L;
if (iter_msec) {
/* save the current time */
- memcpy(&glc->last_iteration, ¤t_time, sizeof(snaketime));
+ memcpy(&bp->last_iteration, ¤t_time, sizeof(snaketime));
/* work out if we have to switch models */
- morf_msec = GETMSECS(glc->last_iteration) - GETMSECS(glc->last_morph) +
- ((long) (GETSECS(glc->last_iteration)-GETSECS(glc->last_morph)) * 1000L);
+ morf_msec = GETMSECS(bp->last_iteration) - GETMSECS(bp->last_morph) +
+ ((long) (GETSECS(bp->last_iteration)-GETSECS(bp->last_morph)) * 1000L);
- if ((morf_msec > statictime) && !interactive && !glc->morphing) {
+ if ((morf_msec > statictime) && !interactive && !bp->morphing) {
/*printf("starting morph\n");*/
- memcpy(&glc->last_morph, &(glc->last_iteration), sizeof(glc->last_morph));
- start_morph(RAND(models), 0);
+ memcpy(&bp->last_morph, &(bp->last_iteration), sizeof(bp->last_morph));
+ start_morph(bp, RAND(models), 0);
}
- if (interactive && !glc->morphing) {
+ if (interactive && !bp->morphing) {
quick_sleep();
return;
}
- /* if (!glc->dragging && !glc->interactive) { */
+ /* if (!bp->dragging && !bp->interactive) { */
if (!interactive) {
yspin += 360/((1000/yangvel)/iter_msec);
still_morphing = 0;
for (i = 0; i < NODE_COUNT; i++) {
- float cur_angle = glc->node[i];
- float dest_angle = model[glc->next_model].node[i];
+ float cur_angle = bp->node[i];
+ float dest_angle = model[bp->next_model].node[i];
if (cur_angle != dest_angle) {
still_morphing = 1;
if (fabs(cur_angle - dest_angle) <= iter_angle_max)
- glc->node[i] = dest_angle;
+ bp->node[i] = dest_angle;
else if (fmod(cur_angle - dest_angle + 360, 360) > 180)
- glc->node[i] = fmod(cur_angle + iter_angle_max, 360);
+ bp->node[i] = fmod(cur_angle + iter_angle_max, 360);
else
- glc->node[i] = fmod(cur_angle + 360 - iter_angle_max, 360);
+ bp->node[i] = fmod(cur_angle + 360 - iter_angle_max, 360);
}
}
if (!still_morphing)
- glc->morphing = 0;
+ bp->morphing = 0;
/* colour cycling */
- morph_colour();
+ morph_colour(bp);
#ifdef HAVE_GLUT
glutSwapBuffers();
}
/* wot draws it */
-void glsnake_display(
+ENTRYPOINT void glsnake_display(
#ifndef HAVE_GLUT
ModeInfo * mi
#endif
- ) {
+ )
+{
#ifndef HAVE_GLUT
struct glsnake_cfg * bp = &glc[MI_SCREEN(mi)];
Display * dpy = MI_DISPLAY(mi);
#ifndef HAVE_GLUT
if (!bp->glx_context)
return;
+
+ glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context));
#endif
/* clear the buffer */
for (i = 0; i < NODE_COUNT; i++) {
float rotmat[16];
- ang = glc->node[i];
+ ang = bp->node[i];
/*printf("ang = %f\n", ang);*/
/* now draw each node along the snake -- this is quite ugly :p */
for (i = 0; i < NODE_COUNT; i++) {
/* choose a colour for this node */
- if ((i == glc->selected || i == glc->selected+1) && interactive)
+ if ((i == bp->selected || i == bp->selected+1) && interactive)
/* yellow */
glColor4f(1.0, 1.0, 0.0, 1.0);
else {
- /*glColor4fv(glc->colour[(i+1)%2]);*/
- glMaterialfv(GL_FRONT, GL_AMBIENT, glc->colour[(i+1)%2]);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, glc->colour[(i+1)%2]);
- /*glMaterialfv(GL_FRONT, GL_SPECULAR, glc->colour[(i+1)%2]);*/
+ /*glColor4fv(bp->colour[(i+1)%2]);*/
+ glMaterialfv(GL_FRONT, GL_AMBIENT, bp->colour[(i+1)%2]);
+ glMaterialfv(GL_FRONT, GL_DIFFUSE, bp->colour[(i+1)%2]);
+ /*glMaterialfv(GL_FRONT, GL_SPECULAR, bp->colour[(i+1)%2]);*/
}
/* draw the node */
if (wireframe)
- glCallList(glc->node_wire);
+ glCallList(bp->node_wire);
else
- glCallList(glc->node_solid);
+ glCallList(bp->node_solid);
/* now work out where to draw the next one */
/* Interpolate between models */
- ang = glc->node[i];
+ ang = bp->node[i];
glTranslatef(0.5, 0.5, 0.5); /* move to center */
glRotatef(90.0, 0.0, 0.0, -1.0); /* reorient */
#ifdef HAVE_GLUT
/* anything that needs to be cleaned up goes here */
-void unmain() {
- glutDestroyWindow(glc->window);
- free(glc);
+static void unmain()
+{
+ glutDestroyWindow(bp->window);
+ free(bp);
}
-void ui_init(int *, char **);
+static void ui_init(int *, char **);
-int main(int argc, char ** argv) {
- glc = malloc(sizeof(struct glsnake_cfg));
- memset(glc, 0, sizeof(struct glsnake_cfg));
+int main(int argc, char ** argv)
+{
+ bp = malloc(sizeof(struct glsnake_cfg));
+ memset(bp, 0, sizeof(struct glsnake_cfg));
- glc->width = 640;
- glc->height = 480;
+ bp->width = 640;
+ bp->height = 480;
ui_init(&argc, argv);
- gettime(&glc->last_iteration);
- memcpy(&glc->last_morph, &glc->last_iteration, sizeof(snaketime));
- srand((unsigned int)GETSECS(glc->last_iteration));
+ gettime(&bp->last_iteration);
+ memcpy(&bp->last_morph, &bp->last_iteration, sizeof(snaketime));
+ srand((unsigned int)GETSECS(bp->last_iteration));
- glc->prev_colour = glc->next_colour = COLOUR_ACYCLIC;
- glc->next_model = RAND(models);
- glc->prev_model = 0;
- start_morph(glc->prev_model, 1);
+ bp->prev_colour = bp->next_colour = COLOUR_ACYCLIC;
+ bp->next_model = RAND(models);
+ bp->prev_model = 0;
+ start_morph(bp->prev_model, 1);
glsnake_init();
#ifdef HAVE_GLUT
/* trackball quaternions */
-float cumquat[4] = {0.0,0.0,0.0,0.0}, oldquat[4] = {0.0,0.0,0.0,0.1};
+static float cumquat[4] = {0.0,0.0,0.0,0.0}, oldquat[4] = {0.0,0.0,0.0,0.1};
/* rotation matrix */
-float rotation[16];
+static float rotation[16];
/* mouse drag vectors: start and end */
-float mouse_start[3], mouse_end[3];
+static float mouse_start[3], mouse_end[3];
/* dragging boolean */
-int dragging = 0;
+static int dragging = 0;
/* this function calculates the rotation matrix based on the quaternions
* generated from the mouse drag vectors */
-void calc_rotation() {
+static void calc_rotation()
+{
double Nq, s;
double xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
rotation[15] = 1.0;
}
-inline void ui_mousedrag() {
+static inline void ui_mousedrag()
+{
glMultMatrixf(rotation);
}
-void ui_keyboard(unsigned char c, int x __attribute__((__unused__)), int y __attribute__((__unused__))) {
+static void ui_keyboard(unsigned char c, int x__attribute__((__unused__)), int y __attribute__((__unused__)))
+{
+ int i;
+
switch (c) {
case 27: /* ESC */
case 'q':
break;
case '.':
/* next model */
- glc->next_model++;
- glc->next_model %= models;
- start_morph(glc->next_model, 0);
+ bp->next_model++;
+ bp->next_model %= models;
+ start_morph(bp->next_model, 0);
/* Reset last_morph time */
- gettime(&glc->last_morph);
+ gettime(&bp->last_morph);
break;
case ',':
/* previous model */
- glc->next_model = (glc->next_model + (int)models - 1) % (int)models;
- start_morph(glc->next_model, 0);
+ bp->next_model = (bp->next_model + (int)models - 1) % (int)models;
+ start_morph(bp->next_model, 0);
- /* Reset glc->last_morph time */
- gettime(&glc->last_morph);
+ /* Reset bp->last_morph time */
+ gettime(&bp->last_morph);
break;
case '+':
angvel += DEF_ANGVEL;
case 'i':
if (interactive) {
/* Reset last_iteration and last_morph time */
- gettime(&glc->last_iteration);
- gettime(&glc->last_morph);
+ gettime(&bp->last_iteration);
+ gettime(&bp->last_morph);
}
interactive = 1 - interactive;
glutPostRedisplay();
}
break;
case 'p':
- if (glc->paused) {
+ if (bp->paused) {
/* unpausing, reset last_iteration and last_morph time */
- gettime(&glc->last_iteration);
- gettime(&glc->last_morph);
+ gettime(&bp->last_iteration);
+ gettime(&bp->last_morph);
}
- glc->paused = 1 - glc->paused;
+ bp->paused = 1 - bp->paused;
break;
case 'd':
/* dump the current model so we can add it! */
- printf("# %s\nnoname:\t", model[glc->next_model].name);
+ printf("# %s\nnoname:\t", model[bp->next_model].name);
{
int i;
for (i = 0; i < NODE_COUNT; i++) {
- if (glc->node[i] == ZERO)
+ if (bp->node[i] == ZERO)
printf("Z");
- else if (glc->node[i] == LEFT)
+ else if (bp->node[i] == LEFT)
printf("L");
- else if (glc->node[i] == PIN)
+ else if (bp->node[i] == PIN)
printf("P");
- else if (glc->node[i] == RIGHT)
+ else if (bp->node[i] == RIGHT)
printf("R");
/*
else
printf("\n");
break;
case 'f':
- glc->fullscreen = 1 - glc->fullscreen;
- if (glc->fullscreen) {
- glc->old_width = glc->width;
- glc->old_height = glc->height;
+ bp->fullscreen = 1 - bp->fullscreen;
+ if (bp->fullscreen) {
+ bp->old_width = bp->width;
+ bp->old_height = bp->height;
glutFullScreen();
} else {
- glutReshapeWindow(glc->old_width, glc->old_height);
+ glutReshapeWindow(bp->old_width, bp->old_height);
glutPositionWindow(50,50);
}
break;
case 't':
titles = 1 - titles;
- if (interactive || glc->paused)
+ if (interactive || bp->paused)
glutPostRedisplay();
break;
case 'c':
break;
case 'z':
zoom += 1.0;
- glsnake_reshape(glc->width, glc->height);
+ glsnake_reshape(bp->width, bp->height);
break;
case 'Z':
zoom -= 1.0;
- glsnake_reshape(glc->width, glc->height);
+ glsnake_reshape(bp->width, bp->height);
break;
default:
break;
}
}
-void ui_special(int key, int x __attribute__((__unused__)), int y __attribute__((__unused__))) {
- float *destAngle = &(model[glc->next_model].node[glc->selected]);
+static void ui_special(int key, int x__attribute__((__unused__)), int y __attribute__((__unused__)))
+{
+ float *destAngle = &(model[bp->next_model].node[bp->selected]);
int unknown_key = 0;
if (interactive) {
switch (key) {
case GLUT_KEY_UP:
- glc->selected = (glc->selected + (NODE_COUNT - 2)) % (NODE_COUNT - 1);
+ bp->selected = (bp->selected + (NODE_COUNT - 2)) % (NODE_COUNT - 1);
break;
case GLUT_KEY_DOWN:
- glc->selected = (glc->selected + 1) % (NODE_COUNT - 1);
+ bp->selected = (bp->selected + 1) % (NODE_COUNT - 1);
break;
case GLUT_KEY_LEFT:
*destAngle = fmod(*destAngle+(LEFT), 360);
- glc->morphing = glc->new_morph = 1;
+ bp->morphing = bp->new_morph = 1;
break;
case GLUT_KEY_RIGHT:
*destAngle = fmod(*destAngle+(RIGHT), 360);
- glc->morphing = glc->new_morph = 1;
+ bp->morphing = bp->new_morph = 1;
break;
case GLUT_KEY_HOME:
start_morph(STRAIGHT_MODEL, 0);
glutPostRedisplay();
}
-void ui_mouse(int button, int state, int x, int y) {
+static void ui_mouse(int button, int state, int x, int y)
+{
if (button==0) {
switch (state) {
case GLUT_DOWN:
dragging = 1;
mouse_start[0] = M_SQRT1_2 *
- (x - (glc->width / 2.0)) / (glc->width / 2.0);
+ (x - (bp->width / 2.0)) / (bp->width / 2.0);
mouse_start[1] = M_SQRT1_2 *
- ((glc->height / 2.0) - y) / (glc->height / 2.0);
+ ((bp->height / 2.0) - y) / (bp->height / 2.0);
mouse_start[2] = sqrt((double)(1-(mouse_start[0]*mouse_start[0]+mouse_start[1]*mouse_start[1])));
break;
case GLUT_UP:
glutPostRedisplay();
}
-void ui_motion(int x, int y) {
+static void ui_motion(int x, int y)
+{
double norm;
float q[4];
if (dragging) {
/* construct the motion end vector from the x,y position on the
* window */
- mouse_end[0] = M_SQRT1_2 * (x - (glc->width/ 2.0)) / (glc->width / 2.0);
- mouse_end[1] = M_SQRT1_2 * ((glc->height / 2.0) - y) / (glc->height / 2.0);
+ mouse_end[0] = M_SQRT1_2 * (x - (bp->width/ 2.0)) / (bp->width / 2.0);
+ mouse_end[1] = M_SQRT1_2 * ((bp->height / 2.0) - y) / (bp->height / 2.0);
/* calculate the normal of the vector... */
norm = mouse_end[0] * mouse_end[0] + mouse_end[1] * mouse_end[1];
/* check if norm is outside the sphere and wraparound if necessary */
glutPostRedisplay();
}
-void ui_init(int * argc, char ** argv) {
+static void ui_init(int * argc, char ** argv)
+{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
- glutInitWindowSize(glc->width, glc->height);
- glc->window = glutCreateWindow("glsnake");
+ glutInitWindowSize(bp->width, bp->height);
+ bp->window = glutCreateWindow("glsnake");
glutDisplayFunc(glsnake_display);
glutReshapeFunc(glsnake_reshape);
transparent = DEF_TRANSPARENT;
}
#endif /* HAVE_GLUT */
+
+XSCREENSAVER_MODULE ("GLSnake", glsnake)