X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fmirrorblob.c;h=c6a5c84d2f9d96870de85d644520ef9c71341e0b;hp=b5a9275602478c7d2a553d1f2d84856ac5dfb82d;hb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;hpb=ccb7f4903325f92555a9722bba74b58346654ba0 diff --git a/hacks/glx/mirrorblob.c b/hacks/glx/mirrorblob.c index b5a92756..c6a5c84d 100644 --- a/hacks/glx/mirrorblob.c +++ b/hacks/glx/mirrorblob.c @@ -19,29 +19,35 @@ * 10-Feb-2004: jon.dowdall@bigpond.com Added motion blur * * The mirrorblob screensaver draws a pulsing blob on the screen. Options - * include adding a background (via screen_to_texture), texturing the blob, + * include adding a background (via load_texture_async), texturing the blob, * making the blob semi-transparent and varying the resolution of the blob * tessellation. * * The blob was inspired by a lavalamp is in no way a simulation. The code is * just an attempt to generate some eye-candy. * - * Much of xscreensaver code framework is taken from the pulsar module by David + * Much of xmirrorblob code framework is taken from the pulsar module by David * Konerding and the glslideshow by Mike Oliphant and Jamie Zawinski. * */ #include -#include -#include -#include #ifdef STANDALONE -# define PROGCLASS "Screensaver" -# define HACK_INIT init_screensaver -# define HACK_DRAW draw_screensaver -# define HACK_RESHAPE reshape_screensaver -# define screensaver_opts xlockmore_opts +#define DEFAULTS \ + "*delay: " DEF_DELAY "\n" \ + "*showFPS: " DEF_FPS "\n" \ + "*useSHM: True \n" + +# define refresh_mirrorblob 0 +# define mirrorblob_handle_event 0 +# include "xlockmore.h" /* from the xmirrorblob distribution */ +#else /* !STANDALONE */ +# include "xlock.h" /* from the xlockmore distribution */ +#endif /* !STANDALONE */ + +#ifdef USE_GL /* whole file */ + #define DEF_DELAY "10000" #define DEF_FPS "False" @@ -62,18 +68,6 @@ #define DEF_HOLD_TIME "30" #define DEF_FADE_TIME "5" -#define DEFAULTS \ - "*delay: " DEF_DELAY "\n" \ - "*showFPS: " DEF_FPS "\n" \ - "*useSHM: True \n" - -# include "xlockmore.h" /* from the xscreensaver distribution */ -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ - -#ifdef USE_GL /* whole file */ - #ifdef HAVE_XMU # ifndef VMS # include @@ -82,13 +76,6 @@ # endif /* VMS */ #endif -#include -#include -#include "GL/glx.h" - -#include -#include -/*#include */ #include "grab-ximage.h" #undef countof @@ -115,8 +102,8 @@ static int fade_time; static int hold_time; static XrmOptionDescRec opts[] = { - {"-wire", ".blob.wire", XrmoptionNoArg, "true" }, - {"+wire", ".blob.wire", XrmoptionNoArg, "false" }, + {"-wireframe", ".blob.wire", XrmoptionNoArg, "true" }, + {"+wireframe", ".blob.wire", XrmoptionNoArg, "false" }, {"-blend", ".blob.blend", XrmoptionNoArg, "true" }, {"+blend", ".blob.blend", XrmoptionNoArg, "false" }, {"-fog", ".blob.fog", XrmoptionNoArg, "true" }, @@ -182,25 +169,17 @@ static OptionStruct desc[] = {"-hold_time", "Number of frames before next image"}, }; -ModeSpecOpt screensaver_opts = {countof(opts), opts, countof(vars), vars, desc}; +ENTRYPOINT ModeSpecOpt mirrorblob_opts = {countof(opts), opts, countof(vars), vars, desc}; #ifdef USE_MODULES -ModStruct screensaver_description = -{"screensaver", "init_screensaver", "draw_screensaver", "release_screensaver", - "draw_screensaver", "init_screensaver", NULL, &screensaver_opts, +ModStruct mirrorblob_description = +{"mirrorblob", "init_mirrorblob", "draw_mirrorblob", "release_mirrorblob", + "draw_mirrorblob", "init_mirrorblob", NULL, &mirrorblob_opts, 1000, 1, 2, 1, 4, 1.0, "", - "OpenGL screensaver", 0, NULL}; + "OpenGL mirrorblob", 0, NULL}; #endif -/* structure for holding the screensaver data */ -typedef struct { - int screen_width, screen_height; - GLXContext *glx_context; - Window window; - XColor fg, bg; -} screensaverstruct; - -static screensaverstruct *Screensaver = NULL; +#define NUM_TEXTURES 2 /***************************************************************************** * Types used in blob code @@ -240,49 +219,61 @@ typedef struct Vector3D pos; } Field_Data; -/***************************************************************************** - * Static blob data - *****************************************************************************/ +typedef enum +{ + HOLDING=0, + TRANSITIONING +} Frame_State; -static Row_Data *row_data; -/* Parameters controlling the position of the blob as a whole */ -static Vector3D blob_center = {0.0, 0.0, 0.0}; -static Vector3D blob_anchor = {0.0, 0.0, 0.0}; -static Vector3D blob_velocity = {0.0, 0.0, 0.0}; -static Vector3D blob_force = {0.0, 0.0, 0.0}; +/* structure for holding the mirrorblob data */ +typedef struct { + int screen_width, screen_height; + GLXContext *glx_context; + Window window; + XColor fg, bg; + double freak, v_freak; -/* Count of the total number of points */ -static int num_points; + Row_Data *row_data; -static Vector3D *dots = NULL; -static Vector3D *normals = NULL; -static Colour *colours = NULL; -static Vector2D *tex_coords = NULL; + /* Parameters controlling the position of the blob as a whole */ + Vector3D blob_center; + Vector3D blob_anchor; + Vector3D blob_velocity; + Vector3D blob_force; -/* Pointer to the field function results */ -static double *field = 0, *wall_field = 0; + /* Count of the total number of points */ + int num_points; -Field_Data *field_data; + Vector3D *dots; + Vector3D *normals; + Colour *colours; + Vector2D *tex_coords; -/* Use 2 textures to allow a gradual fade between images */ -#define NUM_TEXTURES 2 -static int current_texture; + /* Pointer to the field function results */ + double *field, *wall_field; -/* Ratio of used texture size to total texture size */ -GLfloat tex_width[NUM_TEXTURES], tex_height[NUM_TEXTURES]; -GLuint textures[NUM_TEXTURES]; + Field_Data *field_data; -typedef enum -{ - HOLDING, - TRANSITIONING -} Frame_State; + /* Use 2 textures to allow a gradual fade between images */ + int current_texture; + + /* Ratio of used texture size to total texture size */ + GLfloat tex_width[NUM_TEXTURES], tex_height[NUM_TEXTURES]; + GLuint textures[NUM_TEXTURES]; -static Frame_State state = HOLDING; -static double state_start_time = 0; + Frame_State state; + double state_start_time; -static int colour_cycle = 0; + int colour_cycle; + + Bool mipmap_p; + Bool waiting_for_image_p; + Bool first_image_p; + +} mirrorblobstruct; + +static mirrorblobstruct *Mirrorblob = NULL; /****************************************************************************** * @@ -321,30 +312,57 @@ reset_projection(int width, int height) /**************************************************************************** * - * Load a texture using the screen_to_texture function. + * Load a texture. */ -void -grab_texture(ModeInfo *mi, int texture_index) + +static void +image_loaded_cb (const char *filename, XRectangle *geometry, + int image_width, int image_height, + int texture_width, int texture_height, + void *closure) { - Bool mipmap_p = True; - int iw, ih, tw, th; + mirrorblobstruct *mp = (mirrorblobstruct *) closure; + GLint texid = -1; + int texture_index = -1; + int i; + + glGetIntegerv (GL_TEXTURE_BINDING_2D, &texid); + if (texid < 0) abort(); + + for (i = 0; i < NUM_TEXTURES; i++) { + if (mp->textures[i] == texid) { + texture_index = i; + break; + } + } + if (texture_index < 0) abort(); - glBindTexture (GL_TEXTURE_2D, textures[texture_index]); + mp->tex_width [texture_index] = (GLfloat) image_width / texture_width; + mp->tex_height[texture_index] = -(GLfloat) image_height / texture_height; - if (! screen_to_texture (mi->xgwa.screen, mi->window, 0, 0, mipmap_p, - NULL, NULL, &iw, &ih, &tw, &th)) - exit(1); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + (mp->mipmap_p ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR)); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - tex_width [texture_index] = (GLfloat) iw / tw; - tex_height[texture_index] = -(GLfloat) ih / th; + mp->waiting_for_image_p = False; + mp->first_image_p = True; +} - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - (mipmap_p ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR)); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +static void +grab_texture(ModeInfo *mi, int texture_index) +{ + mirrorblobstruct *mp = &Mirrorblob[MI_SCREEN(mi)]; + + mp->waiting_for_image_p = True; + mp->mipmap_p = True; + load_texture_async (mi->xgwa.screen, mi->window, + *mp->glx_context, 0, 0, mp->mipmap_p, + mp->textures[texture_index], + image_loaded_cb, mp); } /****************************************************************************** @@ -354,6 +372,8 @@ grab_texture(ModeInfo *mi, int texture_index) static void initialize_gl(ModeInfo *mi, GLsizei width, GLsizei height) { + mirrorblobstruct *gp = &Mirrorblob[MI_SCREEN(mi)]; + GLfloat fogColor[4] = { 0.1, 0.1, 0.1, 0.1 }; /* Lighting values */ GLfloat lightPos0[] = {500.0f, 100.0f, 200.0f, 1.0f }; @@ -447,9 +467,9 @@ initialize_gl(ModeInfo *mi, GLsizei width, GLsizei height) glLightModeli (GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); glEnable (GL_TEXTURE_2D); - current_texture = 0; - glGenTextures (NUM_TEXTURES, textures); - grab_texture (mi, current_texture); + gp->current_texture = 0; + glGenTextures (NUM_TEXTURES, gp->textures); + grab_texture (mi, gp->current_texture); glEnableClientState (GL_TEXTURE_COORD_ARRAY); } @@ -512,119 +532,119 @@ calculate_normal (Vector3D point1, * Return 0 on success. */ static int -initialise_blob(int width, - int height, +initialise_blob(mirrorblobstruct *gp, + int width, int height, int field_array_size) { /* Loop variables */ int x, y, i; double xd; - colour_cycle = 0; + gp->colour_cycle = 0; - row_data = (Row_Data *) malloc (y_resolution * sizeof (Row_Data)); - if (!row_data) + gp->row_data = (Row_Data *) malloc (y_resolution * sizeof (Row_Data)); + if (!gp->row_data) { fprintf(stderr, "Couldn't allocate row data buffer\n"); return -1; } - field_data = (Field_Data *) malloc (field_points * sizeof (Field_Data)); - if (!field_data) + gp->field_data = (Field_Data *) malloc (field_points * sizeof (Field_Data)); + if (!gp->field_data) { fprintf(stderr, "Couldn't allocate field data buffer\n"); return -1; } - field = (double *)malloc(field_array_size * sizeof(double)); - if (!field) + gp->field = (double *)malloc(field_array_size * sizeof(double)); + if (!gp->field) { fprintf(stderr, "Couldn't allocate field buffer\n"); return -1; } - wall_field = (double *)malloc(field_array_size * sizeof(double)); - if (!wall_field) + gp->wall_field = (double *)malloc(field_array_size * sizeof(double)); + if (!gp->wall_field) { fprintf(stderr, "Couldn't allocate wall field buffer\n"); return -1; } - dots = (Vector3D *)malloc(x_resolution * y_resolution * sizeof(Vector3D)); - if (!dots) + gp->dots = (Vector3D *)malloc(x_resolution * y_resolution * sizeof(Vector3D)); + if (!gp->dots) { fprintf(stderr, "Couldn't allocate points buffer\n"); return -1; } - glVertexPointer (3, GL_DOUBLE, 0, (GLvoid *) dots); + glVertexPointer (3, GL_DOUBLE, 0, (GLvoid *) gp->dots); - normals = (Vector3D *)malloc(x_resolution * y_resolution * sizeof(Vector3D)); - if (!normals) + gp->normals = (Vector3D *)malloc(x_resolution * y_resolution * sizeof(Vector3D)); + if (!gp->normals) { fprintf(stderr, "Couldn't allocate normals buffer\n"); return -1; } - glNormalPointer (GL_DOUBLE, 0, (GLvoid *) normals); + glNormalPointer (GL_DOUBLE, 0, (GLvoid *) gp->normals); if (do_colour) { - colours = (Colour *)malloc(x_resolution * y_resolution * sizeof(Colour)); - if (!colours) + gp->colours = (Colour *)malloc(x_resolution * y_resolution * sizeof(Colour)); + if (!gp->colours) { fprintf(stderr, "Couldn't allocate colours buffer\n"); return -1; } - glColorPointer (4, GL_UNSIGNED_BYTE, 0, (GLvoid *) colours); + glColorPointer (4, GL_UNSIGNED_BYTE, 0, (GLvoid *) gp->colours); } if (do_texture) { - tex_coords = (Vector2D *)malloc(x_resolution * y_resolution + gp->tex_coords = (Vector2D *)malloc(x_resolution * y_resolution * sizeof(Vector2D)); - if (!tex_coords) + if (!gp->tex_coords) { fprintf(stderr, "Couldn't allocate tex_coords buffer\n"); return -1; } - glTexCoordPointer (2, GL_DOUBLE, 0, (GLvoid *) tex_coords); + glTexCoordPointer (2, GL_DOUBLE, 0, (GLvoid *) gp->tex_coords); } - num_points = 0; + gp->num_points = 0; /* Generate constant row data and count of total number of points */ for (y = 0; y < y_resolution; y++) { - row_data[y].cosyd = cos(PI * (double)(y * (y_resolution + 1)) + gp->row_data[y].cosyd = cos(PI * (double)(y * (y_resolution + 1)) / (double)(y_resolution * y_resolution)); - row_data[y].sinyd = sin(PI * (double)(y * (y_resolution + 1)) + gp->row_data[y].sinyd = sin(PI * (double)(y * (y_resolution + 1)) / (double)(y_resolution * y_resolution)); - row_data[y].num_x_points = (int)(x_resolution * row_data[y].sinyd + 1.0); - num_points += row_data[y].num_x_points; + gp->row_data[y].num_x_points = (int)(x_resolution * gp->row_data[y].sinyd + 1.0); + gp->num_points += gp->row_data[y].num_x_points; } /* Initialise field data */ for (i = 0; i < field_points; i++) { - field_data[i].ax = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5); - field_data[i].ay = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5); - field_data[i].apower = (((double)random() / (double)RAND_MAX) - 0.5); - - field_data[i].pos.x = 1.5 * sin(PI * field_data[i].ay) - * cos(PI * field_data[i].ax); - field_data[i].pos.y = 1.5 * cos(PI * field_data[i].ay); - field_data[i].pos.z = 1.5 * sin(PI * field_data[i].ay) - * sin(PI * field_data[i].ax); - - field_data[i].cx = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5); - field_data[i].cy = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5); - field_data[i].cpower = (((double)random() / (double)RAND_MAX) - 0.5); - - field_data[i].vx = 0.0; - field_data[i].vy = 0.0; - field_data[i].vpower = 0.0; - - field_data[i].mx = 0.003 * ((double)random() / (double)RAND_MAX); - field_data[i].my = 0.003 * ((double)random() / (double)RAND_MAX); - field_data[i].mpower = 0.003 * ((double)random() / (double)RAND_MAX); + gp->field_data[i].ax = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5); + gp->field_data[i].ay = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5); + gp->field_data[i].apower = (((double)random() / (double)RAND_MAX) - 0.5); + + gp->field_data[i].pos.x = 1.5 * sin(PI * gp->field_data[i].ay) + * cos(PI * gp->field_data[i].ax); + gp->field_data[i].pos.y = 1.5 * cos(PI * gp->field_data[i].ay); + gp->field_data[i].pos.z = 1.5 * sin(PI * gp->field_data[i].ay) + * sin(PI * gp->field_data[i].ax); + + gp->field_data[i].cx = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5); + gp->field_data[i].cy = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5); + gp->field_data[i].cpower = (((double)random() / (double)RAND_MAX) - 0.5); + + gp->field_data[i].vx = 0.0; + gp->field_data[i].vy = 0.0; + gp->field_data[i].vpower = 0.0; + + gp->field_data[i].mx = 0.003 * ((double)random() / (double)RAND_MAX); + gp->field_data[i].my = 0.003 * ((double)random() / (double)RAND_MAX); + gp->field_data[i].mpower = 0.003 * ((double)random() / (double)RAND_MAX); } /* Initialise lookup table of field strength */ @@ -633,29 +653,29 @@ initialise_blob(int width, xd = 2.0 * (((double)i / (double)field_array_size)); xd = 3.0 * xd * xd * xd * xd; - field[i] = 0.4 / (field_points * (xd + 0.1)); + gp->field[i] = 0.4 / (field_points * (xd + 0.1)); xd = 10.0 * (((double)i / (double)field_array_size)); - wall_field[i] = 0.4 / (xd * xd * xd * xd + 1.0); + gp->wall_field[i] = 0.4 / (xd * xd * xd * xd + 1.0); } for (y = 0; y < y_resolution; y++) { - for (x = 0; x < row_data[y].num_x_points; x++) + for (x = 0; x < gp->row_data[y].num_x_points; x++) { i = x + y * x_resolution; - xd = 2.0 * (((double)x / (double)row_data[y].num_x_points) - 0.5); - - dots[i].x = row_data[y].sinyd * cos(PI * xd); - dots[i].y = row_data[y].cosyd; - dots[i].z = row_data[y].sinyd * sin(PI * xd); - normals[i].x = row_data[y].sinyd * cos(PI * xd); - normals[i].y = row_data[y].cosyd; - normals[i].z = row_data[y].sinyd * sin(PI * xd); + xd = 2.0 * (((double)x / (double)gp->row_data[y].num_x_points) - 0.5); + + gp->dots[i].x = gp->row_data[y].sinyd * cos(PI * xd); + gp->dots[i].y = gp->row_data[y].cosyd; + gp->dots[i].z = gp->row_data[y].sinyd * sin(PI * xd); + gp->normals[i].x = gp->row_data[y].sinyd * cos(PI * xd); + gp->normals[i].y = gp->row_data[y].cosyd; + gp->normals[i].z = gp->row_data[y].sinyd * sin(PI * xd); if (do_texture) { - tex_coords[i].x = 2.0 - 2.0 * x / (float) row_data[y].num_x_points; - tex_coords[i].y = 1.0 - y / (float) y_resolution; + gp->tex_coords[i].x = 2.0 - 2.0 * x / (float) gp->row_data[y].num_x_points; + gp->tex_coords[i].y = 1.0 - y / (float) y_resolution; } } } @@ -668,16 +688,12 @@ initialise_blob(int width, * Calculate the blob shape. */ static void -calc_blob(int width, - int height, +calc_blob(mirrorblobstruct *gp, + int width, int height, int field_array_size, float limit, double fade) { - static double freak = 0.0; - - static double v_freak = 0.0007; - /* Loop variables */ int x, y, i, index, index1, index2, index3; /* position of a point */ @@ -688,46 +704,46 @@ calc_blob(int width, /* Color components */ - colour_cycle++; + gp->colour_cycle++; /* Update position and strength of points used to distort the blob */ for (i = 0; i < field_points; i++) { - field_data[i].vx += field_data[i].mx*(field_data[i].cx - field_data[i].ax); - field_data[i].vy += field_data[i].my*(field_data[i].cy - field_data[i].ay); - field_data[i].vpower += field_data[i].mpower - * (field_data[i].cpower - field_data[i].apower); - - field_data[i].ax += 0.1 * field_data[i].vx; - field_data[i].ay += 0.1 * field_data[i].vy; - field_data[i].apower += 0.1 * field_data[i].vpower; - - field_data[i].pos.x = 1.0 * sin(PI * field_data[i].ay) - * cos(PI * field_data[i].ax); - field_data[i].pos.y = 1.0 * cos(PI * field_data[i].ay); - field_data[i].pos.z = 1.0 * sin(PI * field_data[i].ay) - * sin(PI * field_data[i].ax); + gp->field_data[i].vx += gp->field_data[i].mx*(gp->field_data[i].cx - gp->field_data[i].ax); + gp->field_data[i].vy += gp->field_data[i].my*(gp->field_data[i].cy - gp->field_data[i].ay); + gp->field_data[i].vpower += gp->field_data[i].mpower + * (gp->field_data[i].cpower - gp->field_data[i].apower); + + gp->field_data[i].ax += 0.1 * gp->field_data[i].vx; + gp->field_data[i].ay += 0.1 * gp->field_data[i].vy; + gp->field_data[i].apower += 0.1 * gp->field_data[i].vpower; + + gp->field_data[i].pos.x = 1.0 * sin(PI * gp->field_data[i].ay) + * cos(PI * gp->field_data[i].ax); + gp->field_data[i].pos.y = 1.0 * cos(PI * gp->field_data[i].ay); + gp->field_data[i].pos.z = 1.0 * sin(PI * gp->field_data[i].ay) + * sin(PI * gp->field_data[i].ax); } - blob_force.x = 0.0; - blob_force.y = 0.0; - blob_force.z = 0.0; + gp->blob_force.x = 0.0; + gp->blob_force.y = 0.0; + gp->blob_force.z = 0.0; for (y = 0; y < y_resolution; y++) { - for (x = 0; x < row_data[y].num_x_points; x++) + for (x = 0; x < gp->row_data[y].num_x_points; x++) { index = x + y * x_resolution; - xd = 2.0 * PI * (((double)x / (double)row_data[y].num_x_points) - 0.5); + xd = 2.0 * PI * (((double)x / (double)gp->row_data[y].num_x_points) - 0.5); radius = 1.0 + 0.0 * sin (xd * 10); - zd = radius * row_data[y].sinyd * sin(xd); - xd = radius * row_data[y].sinyd * cos(xd); - yd = radius * row_data[y].cosyd; + zd = radius * gp->row_data[y].sinyd * sin(xd); + xd = radius * gp->row_data[y].sinyd * cos(xd); + yd = radius * gp->row_data[y].cosyd; - normals[index].x = xd; - normals[index].y = yd; - normals[index].z = zd; + gp->normals[index].x = xd; + gp->normals[index].y = yd; + gp->normals[index].z = zd; offset_x = 0.0; offset_y = 0.0; @@ -735,32 +751,32 @@ calc_blob(int width, strength = 0.0; for ( i = 0; i < field_points; i++) { - xdist = field_data[i].pos.x - xd; - ydist = field_data[i].pos.y - yd; - zdist = field_data[i].pos.z - zd; + xdist = gp->field_data[i].pos.x - xd; + ydist = gp->field_data[i].pos.y - yd; + zdist = gp->field_data[i].pos.z - zd; dist = field_array_size * (xdist * xdist + ydist * ydist + zdist * zdist) * 0.1; - strength += PI * field_data[i].apower; + strength += PI * gp->field_data[i].apower; if (dist < field_array_size) { - offset_x += xd * field_data[i].apower * field[dist]; - offset_y += yd * field_data[i].apower * field[dist]; - offset_z += zd * field_data[i].apower * field[dist]; + offset_x += xd * gp->field_data[i].apower * gp->field[dist]; + offset_y += yd * gp->field_data[i].apower * gp->field[dist]; + offset_z += zd * gp->field_data[i].apower * gp->field[dist]; - blob_force.x += 1.0 * xd * field_data[i].apower * field[dist]; - blob_force.y += 1.0 * yd * field_data[i].apower * field[dist]; - blob_force.z += 1.0 * zd * field_data[i].apower * field[dist]; + gp->blob_force.x += 1.0 * xd * gp->field_data[i].apower * gp->field[dist]; + gp->blob_force.y += 1.0 * yd * gp->field_data[i].apower * gp->field[dist]; + gp->blob_force.z += 1.0 * zd * gp->field_data[i].apower * gp->field[dist]; - strength *= 2.0 * field[dist]; + strength *= 2.0 * gp->field[dist]; } if (incremental) { - xd += offset_x * freak * freak; - yd += offset_y * freak * freak; - zd += offset_z * freak * freak; + xd += offset_x * gp->freak * gp->freak; + yd += offset_y * gp->freak * gp->freak; + zd += offset_z * gp->freak * gp->freak; } if (incremental == 1) { @@ -776,16 +792,16 @@ calc_blob(int width, yd += offset_y; zd += offset_z; } - xd += blob_center.x; - yd += blob_center.y; - zd += blob_center.z; + xd += gp->blob_center.x; + yd += gp->blob_center.y; + zd += gp->blob_center.z; if (do_colour) { - colours[index].red = 128 + (int)(sin(strength + colour_cycle * 0.01 + 2.0 * PI * x / row_data[y].num_x_points) * 127.0); - colours[index].green = 128 + (int)(cos(strength + colour_cycle * 0.025) * 127.0); - colours[index].blue = 128 + (int)(sin(strength + colour_cycle * 0.03 + 2.0 * PI * y / y_resolution) * 127.0); - colours[index].alpha = (int)(255.0 * fade); + gp->colours[index].red = 128 + (int)(sin(strength + gp->colour_cycle * 0.01 + 2.0 * PI * x / gp->row_data[y].num_x_points) * 127.0); + gp->colours[index].green = 128 + (int)(cos(strength + gp->colour_cycle * 0.025) * 127.0); + gp->colours[index].blue = 128 + (int)(sin(strength + gp->colour_cycle * 0.03 + 2.0 * PI * y / y_resolution) * 127.0); + gp->colours[index].alpha = (int)(255.0 * fade); } /* Add walls */ @@ -797,18 +813,18 @@ calc_blob(int width, dist = field_array_size * (zd + limit) * (zd + limit) * 0.5; if (dist < field_array_size) { - xd += (xd - blob_center.x) * wall_field[dist]; - yd += (yd - blob_center.y) * wall_field[dist]; - blob_force.z += (zd + limit); + xd += (xd - gp->blob_center.x) * gp->wall_field[dist]; + yd += (yd - gp->blob_center.y) * gp->wall_field[dist]; + gp->blob_force.z += (zd + limit); } else { dist = field_array_size * (zd - limit) * (zd - limit) * 0.5; if (dist < field_array_size) { - xd += (xd - blob_center.x) * wall_field[dist]; - yd += (yd - blob_center.y) * wall_field[dist]; - blob_force.z -= (zd - limit); + xd += (xd - gp->blob_center.x) * gp->wall_field[dist]; + yd += (yd - gp->blob_center.y) * gp->wall_field[dist]; + gp->blob_force.z -= (zd - limit); } if (yd < -limit) yd = -limit; @@ -817,18 +833,18 @@ calc_blob(int width, dist = field_array_size * (yd + limit) * (yd + limit) * 0.5; if (dist < field_array_size) { - xd += (xd - blob_center.x) * wall_field[dist]; - zd += (zd - blob_center.z) * wall_field[dist]; - blob_force.y += (yd + limit); + xd += (xd - gp->blob_center.x) * gp->wall_field[dist]; + zd += (zd - gp->blob_center.z) * gp->wall_field[dist]; + gp->blob_force.y += (yd + limit); } else { dist = field_array_size * (yd - limit) * (yd - limit) * 0.5; if (dist < field_array_size) { - xd += (xd - blob_center.x) * wall_field[dist]; - zd += (zd - blob_center.z) * wall_field[dist]; - blob_force.y -= (yd - limit); + xd += (xd - gp->blob_center.x) * gp->wall_field[dist]; + zd += (zd - gp->blob_center.z) * gp->wall_field[dist]; + gp->blob_force.y -= (yd - limit); } } @@ -838,18 +854,18 @@ calc_blob(int width, dist = field_array_size * (xd + limit) * (xd + limit) * 0.5; if (dist < field_array_size) { - yd += (yd - blob_center.y) * wall_field[dist]; - zd += (zd - blob_center.z) * wall_field[dist]; - blob_force.x += (xd + limit); + yd += (yd - gp->blob_center.y) * gp->wall_field[dist]; + zd += (zd - gp->blob_center.z) * gp->wall_field[dist]; + gp->blob_force.x += (xd + limit); } else { dist = field_array_size * (xd - limit) * (xd - limit) * 0.5; if (dist < field_array_size) { - yd += (yd - blob_center.y) * wall_field[dist]; - zd += (zd - blob_center.z) * wall_field[dist]; - blob_force.x -= (xd - limit); + yd += (yd - gp->blob_center.y) * gp->wall_field[dist]; + zd += (zd - gp->blob_center.z) * gp->wall_field[dist]; + gp->blob_force.x -= (xd - limit); } } @@ -858,9 +874,9 @@ calc_blob(int width, } } - dots[index].x = xd; - dots[index].y = yd; - dots[index].z = zd; + gp->dots[index].x = xd; + gp->dots[index].y = yd; + gp->dots[index].z = zd; } } @@ -876,34 +892,34 @@ calc_blob(int width, index1 = 0; index2 = y * x_resolution; index3 = 1 + y * x_resolution; - calculate_normal (dots[index1], dots[index2], dots[index3], &normals[index1]); + calculate_normal (gp->dots[index1], gp->dots[index2], gp->dots[index3], &gp->normals[index1]); if (do_texture) { if (offset_texture) { - tex_coords[index1].x = dots[index1].x * 0.125 + 0.5 - * (1.0 + 0.25 * asin(normals[index1].x) / (0.5 * PI)); - tex_coords[index1].y = dots[index1].y * 0.125 + 0.5 - * (1.0 + 0.25 * asin(normals[index1].y) / (0.5 * PI)); + gp->tex_coords[index1].x = gp->dots[index1].x * 0.125 + 0.5 + * (1.0 + 0.25 * asin(gp->normals[index1].x) / (0.5 * PI)); + gp->tex_coords[index1].y = gp->dots[index1].y * 0.125 + 0.5 + * (1.0 + 0.25 * asin(gp->normals[index1].y) / (0.5 * PI)); } else { - tex_coords[index1].x = 0.5 * (1.0 + (asin(normals[index1].x) + gp->tex_coords[index1].x = 0.5 * (1.0 + (asin(gp->normals[index1].x) / (0.5 * PI))); - tex_coords[index1].y = 0.5 * (1.0 + (asin(normals[index1].y) + gp->tex_coords[index1].y = 0.5 * (1.0 + (asin(gp->normals[index1].y) / (0.5 * PI))); } - tex_coords[index1].x *= tex_width[current_texture]; - tex_coords[index1].y *= tex_height[current_texture]; + gp->tex_coords[index1].x *= gp->tex_width[gp->current_texture]; + gp->tex_coords[index1].y *= gp->tex_height[gp->current_texture]; } for (y = 1; y < y_resolution - 1; y++) { - if (row_data[y - 1].num_x_points) + if (gp->row_data[y - 1].num_x_points) { - for (x = 0; x < row_data[y].num_x_points; x++) + for (x = 0; x < gp->row_data[y].num_x_points; x++) { - if (x == row_data[y].num_x_points - 1) + if (x == gp->row_data[y].num_x_points - 1) { index1 = y * x_resolution; } @@ -912,28 +928,28 @@ calc_blob(int width, index1 = x + 1 + y * x_resolution; } index2 = x + y * x_resolution; - index3 = ((x + 0.5) * row_data[y - 1].num_x_points - / row_data[y].num_x_points) + (y - 1) * x_resolution; - calculate_normal (dots[index1], dots[index2], dots[index3], - &normals[index1]); + index3 = ((x + 0.5) * gp->row_data[y - 1].num_x_points + / gp->row_data[y].num_x_points) + (y - 1) * x_resolution; + calculate_normal (gp->dots[index1], gp->dots[index2], gp->dots[index3], + &gp->normals[index1]); if (do_texture) { if (offset_texture) { - tex_coords[index1].x = dots[index1].x * 0.125 + 0.5 - * (1.0 + 0.25 * asin(normals[index1].x) / (0.5 * PI)); - tex_coords[index1].y = dots[index1].y * 0.125 + 0.5 - * (1.0 + 0.25 * asin(normals[index1].y) / (0.5 * PI)); + gp->tex_coords[index1].x = gp->dots[index1].x * 0.125 + 0.5 + * (1.0 + 0.25 * asin(gp->normals[index1].x) / (0.5 * PI)); + gp->tex_coords[index1].y = gp->dots[index1].y * 0.125 + 0.5 + * (1.0 + 0.25 * asin(gp->normals[index1].y) / (0.5 * PI)); } else { - tex_coords[index1].x = 0.5 * (1.0 + (asin(normals[index1].x) + gp->tex_coords[index1].x = 0.5 * (1.0 + (asin(gp->normals[index1].x) / (0.5 * PI))); - tex_coords[index1].y = 0.5 * (1.0 + (asin(normals[index1].y) + gp->tex_coords[index1].y = 0.5 * (1.0 + (asin(gp->normals[index1].y) / (0.5 * PI))); } - tex_coords[index1].x *= tex_width[current_texture]; - tex_coords[index1].y *= tex_height[current_texture]; + gp->tex_coords[index1].x *= gp->tex_width[gp->current_texture]; + gp->tex_coords[index1].y *= gp->tex_height[gp->current_texture]; } } } @@ -941,46 +957,46 @@ calc_blob(int width, index1 = (y_resolution - 1) * x_resolution; index2 = (y_resolution - 2) * x_resolution; index3 = 1 + (y_resolution - 2) * x_resolution; - calculate_normal (dots[index1], dots[index2], dots[index3], &normals[index1]); + calculate_normal (gp->dots[index1], gp->dots[index2], gp->dots[index3], &gp->normals[index1]); if (do_texture) { if (offset_texture) { - tex_coords[index1].x = dots[index1].x * 0.125 + 0.5 - * (1.0 + 0.25 * asin(normals[index1].x) / (0.5 * PI)); - tex_coords[index1].y = dots[index1].y * 0.125 + 0.5 - * (1.0 + 0.25 * asin(normals[index1].y) / (0.5 * PI)); + gp->tex_coords[index1].x = gp->dots[index1].x * 0.125 + 0.5 + * (1.0 + 0.25 * asin(gp->normals[index1].x) / (0.5 * PI)); + gp->tex_coords[index1].y = gp->dots[index1].y * 0.125 + 0.5 + * (1.0 + 0.25 * asin(gp->normals[index1].y) / (0.5 * PI)); } else { - tex_coords[index1].x = 0.5 * (1.0 + (asin(normals[index1].x) + gp->tex_coords[index1].x = 0.5 * (1.0 + (asin(gp->normals[index1].x) / (0.5 * PI))); - tex_coords[index1].y = 0.5 * (1.0 + (asin(normals[index1].y) + gp->tex_coords[index1].y = 0.5 * (1.0 + (asin(gp->normals[index1].y) / (0.5 * PI))); } - tex_coords[index1].x *= tex_width[current_texture]; - tex_coords[index1].y *= tex_height[current_texture]; + gp->tex_coords[index1].x *= gp->tex_width[gp->current_texture]; + gp->tex_coords[index1].y *= gp->tex_height[gp->current_texture]; } - freak += v_freak; - v_freak += -freak / 2000000.0; + gp->freak += gp->v_freak; + gp->v_freak += -gp->freak / 2000000.0; /* Update the center of the whole blob */ - blob_velocity.x += (blob_anchor.x - blob_center.x) / 80.0 - + 0.01 * blob_force.x / num_points; - blob_velocity.y += (blob_anchor.y - blob_center.y) / 80.0 - + 0.01 * blob_force.y / num_points; - blob_velocity.z += (blob_anchor.z - blob_center.z) / 80.0 - + 0.01 * blob_force.z / num_points; - - blob_center.x += blob_velocity.x * 0.5; - blob_center.y += blob_velocity.y * 0.5; - blob_center.z += blob_velocity.z * 0.5; - - blob_velocity.x *= 0.99; - blob_velocity.y *= 0.99; - blob_velocity.z *= 0.99; + gp->blob_velocity.x += (gp->blob_anchor.x - gp->blob_center.x) / 80.0 + + 0.01 * gp->blob_force.x / gp->num_points; + gp->blob_velocity.y += (gp->blob_anchor.y - gp->blob_center.y) / 80.0 + + 0.01 * gp->blob_force.y / gp->num_points; + gp->blob_velocity.z += (gp->blob_anchor.z - gp->blob_center.z) / 80.0 + + 0.01 * gp->blob_force.z / gp->num_points; + + gp->blob_center.x += gp->blob_velocity.x * 0.5; + gp->blob_center.y += gp->blob_velocity.y * 0.5; + gp->blob_center.z += gp->blob_velocity.z * 0.5; + + gp->blob_velocity.x *= 0.99; + gp->blob_velocity.y *= 0.99; + gp->blob_velocity.z *= 0.99; } /****************************************************************************** @@ -993,7 +1009,7 @@ calc_blob(int width, * with the more interesting bits of the code. */ static void -draw_blob (void) +draw_blob (mirrorblobstruct *gp) { int x, y, x2, x3; int index1, index2, index3; @@ -1007,12 +1023,12 @@ draw_blob (void) for (y = 1; y < y_resolution; y++) { - if (row_data[y - 1].num_x_points) + if (gp->row_data[y - 1].num_x_points) { - for (x = 0; x < row_data[y].num_x_points; x++) + for (x = 0; x < gp->row_data[y].num_x_points; x++) { glBegin (GL_TRIANGLES); - if (x == row_data[y].num_x_points - 1) + if (x == gp->row_data[y].num_x_points - 1) { index1 = y * x_resolution; } @@ -1021,17 +1037,17 @@ draw_blob (void) index1 = x + 1 + y * x_resolution; } index2 = x + y * x_resolution; - index3 = ((x + 0.5) * row_data[y - 1].num_x_points - / row_data[y].num_x_points) + (y - 1) * x_resolution; + index3 = ((x + 0.5) * gp->row_data[y - 1].num_x_points + / gp->row_data[y].num_x_points) + (y - 1) * x_resolution; glArrayElement(index1); glArrayElement(index2); glArrayElement(index3); glEnd(); - lower = ((x - 0.5) * row_data[y - 1].num_x_points - / (float)row_data[y].num_x_points); - upper = ((x + 0.5) * row_data[y - 1].num_x_points - / (float)row_data[y].num_x_points); + lower = ((x - 0.5) * gp->row_data[y - 1].num_x_points + / (float)gp->row_data[y].num_x_points); + upper = ((x + 0.5) * gp->row_data[y - 1].num_x_points + / (float)gp->row_data[y].num_x_points); if (upper > lower) { @@ -1041,17 +1057,17 @@ draw_blob (void) for (x2 = lower; x2 <= upper; x2++) { x3 = x2; - while (x3 < 0) x3 += row_data[y - 1].num_x_points; - while (x3 >= row_data[y - 1].num_x_points) - x3 -= row_data[y - 1].num_x_points; + while (x3 < 0) x3 += gp->row_data[y - 1].num_x_points; + while (x3 >= gp->row_data[y - 1].num_x_points) + x3 -= gp->row_data[y - 1].num_x_points; index2 = x3 + (y - 1) * x_resolution; if (x2 < upper) { x3 = x2 + 1; - while (x3 < 0) x3 += row_data[y - 1].num_x_points; - while (x3 >= row_data[y - 1].num_x_points) - x3 -= row_data[y - 1].num_x_points; + while (x3 < 0) x3 += gp->row_data[y - 1].num_x_points; + while (x3 >= gp->row_data[y - 1].num_x_points) + x3 -= gp->row_data[y - 1].num_x_points; index3 = x3 + (y - 1) * x_resolution; if (x2 == lower) { @@ -1074,6 +1090,8 @@ draw_blob (void) static void draw_background (ModeInfo *mi) { + mirrorblobstruct *gp = &Mirrorblob[MI_SCREEN(mi)]; + glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glEnable (GL_TEXTURE_2D); glDisable(GL_LIGHTING); @@ -1092,13 +1110,13 @@ draw_background (ModeInfo *mi) glTexCoord2f (0.0, 0.0); glVertex2i (0, 0); - glTexCoord2f (0.0, -tex_height[current_texture]); + glTexCoord2f (0.0, -gp->tex_height[gp->current_texture]); glVertex2i (0, MI_HEIGHT(mi)); - glTexCoord2f (tex_width[current_texture], -tex_height[current_texture]); + glTexCoord2f (gp->tex_width[gp->current_texture], -gp->tex_height[gp->current_texture]); glVertex2i (MI_WIDTH(mi), MI_HEIGHT(mi)); - glTexCoord2f (tex_width[current_texture], 0.0); + glTexCoord2f (gp->tex_width[gp->current_texture], 0.0); glVertex2i (MI_WIDTH(mi), 0); glEnd(); @@ -1114,6 +1132,8 @@ draw_background (ModeInfo *mi) static GLvoid draw_scene(ModeInfo * mi) { + mirrorblobstruct *gp = &Mirrorblob[MI_SCREEN(mi)]; + double fade = 0.0; double current_time; check_gl_error ("draw_scene"); @@ -1121,10 +1141,10 @@ draw_scene(ModeInfo * mi) glColor4d(1.0, 1.0, 1.0, 1.0); current_time = double_time(); - switch (state) + switch (gp->state) { case TRANSITIONING: - fade = (current_time - state_start_time) / fade_time; + fade = (current_time - gp->state_start_time) / fade_time; break; case HOLDING: @@ -1139,7 +1159,7 @@ draw_scene(ModeInfo * mi) */ if (do_texture) { - glBindTexture (GL_TEXTURE_2D, textures[current_texture]); + glBindTexture (GL_TEXTURE_2D, gp->textures[gp->current_texture]); } if (do_paint_background && !do_wire) @@ -1155,18 +1175,18 @@ draw_scene(ModeInfo * mi) /* When transitioning between two images paint the new image over the old * image with a varying alpha value to get a smooth fade. */ - if (state == TRANSITIONING) + if (gp->state == TRANSITIONING) { glDisable (GL_DEPTH_TEST); glEnable (GL_BLEND); /* Select the texture to transition to */ - glBindTexture (GL_TEXTURE_2D, textures[1 - current_texture]); + glBindTexture (GL_TEXTURE_2D, gp->textures[1 - gp->current_texture]); glColor4d (1.0, 1.0, 1.0, fade); draw_background (mi); /* Select the original texture to draw the blob */ - glBindTexture (GL_TEXTURE_2D, textures[current_texture]); + glBindTexture (GL_TEXTURE_2D, gp->textures[gp->current_texture]); glEnable (GL_DEPTH_TEST); } /* Clear the depth buffer bit so the backgound is behind the blob */ @@ -1196,7 +1216,7 @@ draw_scene(ModeInfo * mi) fade = fade * 0.5; } - calc_blob(MI_WIDTH(mi), MI_HEIGHT(mi), 1024, 2.5, fade); + calc_blob(gp, MI_WIDTH(mi), MI_HEIGHT(mi), 1024, 2.5, fade); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); @@ -1219,7 +1239,7 @@ draw_scene(ModeInfo * mi) glDisable (GL_BLEND); glColor4d (1.0, 1.0, 1.0, 1.0); } - draw_blob(); + draw_blob(gp); if (do_blend && do_colour) { @@ -1232,34 +1252,34 @@ draw_scene(ModeInfo * mi) */ if (do_texture && (hold_time > 0)) { - switch (state) + switch (gp->state) { case TRANSITIONING: glClear(GL_DEPTH_BUFFER_BIT); glEnable (GL_BLEND); /* Select the texture to transition to */ - glBindTexture (GL_TEXTURE_2D, textures[1 - current_texture]); + glBindTexture (GL_TEXTURE_2D, gp->textures[1 - gp->current_texture]); glColor4d (1.0, 1.0, 1.0, fade); - draw_blob (); + draw_blob (gp); - if ((current_time - state_start_time) > fade_time) + if ((current_time - gp->state_start_time) > fade_time) { - state = HOLDING; - state_start_time = current_time; - current_texture = 1 - current_texture; + gp->state = HOLDING; + gp->state_start_time = current_time; + gp->current_texture = 1 - gp->current_texture; } break; case HOLDING: - if ((current_time - state_start_time) > hold_time) + if ((current_time - gp->state_start_time) > hold_time) { - grab_texture (mi, 1 - current_texture); - state = TRANSITIONING; + grab_texture (mi, 1 - gp->current_texture); + gp->state = TRANSITIONING; /* Get the time again rather than using the current time so * that the time taken by the grab_texture function is not part * of the fade time */ - state_start_time = double_time(); + gp->state_start_time = double_time(); } break; } @@ -1268,18 +1288,23 @@ draw_scene(ModeInfo * mi) /****************************************************************************** * - * XScreensaver screen update entry + * XMirrorblob screen update entry */ -void -draw_screensaver(ModeInfo * mi) +ENTRYPOINT void +draw_mirrorblob(ModeInfo * mi) { - screensaverstruct *gp = &Screensaver[MI_SCREEN(mi)]; + mirrorblobstruct *gp = &Mirrorblob[MI_SCREEN(mi)]; Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); if (!gp->glx_context) return; + /* Wait for the first image; for subsequent images, load them in the + background while animating. */ + if (gp->waiting_for_image_p && gp->first_image_p) + return; + glXMakeCurrent(display, window, *(gp->glx_context)); draw_scene(mi); if (mi->fps_p) do_fps (mi); @@ -1288,10 +1313,10 @@ draw_screensaver(ModeInfo * mi) /****************************************************************************** * - * XScreensaver screen resize entry + * XMirrorblob screen resize entry */ -void -reshape_screensaver(ModeInfo *mi, int width, int height) +ENTRYPOINT void +reshape_mirrorblob(ModeInfo *mi, int width, int height) { glViewport( 0, 0, MI_WIDTH(mi), MI_HEIGHT(mi) ); reset_projection(width, height); @@ -1299,29 +1324,29 @@ reshape_screensaver(ModeInfo *mi, int width, int height) /****************************************************************************** * - * XScreensaver initialise entry + * XMirrorblob initialise entry */ -void -init_screensaver(ModeInfo * mi) +ENTRYPOINT void +init_mirrorblob(ModeInfo * mi) { int screen = MI_SCREEN(mi); - screensaverstruct *gp; + mirrorblobstruct *gp; - if (Screensaver == NULL) + if (Mirrorblob == NULL) { - if ((Screensaver = (screensaverstruct *) - calloc(MI_NUM_SCREENS(mi), sizeof (screensaverstruct))) == NULL) + if ((Mirrorblob = (mirrorblobstruct *) + calloc(MI_NUM_SCREENS(mi), sizeof (mirrorblobstruct))) == NULL) { return; } } - gp = &Screensaver[screen]; + gp = &Mirrorblob[screen]; gp->window = MI_WINDOW(mi); if ((gp->glx_context = init_GL(mi)) != NULL) { - reshape_screensaver(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); + reshape_mirrorblob(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); initialize_gl(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); } else @@ -1329,30 +1354,40 @@ init_screensaver(ModeInfo * mi) MI_CLEARWINDOW(mi); } - initialise_blob(MI_WIDTH(mi), MI_HEIGHT(mi), 1024); - state_start_time = double_time(); + initialise_blob(gp, MI_WIDTH(mi), MI_HEIGHT(mi), 1024); + gp->state_start_time = double_time(); + + gp->freak = 0.0; + gp->v_freak = 0.0007; + gp->first_image_p = True; } /****************************************************************************** * - * XScreensaver cleanup entry + * XMirrorblob cleanup entry */ -void -release_screensaver(ModeInfo * mi) +ENTRYPOINT void +release_mirrorblob(ModeInfo * mi) { - if (row_data) free(row_data); - if (field_data) free(field_data); - if (colours) free(colours); - if (tex_coords) free(tex_coords); - if (dots) free(dots); - if (wall_field) free(wall_field); - if (field) free(field); - - if (Screensaver != NULL) - { - (void) free((void *) Screensaver); - Screensaver = NULL; + if (Mirrorblob != NULL) { + int i; + for (i = 0; i < MI_NUM_SCREENS(mi); i++) { + mirrorblobstruct *gp = &Mirrorblob[i]; + if (gp->row_data) free(gp->row_data); + if (gp->field_data) free(gp->field_data); + if (gp->colours) free(gp->colours); + if (gp->tex_coords) free(gp->tex_coords); + if (gp->dots) free(gp->dots); + if (gp->wall_field) free(gp->wall_field); + if (gp->field) free(gp->field); } - FreeAllGL(mi); + + free(Mirrorblob); + Mirrorblob = NULL; + } + FreeAllGL(mi); } + +XSCREENSAVER_MODULE ("MirrorBlob", mirrorblob) + #endif