diff options
| author | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
|---|---|---|
| committer | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
| commit | badef32037f52f79abc1f1440b786cd71afdf270 (patch) | |
| tree | 412b792d4cab4a7a110db82fcf74fe8a1ac55ec1 /hacks/glx/lockward.c | |
| parent | Delete pre-6.00 files (diff) | |
| download | xscreensaver-master.tar.gz xscreensaver-master.tar.xz xscreensaver-master.zip | |
Diffstat (limited to 'hacks/glx/lockward.c')
| -rw-r--r-- | hacks/glx/lockward.c | 963 |
1 files changed, 0 insertions, 963 deletions
diff --git a/hacks/glx/lockward.c b/hacks/glx/lockward.c deleted file mode 100644 index 6c80afa..0000000 --- a/hacks/glx/lockward.c +++ /dev/null @@ -1,963 +0,0 @@ -/* - * lockward.c: First attempt at an Xscreensaver. - * - * Leo L. Schwab 2007.08.17 - **** - * Copyright (c) 2007 Leo L. Schwab - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to permit - * persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN - * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include <ctype.h> -#include <strings.h> - -#include "xlockmore.h" -#include "colors.h" - - -/*************************************************************************** - * #defines - */ -#ifdef USE_GL /* whole file */ - -#define DEFAULTS "*delay: 20000 \n"\ - "*showFPS: False \n" - -#define release_lockward 0 - - -#define NUMOF(x) (sizeof ((x)) / sizeof ((*x))) - -#define NBLADES 12 -#define NSPINNERS 4 -#define NRADII 8 -#define COLORIDX_SHF 4 -#define SUBDIV 6 - - -/*************************************************************************** - * Structure definitions. - */ -struct lockward_context; /* Forward declaration. */ - -#define int8_t char -#define int16_t short -#define int32_t int -#define uint8_t unsigned char -#define uint16_t unsigned short -#define uint32_t unsigned int - -typedef struct bladestate { - uint8_t outer, inner; /* Radii */ -} bladestate; - -typedef struct spinnerstate { - GLfloat rot; /* Terminal rotation after count expires */ - GLfloat rotinc; /* Per-frame increment to rot. */ - XColor *colors; - bladestate *bladeidx; - int ncolors; /* n.4 fixed-point */ - int ccolor; /* n.4 fixed-point */ - int colorinc; /* n.4 fixed-point */ - int rotcount; - uint8_t nblades; -} spinnerstate; - -typedef struct blinkstate { - int (*drawfunc) (struct lockward_context *ctx, - struct blinkstate *bs); - uint32_t *noise; /* For draw_blink_segment_scatter() */ - GLfloat color[4]; - uint32_t val; - int16_t dwell; /* <0: sharp >0: decay */ - int16_t dwellcnt; - uint8_t type; - int8_t counter; - int8_t direction; - int8_t radius; -} blinkstate; - -enum blinktype { - BTYPE_RADIAL_SINGLE = 0, - BTYPE_RADIAL_RANDOM, - BTYPE_RADIAL_SEQ, - BTYPE_RADIAL_DOUBLESEQ, - BTYPE_SEGMENT_SINGLE, - BTYPE_SEGMENT_RANDOM, - BTYPE_CONCENTRIC_SINGLE, - BTYPE_CONCENTRIC_RANDOM, - BTYPE_CONCENTRIC_SEQ, - BTYPE_SEGMENT_SCATTER, - MAX_BTYPE -}; - -typedef struct { GLfloat x,y,z; } XYZ; - -typedef struct lockward_context { - GLXContext *glx_context; - - spinnerstate spinners[NSPINNERS]; - blinkstate blink; - - /* This used to put vertexes into lists without putting begin/end - into the same list! I didn't even know that worked. Well, it - doesn't work with jwzgles, so I changed it to not do that. */ - /* GLuint blades_outer, blades_inner; */ - XYZ points_outer[NRADII][SUBDIV+1]; - XYZ points_inner[NRADII][SUBDIV+1]; - - GLuint rings; - Bool blendmode; - int nextblink; - int fps; - -} lockward_context; - - -/*************************************************************************** - * Prototypes. - */ -ENTRYPOINT void free_lockward (ModeInfo *mi); - - -/*************************************************************************** - * Global variables. - */ -static lockward_context *g_ctx = NULL; -static Bool g_blink_p = True; -static int g_blades = NBLADES; -static int g_rotateidle_min, - g_rotateidle_max; -static int g_blinkidle_min, - g_blinkidle_max; -static int g_blinkdwell_min, - g_blinkdwell_max; - -#define DEF_BLINK "True" -#define DEF_ROTATEIDLEMIN "1000" -#define DEF_ROTATEIDLEMAX "6000" -#define DEF_BLINKIDLEMIN "1000" -#define DEF_BLINKIDLEMAX "9000" -#define DEF_BLINKDWELLMIN "100" -#define DEF_BLINKDWELLMAX "600" - - -static XrmOptionDescRec opts[] = { - { "-blink", ".blink", XrmoptionNoArg, "on" }, - { "+blink", ".blink", XrmoptionNoArg, "off" }, - { "-rotateidle-min", ".rotateidlemin", XrmoptionSepArg, 0 }, - { "-rotateidle-max", ".rotateidlemax", XrmoptionSepArg, 0 }, - { "-blinkidle-min", ".blinkidlemin", XrmoptionSepArg, 0 }, - { "-blinkidle-max", ".blinkidlemax", XrmoptionSepArg, 0 }, - { "-blinkdwell-min", ".blinkdwellmin", XrmoptionSepArg, 0 }, - { "-blinkdwell-max", ".blinkdwellmax", XrmoptionSepArg, 0 }, -}; - -static argtype vars[] = { - { &g_blink_p, "blink", "Blink", DEF_BLINK, t_Bool }, - { &g_rotateidle_min, "rotateidlemin", "Rotateidlemin", DEF_ROTATEIDLEMIN, t_Int }, - { &g_rotateidle_max, "rotateidlemax", "Rotateidlemax", DEF_ROTATEIDLEMAX, t_Int }, - { &g_blinkidle_min, "blinkidlemin", "Blinkidlemin", DEF_BLINKIDLEMIN, t_Int }, - { &g_blinkidle_max, "blinkidlemax", "Blinkidlemax", DEF_BLINKIDLEMAX, t_Int }, - { &g_blinkdwell_min, "blinkdwellmin", "Blinkdwellmin", DEF_BLINKDWELLMIN, t_Int }, - { &g_blinkdwell_max, "blinkdwellmax", "Blinkdwellmax", DEF_BLINKDWELLMAX, t_Int }, -}; - -static OptionStruct desc[] = { - { "-/+blink", "Turn on/off blinking effects." }, - { "-rotateidle-min", "Minimum idle time for rotators, in milliseconds." }, - { "-rotateidle-max", "Maximum idle time for rotators, in milliseconds." }, - { "-blinkidle-min", "Minimum idle time between blink effects, in milliseconds." }, - { "-blinkidle-max", "Maximum idle time between blink effects, in milliseconds." }, - { "-blinkdwell-min", "Minimum dwell time for blink effects, in milliseconds." }, - { "-blinkdwell-max", "Maximum dwell time for blink effects, in milliseconds." }, -}; - -ENTRYPOINT ModeSpecOpt lockward_opts = { - NUMOF(opts), opts, NUMOF(vars), vars, desc -}; - - -/*************************************************************************** - * Window management. - */ -ENTRYPOINT void -reshape_lockward (ModeInfo *mi, int width, int height) -{ - lockward_context *ctx = &g_ctx[MI_SCREEN (mi)]; - GLfloat 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; - } - - glXMakeCurrent (MI_DISPLAY (mi), MI_WINDOW (mi), *ctx->glx_context); - - glViewport (0, y, (GLint) width, (GLint) height); - - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); - if (height > width) - glOrtho (-8.0, 8.0, -8.0 * h, 8.0 * h, -1, 1); - else - glOrtho (-8.0 / h, 8.0 / h, -8.0, 8.0, -1, 1); - - glMatrixMode (GL_MODELVIEW); -} - -ENTRYPOINT Bool -lockward_handle_event (ModeInfo *mi, XEvent *event) -{ - lockward_context *ctx = &g_ctx[MI_SCREEN (mi)]; - - if (event->xany.type == KeyPress) { - KeySym keysym; - char c = 0; - - XLookupString (&event->xkey, &c, 1, &keysym, 0); - if (c == ' ' || c == '\t') { - ctx->blendmode ^= 1; - return True; - } - } - - return False; -} - - -/*************************************************************************** - * "Blade" routines. - */ -static void -random_blade_rot (lockward_context *ctx, struct spinnerstate *ss) -{ - /* - * The circle is divided up in to g_blades divisions. The idea here - * is to rotate to an exact division point. - * - * The target rotation is computed via random numbers. - * - * The time it takes to get there is a maximum of six seconds per - * division, and a minimum of one second (no matter how far away it - * is), and is selected by random numbers. - * - * The time value is converted into frames, and a per-frame rotation - * is computed. - * - * During rendering, we approach the target rotation by subtracting - * from it the per-frame rotation times the number of outstanding - * ticks. Doing it this way means we'll hit the target rotation - * exactly, without low-order errors creeping in to the values (at - * least not nearly as quickly). - */ - GLfloat d; - int dist; - - dist = random() % g_blades + 1; - - ss->rotcount = random() % (6 * dist * ctx->fps - ctx->fps) - + ctx->fps; - - if (random() & 4) - dist = -dist; - d = dist * 360.0 / (GLfloat) g_blades; - ss->rot += d; - ss->rotinc = d / (GLfloat) ss->rotcount; -} - - -/* - * A "blade" is pie-wedge shaped flat thing that is rotated around where the - * apex is/would be. Initially envisioned as 1/12th of a circle, but that - * could be configurable. The inner and outer edges are rounded off using - * six subdivisions so that, when multiple blades are assembled, it looks - * more like a circle and less like a polygon. - * - * The blade is assembled as a tri-fan. It is oriented centered at 3 - * o'clock. The blade is composed of two display lists -- arcs, essentially - * -- the outer and the inner one. The outer one *must* be called before - * the inner one, or the blade clockwise-ness will be wrong, and become - * invisible. Arcs of various radii are compiled. - */ - -static void -gen_blade_arcs (lockward_context *ctx) -{ - GLfloat here, there, step; - int i, n; - - here = 0; - there = M_PI * 2.0 / g_blades; - step = there / SUBDIV; - here -= SUBDIV * step / 2.0; - - /* - * Build outer blade arcs. - * Start at left side of outer radius. Strike all its vertices. - */ - for (n = 0; n < NRADII; ++n) { - /* glNewList (ctx->blades_outer + n, GL_COMPILE); */ - XYZ *a = ctx->points_outer[n]; - int j = 0; - for (i = SUBDIV; i >= 0; --i) { - /* glVertex3f (cos (here + step * i) * (n + 1.0), - sin (here + step * i) * (n + 1.0), 0); */ - a[j].x = cos (here + step * i) * (n + 1.0); - a[j].y = sin (here + step * i) * (n + 1.0); - a[j].z = 0; - j++; - } - if (j != SUBDIV+1) abort(); - /* glEndList (); */ - } - - /* - * Build inner blade arcs. - * Move to inner radius, strike all vertices in opposite order. - */ - for (n = 0; n < NRADII; ++n) { - /* glNewList (ctx->blades_inner + n, GL_COMPILE); */ - XYZ *a = ctx->points_inner[n]; - int j = 0; - for (i = 0; i <= SUBDIV; ++i) { - /* glVertex3f (cos (here + step * i) * (n + 1.0), - sin (here + step * i) * (n + 1.0), 0); */ - a[j].x = cos (here + step * i) * (n + 1.0); - a[j].y = sin (here + step * i) * (n + 1.0); - a[j].z = 0; - j++; - } - if (j != SUBDIV+1) abort(); - /* glEndList (); */ - } -} - -static void -gen_rings (lockward_context *ctx) -{ - GLfloat step; - int i, n; - - step = M_PI * 2.0 / (g_blades * SUBDIV); - - for (n = 0; n < NRADII - 1; ++n) { - glNewList (ctx->rings + n, GL_COMPILE); - glBegin (GL_TRIANGLE_STRIP); - for (i = g_blades * SUBDIV; i >= 0; --i) { - glVertex3f (cos (step * i) * (n + 1.0), - sin (step * i) * (n + 1.0), 0); - glVertex3f (cos (step * i) * (n + 2.0), - sin (step * i) * (n + 2.0), 0); - } - glEnd(); - glEndList (); - } -} - - -/*************************************************************************** - * "Blink" routines. - */ -static int -calc_interval_frames (lockward_context *ctx, int min, int max) -{ - /* - * Compute random interval between min and max milliseconds. - * Returned value is in frames. - */ - register int i; - - i = min; - if (max > min) - i += random() % (max - min); - - return i * ctx->fps / 1000; -} - -static void -set_alpha_by_dwell (struct blinkstate *bs) -{ - if (bs->dwell > 0) - bs->color[3] = (GLfloat) bs->dwellcnt / (GLfloat) bs->dwell; - else - bs->color[3] = bs->dwellcnt > (-bs->dwell >> 2) ? 1.0 : 0.0; -} - - -static void -draw_blink_blade (lockward_context *ctx, int inner, int outer, - Bool begin_p) -{ - int i; - if (begin_p) glBegin (GL_TRIANGLE_FAN); - /* glCallList (ctx->blades_outer + outer); */ - for (i = 0; i < countof(*ctx->points_outer); i++) - glVertex3f(ctx->points_outer[outer][i].x, - ctx->points_outer[outer][i].y, - ctx->points_outer[outer][i].z); - - /* glCallList (ctx->blades_inner + inner); */ - for (i = 0; i < countof(*ctx->points_inner); i++) - glVertex3f(ctx->points_inner[inner][i].x, - ctx->points_inner[inner][i].y, - ctx->points_inner[inner][i].z); - if (begin_p) glEnd(); -} - -static int -draw_blink_radial_random (lockward_context *ctx, struct blinkstate *bs) -{ - int i; - - /* - * There is no sense of direction in a random sweep, so re-use the - * 'direction' field to hold the current blade we're messing with. - */ - if (bs->dwellcnt < 0) { - if (bs->counter <= 0) { - bs->drawfunc = NULL; - return 0; - } - - /* - * Find available blade. Potentially very slow, depending on - * how unlucky we are. - */ - do { - i = random() % g_blades; - } while (bs->val & (1 << i)); - bs->val |= (1 << i); /* Mark as used. */ - bs->direction = i; - if ((bs->dwellcnt = bs->dwell) < 0) - bs->dwellcnt = -bs->dwellcnt; - - if ( bs->type == BTYPE_SEGMENT_SINGLE - || bs->type == BTYPE_SEGMENT_RANDOM) - bs->radius = random() % (NRADII - 1); - - --bs->counter; - } - - set_alpha_by_dwell (bs); - glBlendFunc (GL_DST_COLOR, GL_SRC_ALPHA); - glColor4fv (bs->color); - glRotatef (bs->direction * 360.0 / (GLfloat) g_blades, 0, 0, 1); - if (bs->radius >= 0) - draw_blink_blade (ctx, bs->radius, bs->radius + 1, True); - else - draw_blink_blade (ctx, 0, NRADII - 1, True); - - --bs->dwellcnt; - - return SUBDIV + SUBDIV; -} - -static int -draw_blink_radial_sequential (lockward_context *ctx, struct blinkstate *bs) -{ - if (bs->dwellcnt < 0) { - if (bs->counter <= 0) { - bs->drawfunc = NULL; - return 0; - } - if ((bs->dwellcnt = bs->dwell) < 0) - bs->dwellcnt = -bs->dwellcnt; - --bs->counter; - } - - set_alpha_by_dwell (bs); - glBlendFunc (GL_DST_COLOR, GL_SRC_ALPHA); - glColor4fv (bs->color); - glRotatef ((bs->counter * bs->direction + (int) bs->val) - * 360.0 / (GLfloat) g_blades, - 0, 0, 1); - draw_blink_blade (ctx, 0, NRADII - 1, True); - - --bs->dwellcnt; - - return SUBDIV + SUBDIV; -} - -static int -draw_blink_radial_doubleseq (lockward_context *ctx, struct blinkstate *bs) -{ - int polys; - - if (bs->dwellcnt < 0) { - if (bs->counter <= 0) { - bs->drawfunc = NULL; - return 0; - } - if ((bs->dwellcnt = bs->dwell) < 0) - bs->dwellcnt = -bs->dwellcnt; - --bs->counter; - } - - set_alpha_by_dwell (bs); - glBlendFunc (GL_DST_COLOR, GL_SRC_ALPHA); - glColor4fv (bs->color); - - glPushMatrix (); - glRotatef (((int) bs->val + bs->counter) * 360.0 / (GLfloat) g_blades, - 0, 0, 1); - draw_blink_blade (ctx, 0, NRADII - 1, True); - glPopMatrix (); - polys = SUBDIV + SUBDIV; - - if (bs->counter && bs->counter < g_blades / 2) { - glRotatef (((int) bs->val - bs->counter) - * 360.0 / (GLfloat) g_blades, - 0, 0, 1); - draw_blink_blade (ctx, 0, NRADII - 1, True); - polys += SUBDIV + SUBDIV; - } - - --bs->dwellcnt; - - return polys; -} - -static int -draw_blink_concentric_random (lockward_context *ctx, struct blinkstate *bs) -{ - int i; - - if (bs->dwellcnt < 0) { - if (bs->counter <= 0) { - bs->drawfunc = NULL; - return 0; - } - - do { - i = random() % (NRADII - 1); - } while (bs->val & (1 << i)); - bs->val |= (1 << i); - bs->direction = i; - if ((bs->dwellcnt = bs->dwell) < 0) - bs->dwellcnt = -bs->dwellcnt; - - --bs->counter; - } - - set_alpha_by_dwell (bs); - glBlendFunc (GL_DST_COLOR, GL_SRC_ALPHA); - glColor4fv (bs->color); - glCallList (ctx->rings + bs->direction); - - --bs->dwellcnt; - - return g_blades * SUBDIV * 2; -} - -static int -draw_blink_concentric_sequential (lockward_context *ctx, struct blinkstate *bs) -{ - if (bs->dwellcnt < 0) { - if (bs->counter <= 0) { - bs->drawfunc = NULL; - return 0; - } - if ((bs->dwellcnt = bs->dwell) < 0) - bs->dwellcnt = -bs->dwellcnt; - --bs->counter; - } - - set_alpha_by_dwell (bs); - glBlendFunc (GL_DST_COLOR, GL_SRC_ALPHA); - glColor4fv (bs->color); - if (bs->direction > 0) - glCallList (ctx->rings + (NRADII - 2) - bs->counter); - else - glCallList (ctx->rings + bs->counter); - - --bs->dwellcnt; - - return g_blades * SUBDIV * 2; -} - -static int -draw_blink_segment_scatter (lockward_context *ctx, struct blinkstate *bs) -{ - int i, polys = 0; - - if (bs->dwellcnt < 0) { - if (bs->counter <= 0) { - bs->drawfunc = NULL; - return 0; - } - - /* - * Init random noise array. On average, 1/4 of the bits will - * be set, which should look nice. (1/2 looks too busy.) - */ - for (i = g_blades; --i >= 0; ) - bs->noise[i] = random() & random() - & ((1 << (NRADII - 1)) - 1); - - if ((bs->dwellcnt = bs->dwell) < 0) - bs->dwellcnt = -bs->dwellcnt; - --bs->counter; - } - - set_alpha_by_dwell (bs); - glBlendFunc (GL_DST_COLOR, GL_SRC_ALPHA); - glColor4fv (bs->color); - - for (i = g_blades; --i >= 0; ) { - register uint32_t bits; - int inner, outer; - - /* - * Find consecutive runs of 1 bits. Keep going until we run - * out of them. - */ - for (bits = bs->noise[i]; bits; ) { - inner = ffs (bits) - 1; - bits = ~bits & ~((1 << inner) - 1); - outer = ffs (bits) - 1; - bits = ~bits & ~((1 << outer) - 1); - - glPushMatrix (); - glRotatef (i * 360.0 / (GLfloat) g_blades, 0, 0, 1); - draw_blink_blade (ctx, inner, outer, True); - glPopMatrix (); - - polys += SUBDIV + SUBDIV; - } - } - - --bs->dwellcnt; - - return polys; -} - -static void -random_blink (lockward_context *ctx, struct blinkstate *bs) -{ - bs->color[0] = - bs->color[1] = - bs->color[2] = - bs->color[3] = 1.0; - bs->dwellcnt = -1; - bs->radius = -1; - bs->dwell = calc_interval_frames - (ctx, g_blinkdwell_min, g_blinkdwell_max); - if (random() & 2) - bs->dwell = -bs->dwell; - - bs->type = random() % MAX_BTYPE; - - switch (bs->type) { - case BTYPE_RADIAL_SINGLE: - case BTYPE_SEGMENT_SINGLE: - bs->drawfunc = draw_blink_radial_random; - bs->val = 0; - bs->counter = 1; - break; - case BTYPE_RADIAL_RANDOM: - case BTYPE_SEGMENT_RANDOM: - bs->drawfunc = draw_blink_radial_random; - bs->val = 0; - bs->counter = g_blades; - break; - case BTYPE_RADIAL_SEQ: - bs->drawfunc = draw_blink_radial_sequential; - bs->val = random() % g_blades; /* Initial offset */ - bs->direction = random() & 8 ? 1 : -1; - bs->counter = g_blades; - break; - case BTYPE_RADIAL_DOUBLESEQ: - bs->drawfunc = draw_blink_radial_doubleseq; - bs->val = random() % g_blades; /* Initial offset */ - bs->counter = g_blades / 2 + 1; - break; - case BTYPE_CONCENTRIC_SINGLE: - bs->drawfunc = draw_blink_concentric_random; - bs->val = 0; - bs->counter = 1; - break; - case BTYPE_CONCENTRIC_RANDOM: - bs->drawfunc = draw_blink_concentric_random; - bs->val = 0; - bs->counter = NRADII - 1; - break; - case BTYPE_CONCENTRIC_SEQ: - bs->drawfunc = draw_blink_concentric_sequential; - bs->direction = random() & 8 ? 1 : -1; - bs->counter = NRADII - 1; - break; - case BTYPE_SEGMENT_SCATTER: - bs->drawfunc = draw_blink_segment_scatter; - bs->counter = random() % (g_blades / 2) + (g_blades / 2) + 1; - break; - } -} - - -/*************************************************************************** - * Main rendering routine. - */ -ENTRYPOINT void -draw_lockward (ModeInfo *mi) -{ - lockward_context *ctx = &g_ctx[MI_SCREEN (mi)]; - spinnerstate *ss; - Display *dpy = MI_DISPLAY(mi); - Window window = MI_WINDOW(mi); - int i, n; - - GLfloat scolor[4] = {0.0, 0.0, 0.0, 0.5}; - - if (!ctx->glx_context) - return; - - glXMakeCurrent (MI_DISPLAY (mi), MI_WINDOW (mi), *ctx->glx_context); - - - glClear (GL_COLOR_BUFFER_BIT); - - if (ctx->blendmode) - glBlendFunc (GL_ONE, GL_ONE); - else - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glPushMatrix (); - glLoadIdentity (); - - mi->polygon_count = 0; - - for (n = NSPINNERS; --n >= 0; ) { - ss = &ctx->spinners[n]; - - /* Set color. */ - i = ss->ccolor >> COLORIDX_SHF; - scolor[0] = ss->colors[i].red / 65535.0; - scolor[1] = ss->colors[i].green / 65535.0; - scolor[2] = ss->colors[i].blue / 65535.0; - glColor4fv (scolor); - - glPushMatrix (); - glRotatef (ss->rot - ss->rotcount * ss->rotinc, 0, 0, 1); - for (i = ss->nblades; --i >= 0; ) { - glPushMatrix (); - glRotatef (360.0 * i / ss->nblades, 0, 0, 1); - - glBegin (GL_TRIANGLE_FAN); - /* glCallList (ctx->blades_outer + ss->bladeidx[i].outer); */ - /* glCallList (ctx->blades_inner + ss->bladeidx[i].inner); */ - draw_blink_blade (ctx, - ss->bladeidx[i].inner, - ss->bladeidx[i].outer, - False); - glEnd (); - - glPopMatrix (); - mi->polygon_count += SUBDIV + SUBDIV; - } - glPopMatrix (); - - /* Advance rotation. */ - if (ss->rotcount) { - if (ss->rotcount > 0) - --ss->rotcount; - } else { - if (ss->rotinc == 0.0) - random_blade_rot (ctx, ss); - else { - /* Compute # of ticks to sit idle. */ - ss->rotinc = 0.0; - ss->rotcount = - calc_interval_frames (ctx, - g_rotateidle_min, - g_rotateidle_max); - } - } - - /* Advance colors. */ - if ((ss->ccolor += ss->colorinc) >= ss->ncolors) - ss->ccolor -= ss->ncolors; - else if (ss->ccolor < 0) - ss->ccolor += ss->ncolors; - } - - if (g_blink_p) { - if (ctx->blink.drawfunc) { - mi->polygon_count += - ctx->blink.drawfunc (ctx, &ctx->blink); - } else { - if (ctx->nextblink > 0) - --ctx->nextblink; - else { - /* Compute # of frames for blink idle time. */ - ctx->nextblink = - calc_interval_frames (ctx, - g_blinkidle_min, - g_blinkidle_max); - random_blink (ctx, &ctx->blink); - } - } - } - glPopMatrix (); - - if (MI_IS_FPS (mi)) do_fps (mi); - glFinish(); - - glXSwapBuffers (dpy, window); -} - - -/*************************************************************************** - * Initialization/teardown. - */ -ENTRYPOINT void -init_lockward (ModeInfo *mi) -{ - lockward_context *ctx; - int i, n; - - MI_INIT (mi, g_ctx); - ctx = &g_ctx[MI_SCREEN (mi)]; - - ctx->glx_context = init_GL (mi); - - reshape_lockward (mi, MI_WIDTH (mi), MI_HEIGHT (mi)); - - glEnable (GL_CULL_FACE); - glEnable (GL_BLEND); - glDisable (GL_DEPTH_TEST); - - glShadeModel (GL_FLAT); - glFrontFace (GL_CW); - - /* ctx->blades_outer = glGenLists (NRADII); */ - /* ctx->blades_inner = glGenLists (NRADII); */ - ctx->rings = glGenLists (NRADII - 1); - ctx->blendmode = 0; -/* WTF? ctx->fps = 1000000 / MI_DELAY (mi); */ - ctx->fps = 60; - ctx->nextblink = calc_interval_frames - (ctx, g_blinkidle_min, g_blinkidle_max); - ctx->blink.drawfunc = NULL; - ctx->blink.noise = malloc (sizeof (uint32_t) * g_blades); - if (!ctx->blink.noise) { - fprintf (stderr, "Can't allocate noise array.\n"); - exit (1); - } - - gen_blade_arcs (ctx); - gen_rings (ctx); - - for (i = NSPINNERS; --i >= 0; ) { - spinnerstate *ss = &ctx->spinners[i]; - - ss->rot = 0.0; - ss->rotcount = -1; - - /* Establish rotation */ - random_blade_rot (ctx, ss); - - /* - * Establish color cycling path and rate. Rate avoids zero. - */ - ss->ncolors = 128; - ss->colorinc = (random() & ((2 << COLORIDX_SHF) - 1)) - - (1 << COLORIDX_SHF); - if (ss->colorinc >= 0) - ++ss->colorinc; - - ss->colors = (XColor *) calloc (ss->ncolors, sizeof (XColor)); - if (!ss->colors) { - fprintf (stderr, - "Can't allocate XColors for spinner %d.\n", - i); - exit (1); - } - make_smooth_colormap (0, 0, 0, - ss->colors, &ss->ncolors, - False, 0, False); - ss->ncolors <<= COLORIDX_SHF; - - /* - * Create blades. - */ - ss->nblades = g_blades; - ss->bladeidx = malloc (sizeof (bladestate) * g_blades); - if (!ss->bladeidx) { - fprintf (stderr, "Can't allocate blades.\n"); - exit (1); - } - for (n = g_blades; --n >= 0; ) { - /* - * Establish blade radii. Can't be equal. Ensure - * outer > inner. - */ - do { - ss->bladeidx[n].outer = random() & 7; - ss->bladeidx[n].inner = random() & 7; - } while (ss->bladeidx[n].outer == - ss->bladeidx[n].inner); - - if (ss->bladeidx[n].outer < ss->bladeidx[n].inner) { - uint8_t tmp; - - tmp = ss->bladeidx[n].outer; - ss->bladeidx[n].outer = ss->bladeidx[n].inner; - ss->bladeidx[n].inner = tmp; - } - } - } -} - -ENTRYPOINT void -free_lockward (ModeInfo *mi) -{ - lockward_context *ctx = &g_ctx[MI_SCREEN (mi)]; - int i; - - if (!ctx->glx_context) return; - glXMakeCurrent (MI_DISPLAY (mi), MI_WINDOW (mi), *ctx->glx_context); - - if (ctx->blink.noise) - free (ctx->blink.noise); - if (glIsList (ctx->rings)) - glDeleteLists (ctx->rings, NRADII - 1); - /* if (glIsList (ctx->blades_outer)) - glDeleteLists (ctx->blades_outer, NRADII); - if (glIsList (ctx->blades_inner)) - glDeleteLists (ctx->blades_inner, NRADII); */ - - for (i = NSPINNERS; --i >= 0; ) { - spinnerstate *ss = &ctx->spinners[i]; - - if (ss->colors) - free (ss->colors); - if (ss->bladeidx) - free (ss->bladeidx); - } -} - - -XSCREENSAVER_MODULE ("Lockward", lockward) - -#endif /* USE_GL */ - -/* vim:se ts=8 sts=8 sw=8: */ |
