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/rubikblocks.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/rubikblocks.c')
| -rw-r--r-- | hacks/glx/rubikblocks.c | 650 |
1 files changed, 0 insertions, 650 deletions
diff --git a/hacks/glx/rubikblocks.c b/hacks/glx/rubikblocks.c deleted file mode 100644 index 6dcf2a3..0000000 --- a/hacks/glx/rubikblocks.c +++ /dev/null @@ -1,650 +0,0 @@ -/* rubikblocks, Copyright (c) 2009 Vasek Potocek <vasek.potocek@post.cz> - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation. No representations are made about the suitability of this - * software for any purpose. It is provided "as is" without express or - * implied warranty. - */ - -/* RubikBlocks - a Rubik's Mirror Blocks puzzle introduced in 2008. - * No mirrors in this version, though, hence the altered name. - */ - -/* TODO: - * add reflection to the faces - */ - -#define DEFAULTS "*delay: 20000 \n" \ - "*showFPS: False \n" \ - "*wireframe: False \n" \ - "*suppressRotationAnimation: True\n" \ - -# define release_rubikblocks 0 -#include "xlockmore.h" -#include "rotator.h" -#include "gltrackball.h" - -#ifdef USE_GL - -#define DEF_SPIN "True" -#define DEF_WANDER "True" -#define DEF_TEXTURE "True" -#define DEF_RANDOMIZE "False" -#define DEF_SPINSPEED "0.1" -#define DEF_ROTSPEED "3.0" -#define DEF_WANDERSPEED "0.005" -#define DEF_WAIT "40.0" -#define DEF_CUBESIZE "1.0" - -#define SHUFFLE 100 - -#define TEX_WIDTH 64 -#define TEX_HEIGHT 64 -#define BORDER 5 -#define BORDER2 (BORDER*BORDER) - -#define rnd01() ((int)(random()%2)) - -/*************************************************************************/ - -static Bool spin, wander, rndstart, tex; -static float spinspeed, tspeed, wspeed, twait, size; - -static argtype vars[] = { - { &spin, "spin", "Spin", DEF_SPIN, t_Bool}, - { &wander, "wander", "Wander", DEF_WANDER, t_Bool}, - { &rndstart, "randomize", "Randomize", DEF_RANDOMIZE, t_Bool}, - { &tex, "texture", "Texture", DEF_TEXTURE, t_Bool}, - { &spinspeed, "spinspeed", "SpinSpeed", DEF_SPINSPEED, t_Float}, - { &tspeed, "rotspeed", "RotSpeed", DEF_ROTSPEED, t_Float}, - { &wspeed, "wanderspeed", "WanderSpeed", DEF_WANDERSPEED, t_Float}, - { &twait, "wait", "Wait", DEF_WAIT, t_Float}, - { &size, "cubesize", "CubeSize", DEF_CUBESIZE, t_Float}, -}; - -static XrmOptionDescRec opts[] = { - { "-spin", ".spin", XrmoptionNoArg, "True" }, - { "+spin", ".spin", XrmoptionNoArg, "False" }, - { "-wander", ".wander", XrmoptionNoArg, "True" }, - { "+wander", ".wander", XrmoptionNoArg, "False" }, - { "-randomize", ".randomize", XrmoptionNoArg, "True" }, - { "+randomize", ".randomize", XrmoptionNoArg, "False" }, - { "-texture", ".texture", XrmoptionNoArg, "True" }, - { "+texture", ".texture", XrmoptionNoArg, "False" }, - { "-spinspeed", ".spinspeed", XrmoptionSepArg, 0 }, - { "-wanderspeed", ".wanderspeed", XrmoptionSepArg, 0 }, - { "-rotspeed", ".rotspeed", XrmoptionSepArg, 0 }, - { "-wait", ".wait", XrmoptionSepArg, 0 }, - { "-cubesize", ".cubesize", XrmoptionSepArg, 0 }, -}; - -ENTRYPOINT ModeSpecOpt rubikblocks_opts = {countof(opts), opts, countof(vars), vars, NULL}; - -#ifdef USE_MODULES -ModStruct rubikblocks_description = -{ "rubikblocks", "init_rubikblocks", "draw_rubikblocks", NULL, - "draw_rubikblocks", "change_rubikblocks", NULL, &rubikblocks_opts, - 25000, 1, 1, 1, 1.0, 4, "", - "Shows randomly shuffling Rubik's Mirror Blocks puzzle", 0, NULL -}; -#endif - -typedef struct { - float pos[3]; /* _original_ position */ - float qr[4]; /* quaternion of rotation */ - Bool act; /* flag if it is undergoing the current rotation */ -} piece_t; - -typedef struct { - GLXContext *glx_context; - rotator *rot; - trackball_state *trackball; - GLfloat ratio; - Bool button_down; - - Bool pause; /* pause between two rotations */ - float qfram[4]; /* quaternion describing the rotation in one anim. frame */ - GLfloat t, tmax; /* rotation clock */ - piece_t pieces[27]; /* type and tilt of all the pieces */ - - unsigned char texture[TEX_HEIGHT][TEX_WIDTH]; - GLuint list_base; - Bool wire; -} rubikblocks_conf; - -static rubikblocks_conf *rubikblocks = NULL; - -static const GLfloat shininess = 20.0; -static const GLfloat ambient[] = {0.0, 0.0, 0.0, 1.0}; -static const GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0}; -static const GLfloat position0[] = {1.0, 1.0, 1.0, 0.0}; -static const GLfloat position1[] = {-1.0, -1.0, 1.0, 0.0}; -static const GLfloat lmodel_ambient[] = {0.1, 0.1, 0.1, 1.0}; -static const GLfloat material_ambient[] = {0.7, 0.7, 0.7, 1.0}; -static const GLfloat material_diffuse[] = {0.7, 0.7, 0.7, 1.0}; -static const GLfloat material_specular[] = {0.2, 0.2, 0.2, 1.0}; - -/*************************************************************************/ - -/* Multiplies two quaternions, src*dest, and stores the result in dest. */ -static void -mult_quat(float src[4], float dest[4]) -{ - float r, i, j, k; - r = src[0]*dest[0] - src[1]*dest[1] - src[2]*dest[2] - src[3]*dest[3]; - i = src[0]*dest[1] + src[1]*dest[0] + src[2]*dest[3] - src[3]*dest[2]; - j = src[0]*dest[2] + src[2]*dest[0] + src[3]*dest[1] - src[1]*dest[3]; - k = src[0]*dest[3] + src[3]*dest[0] + src[1]*dest[2] - src[2]*dest[1]; - dest[0] = r; - dest[1] = i; - dest[2] = j; - dest[3] = k; -} - -/* Sets the 'act' flag for pieces which will undergo the rotation. */ -static void -flag_pieces(piece_t pieces[27], int axis, int side) -{ - int i, j; - float q[4]; - for(i = 0; i < 27; i++) - { - q[0] = 0; - q[1] = pieces[i].pos[0]; - q[2] = pieces[i].pos[1]; - q[3] = pieces[i].pos[2]; - mult_quat(pieces[i].qr, q); - for(j = 1; j < 4; j++) - q[j] = -q[j]; - mult_quat(pieces[i].qr, q); - for(j = 1; j < 4; j++) - q[j] = -q[j]; - if(fabs(q[axis] - side) < 0.1) - pieces[i].act = True; - else - pieces[i].act = False; - } -} - -/* "Rounds" the value to the nearest from the set {0, +-1/2, +-1/sqrt(2), +-1}. - * It is guaranteed to be pretty close to one when this function is called. */ -static float -settle_value(float v) -{ - if(v > 0.9) return 1; - else if(v < -0.9) return -1; - else if(v > 0.6) return M_SQRT1_2; - else if(v < -0.6) return -M_SQRT1_2; - else if(v > 0.4) return 0.5; - else if(v < -0.4) return -0.5; - else return 0; -} - -static void -randomize(rubikblocks_conf *cp) -{ - int axis, side; - int i, j; - for(i = 0; i < SHUFFLE; i++) - { - axis = (random()%3)+1; - side = rnd01()*2-1; - flag_pieces(cp->pieces, axis, side); - for(j = 1; j < 4; j++) - cp->qfram[j] = 0; - cp->qfram[0] = M_SQRT1_2; - cp->qfram[axis] = M_SQRT1_2; - for(j = 0; j < 27; j++) - { - if(cp->pieces[j].act) - mult_quat(cp->qfram, cp->pieces[j].qr); - } - } -} - -static void -finish(rubikblocks_conf *cp) -{ - static int axis = 1; - int side, angle; - int i, j; - if(cp->pause) - { - switch(axis) - { - case 1: - axis = rnd01()+2; - break; - case 2: - axis = 2*rnd01()+1; - break; - default: - axis = rnd01()+1; - } - side = rnd01()*2-1; - angle = rnd01()+1; - flag_pieces(cp->pieces, axis, side); - cp->pause = False; - cp->tmax = 90.0*angle; - for(i = 1; i < 4; i++) - cp->qfram[i] = 0; - cp->qfram[0] = cos(tspeed*M_PI/360); - cp->qfram[axis] = sin((rnd01()*2-1)*tspeed*M_PI/360); - } - else - { - for(i = 0; i < 27; i++) - { - for(j = 0; j < 4; j++) - { - cp->pieces[i].qr[j] = settle_value(cp->pieces[i].qr[j]); - } - } - cp->pause = True; - cp->tmax = twait; - } - cp->t = 0; -} - -static Bool -draw_main(ModeInfo *mi, rubikblocks_conf *cp) -{ - int i; - double x, y, z; - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glLoadIdentity(); - - get_position(cp->rot, &x, &y, &z, !cp->button_down); - glTranslatef((x-0.5)*6, (y-0.5)*6, -20); - - gltrackball_rotate(cp->trackball); - - get_rotation(cp->rot, &x, &y, &z, !cp->button_down); - glRotatef(x*360, 1, 0, 0); - glRotatef(y*360, 0, 1, 0); - glRotatef(z*360, 0, 0, 1); - glScalef(size, size, size); - -# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */ - { - GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi); - int o = (int) current_device_rotation(); - if (o != 0 && o != 180 && o != -180) - glScalef (1/h, 1/h, 1/h); - } -# else - { - /* Don't understand why this clause doesn't work on mobile, but it - doesn't. */ - GLfloat s = (MI_WIDTH(mi) < MI_HEIGHT(mi) - ? (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi)) - : 1); - glRotatef (current_device_rotation(), 0, 0, 1); - glScalef (s, s, s); - } -# endif - - if(cp->wire) glColor3f(0.7, 0.7, 0.7); - if(!cp->pause) - for(i = 0; i < 27; i++) - if(cp->pieces[i].act) - mult_quat(cp->qfram, cp->pieces[i].qr); - for(i = 0; i < 27; i++) - { - glPushMatrix(); - if(fabs(cp->pieces[i].qr[0]) < 1) - glRotatef(360/M_PI*acos(cp->pieces[i].qr[0]), - cp->pieces[i].qr[1], cp->pieces[i].qr[2], cp->pieces[i].qr[3]); - glCallList(cp->list_base + i); - glPopMatrix(); - } - if((cp->t += tspeed) > cp->tmax) finish(cp); - return True; -} - -static void -draw_horz_line(rubikblocks_conf *cp, int x1, int x2, int y) -{ - int x, y0 = y, w; - if(y < BORDER) y = -y; - else y = -BORDER; - for(; y < BORDER; y++) { - if(y0+y >= TEX_HEIGHT) break; - w = y*y*255/BORDER2; - for(x = x1; x <= x2; x++) - if(cp->texture[y0+y][x]>w) cp->texture[y0+y][x] = w; - } -} - -static void -draw_vert_line(rubikblocks_conf *cp, int x, int y1, int y2) -{ - int x0 = x, y, w; - if(x<BORDER) x = -x; - else x = -BORDER; - for(; x < BORDER; x++) { - if(x0+x >= TEX_WIDTH) break; - w = x*x*255/BORDER2; - for(y = y1; y <= y2; y++) - if(cp->texture[y][x0+x]>w) cp->texture[y][x0+x] = w; - } -} - -static void -make_texture(rubikblocks_conf *cp) -{ - int x, y; - for(y = 0; y < TEX_HEIGHT; y++) - for(x = 0; x < TEX_WIDTH; x++) - cp->texture[y][x] = 255; - draw_horz_line(cp, 0, TEX_WIDTH-1, 0); - draw_horz_line(cp, 0, TEX_WIDTH-1, TEX_HEIGHT-1); - draw_vert_line(cp, 0, 0, TEX_HEIGHT-1); - draw_vert_line(cp, TEX_WIDTH-1, 0, TEX_HEIGHT-1); -} - -/* These simple transforms make the actual shape of the pieces. The parameters - * A, B and C affect the excentricity of the pieces in each direction. */ -static float -fx(float x) -{ - const float A = 0.5; - if(x > 1.4) return 1.5 - A; - else if(x < -1.4) return -1.5 - A; - else return x; -} - -static float -fy(float y) -{ - const float B = 0.25; - if(y > 1.4) return 1.5 - B; - else if(y < -1.4) return -1.5 - B; - else return y; -} - -static float -fz(float z) -{ - const float C = 0.0; - if(z > 1.4) return 1.5 - C; - else if(z < -1.4) return -1.5 - C; - else return z; -} - -static void -init_lists(rubikblocks_conf *cp) -{ - GLuint base; - int i; - float x, y, z; - base = cp->list_base = glGenLists(27); - for(i = 0; i < 27; i++) - { - x = cp->pieces[i].pos[0]; - y = cp->pieces[i].pos[1]; - z = cp->pieces[i].pos[2]; - glNewList(base+i, GL_COMPILE); - glBegin(GL_QUAD_STRIP); - glNormal3f(1, 0, 0); - glTexCoord2f(0, 0); - glVertex3f(fx(x+0.5), fy(y-0.5), fz(z-0.5)); - glTexCoord2f(0, 1); - glVertex3f(fx(x+0.5), fy(y+0.5), fz(z-0.5)); - glTexCoord2f(1, 0); - glVertex3f(fx(x+0.5), fy(y-0.5), fz(z+0.5)); - glTexCoord2f(1, 1); - glVertex3f(fx(x+0.5), fy(y+0.5), fz(z+0.5)); - glNormal3f(0, 0, 1); - glTexCoord2f(0, 0); - glVertex3f(fx(x-0.5), fy(y-0.5), fz(z+0.5)); - glTexCoord2f(0, 1); - glVertex3f(fx(x-0.5), fy(y+0.5), fz(z+0.5)); - glNormal3f(-1, 0, 0); - glTexCoord2f(1, 0); - glVertex3f(fx(x-0.5), fy(y-0.5), fz(z-0.5)); - glTexCoord2f(1, 1); - glVertex3f(fx(x-0.5), fy(y+0.5), fz(z-0.5)); - glNormal3f(0, 0, -1); - glTexCoord2f(0, 0); - glVertex3f(fx(x+0.5), fy(y-0.5), fz(z-0.5)); - glTexCoord2f(0, 1); - glVertex3f(fx(x+0.5), fy(y+0.5), fz(z-0.5)); - glEnd(); - glBegin(GL_QUADS); - glNormal3f(0, 1, 0); - glTexCoord2f(0, 0); - glVertex3f(fx(x+0.5), fy(y+0.5), fz(z+0.5)); - glTexCoord2f(0, 1); - glVertex3f(fx(x+0.5), fy(y+0.5), fz(z-0.5)); - glTexCoord2f(1, 1); - glVertex3f(fx(x-0.5), fy(y+0.5), fz(z-0.5)); - glTexCoord2f(1, 0); - glVertex3f(fx(x-0.5), fy(y+0.5), fz(z+0.5)); - glNormal3f(0, -1, 0); - glTexCoord2f(0, 0); - glVertex3f(fx(x+0.5), fy(y-0.5), fz(z-0.5)); - glTexCoord2f(0, 1); - glVertex3f(fx(x+0.5), fy(y-0.5), fz(z+0.5)); - glTexCoord2f(1, 1); - glVertex3f(fx(x-0.5), fy(y-0.5), fz(z+0.5)); - glTexCoord2f(1, 0); - glVertex3f(fx(x-0.5), fy(y-0.5), fz(z-0.5)); - glEnd(); - glEndList(); - } -} - -/* It looks terrible... FIXME: any other ideas, maybe some anisotropic filtering? */ -/*#define MIPMAP*/ - -static void -init_gl(ModeInfo *mi) -{ - rubikblocks_conf *cp = &rubikblocks[MI_SCREEN(mi)]; -#ifdef MIPMAP - int status; -#endif - cp->wire = MI_IS_WIREFRAME(mi); - -# ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */ - cp->wire = 0; -# endif - - if(MI_IS_MONO(mi)) - tex = False; - if(cp->wire) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - return; - } - - glClearDepth(1.0); - glDrawBuffer(GL_BACK); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glShadeModel(GL_FLAT); - glDepthFunc(GL_LESS); - glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); - glLightfv(GL_LIGHT0, GL_POSITION, position0); - glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); - glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse); - glLightfv(GL_LIGHT1, GL_POSITION, position1); - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); - glEnable(GL_DEPTH_TEST); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHT1); - glEnable(GL_LIGHTING); - glEnable(GL_NORMALIZE); - glEnable(GL_COLOR_MATERIAL); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material_ambient); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material_diffuse); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_specular); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess); - if (!tex) return; - glEnable(GL_TEXTURE_2D); -#ifdef MIPMAP - clear_gl_error(); - status = gluBuild2DMipmaps(GL_TEXTURE_2D, 1, TEX_WIDTH, TEX_HEIGHT, - GL_LUMINANCE, GL_UNSIGNED_BYTE, cp->texture); - if (status) { - const char *s = (char *)gluErrorString(status); - fprintf (stderr, "%s: error mipmapping texture: %s\n", progname, (s?s:"(unknown)")); - exit (1); - } - check_gl_error("mipmapping"); -#else - glTexImage2D(GL_TEXTURE_2D, 0, 1, TEX_WIDTH, TEX_HEIGHT, - 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, cp->texture); -#endif - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -#ifdef MIPMAP - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); -#else - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -#endif -} - -static void -init_cp(rubikblocks_conf *cp) -{ - int i, j, k, m; - - cp->pause = True; - cp->t = 0.0; - cp->tmax = twait; - - for(i = -1, m = 0; i <= 1; i++) - for(j = -1; j <= 1; j++) - for(k = -1; k <= 1; k++) - { - cp->pieces[m].pos[0] = k; - cp->pieces[m].pos[1] = j; - cp->pieces[m].pos[2] = i; - cp->pieces[m].qr[0] = 1; - cp->pieces[m].qr[1] = 0; - cp->pieces[m].qr[2] = 0; - cp->pieces[m].qr[3] = 0; - m++; - } - - cp->rot = make_rotator(spin?spinspeed:0, spin?spinspeed:0, spin?spinspeed:0, - 0.1, wander?wspeed:0, True); - cp->trackball = gltrackball_init(True); - - if(rndstart) randomize(cp); -} - -/*************************************************************************/ - -ENTRYPOINT void -reshape_rubikblocks(ModeInfo *mi, int width, int height) -{ - rubikblocks_conf *cp = &rubikblocks[MI_SCREEN(mi)]; - int y = 0; - - if (width > height * 5) { /* tiny window: show middle */ - height = width; - y = -height/2; - } - if(!height) height = 1; - cp->ratio = (GLfloat)width/(GLfloat)height; - glViewport(0, y, (GLint) width, (GLint) height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(30.0, cp->ratio, 1.0, 100.0); - glMatrixMode(GL_MODELVIEW); - glClear(GL_COLOR_BUFFER_BIT); -} - -ENTRYPOINT void -init_rubikblocks(ModeInfo *mi) -{ - rubikblocks_conf *cp; - MI_INIT(mi, rubikblocks); - cp = &rubikblocks[MI_SCREEN(mi)]; - - if(tex) - make_texture(cp); - - if ((cp->glx_context = init_GL(mi)) != NULL) - { - init_gl(mi); - init_cp(cp); - init_lists(cp); - reshape_rubikblocks(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - } - else - { - MI_CLEARWINDOW(mi); - } -} - -ENTRYPOINT void -draw_rubikblocks(ModeInfo * mi) -{ - Display *display = MI_DISPLAY(mi); - Window window = MI_WINDOW(mi); - rubikblocks_conf *cp; - if (!rubikblocks) return; - cp = &rubikblocks[MI_SCREEN(mi)]; - MI_IS_DRAWN(mi) = True; - if (!cp->glx_context) return; - mi->polygon_count = 0; - glXMakeCurrent(display, window, *cp->glx_context); - if (!draw_main(mi, cp)) - { - MI_ABORT(mi); - return; - } - if (MI_IS_FPS(mi)) do_fps (mi); - glFlush(); - glXSwapBuffers(display, window); -} - -#ifndef STANDALONE -ENTRYPOINT void -change_rubikblocks(ModeInfo * mi) -{ - rubikblocks_conf *cp = &rubikblocks[MI_SCREEN(mi)]; - if (!cp->glx_context) return; - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *cp->glx_context); - init_gl(mi); -} -#endif /* !STANDALONE */ - -ENTRYPOINT Bool -rubikblocks_handle_event (ModeInfo *mi, XEvent *event) -{ - rubikblocks_conf *cp = &rubikblocks[MI_SCREEN(mi)]; - - if (gltrackball_event_handler (event, cp->trackball, - MI_WIDTH (mi), MI_HEIGHT (mi), - &cp->button_down)) - return True; - - return False; -} - - -ENTRYPOINT void -free_rubikblocks (ModeInfo *mi) -{ - rubikblocks_conf *cp = &rubikblocks[MI_SCREEN(mi)]; - if (!cp->glx_context) return; - glXMakeCurrent (MI_DISPLAY(mi), MI_WINDOW(mi), *cp->glx_context); - if (cp->trackball) gltrackball_free (cp->trackball); - glDeleteLists (cp->list_base, 27); -} - - -XSCREENSAVER_MODULE ("RubikBlocks", rubikblocks) - -#endif |
