1 /* flipflop, Copyright (c) 2003 Kevin Ogden <kogden1@hotmail.com>
2 * (c) 2006 Sergio GutiƩrrez "Sergut" <sergut@gmail.com>
3 * (c) 2008 Andrew Galante <a.drew7@gmail.com>
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation. No representations are made about the suitability of this
10 * software for any purpose. It is provided "as is" without express or
14 * 2003 Kevin Odgen First version
15 * 2006 Sergio GutiƩrrez "Sergut" Made several parameters dynamic and selectable
16 * from the command line: size of the board,
17 * rotation speed and number of free squares; also
18 * added the "sticks" mode.
19 * 2008 Andrew Galante Added -textured option: textures the board with
20 * an image which gets scrambled as the tiles move
24 #define DEF_MODE "tiles" /* Default mode (options: "tiles", "sticks") */
25 #define DEF_SIZEX "9" /* Default width of the board */
26 #define DEF_SIZEY "9" /* Default length of the board */
28 #define DEF_BOARD_SIZE "0" /* "0" means "no value selected by user". It is changed */
29 #define DEF_NUMSQUARES "0" /* in function init_flipflop() to its correct value (that */
30 #define DEF_FREESQUARES "0" /* is a function of the size of the board and the mode)*/
32 #define DEF_SPIN "0.1" /* Default angular velocity: PI/10 rads/s */
34 #define DEF_TEXTURED "False" /* Default: do not grab an image for texturing */
36 #define DEF_STICK_THICK 54 /* Thickness for the sticks mode (over 100) */
37 #define DEF_STICK_RATIO 80 /* Ratio of sticks/total squares (over 100) */
38 #define DEF_TILE_THICK 4 /* Thickness for the tiles mode (over 100) */
39 #define DEF_TILE_RATIO 95 /* Ratio of tiles/total squares (over 100) */
42 #define DEFAULTS "*delay: 20000 \n" \
43 "*showFPS: False \n" \
44 "*wireframe: False \n"
46 # define refresh_flipflop 0
47 # include "xlockmore.h"
51 #endif /* STANDALONE */
55 #include "gltrackball.h"
58 #define countof(x) (sizeof((x))/sizeof((*x)))
60 static XrmOptionDescRec opts[] = {
61 {"-sticks", ".mode", XrmoptionNoArg, "sticks"},
62 {"-tiles", ".mode", XrmoptionNoArg, "tiles" },
63 {"-mode", ".mode", XrmoptionSepArg, 0 },
64 {"-size", ".size", XrmoptionSepArg, 0 },
65 {"-size-x", ".sizex", XrmoptionSepArg, 0 },
66 {"-size-y", ".sizey", XrmoptionSepArg, 0 },
67 {"-count", ".numsquares", XrmoptionSepArg, 0 },
68 {"-free", ".freesquares", XrmoptionSepArg, 0 },
69 {"-spin", ".spin", XrmoptionSepArg, 0 },
70 {"-texture", ".textured", XrmoptionNoArg, "True" },
71 {"+texture", ".textured", XrmoptionNoArg, "False" },
74 static int wire, clearbits;
75 static int board_x_size, board_y_size, board_avg_size;
76 static int numsquares, freesquares;
77 static float half_thick;
79 static char* flipflopmode_str="tiles";
82 static argtype vars[] = {
83 { &flipflopmode_str, "mode", "Mode", DEF_MODE, t_String},
84 { &board_avg_size, "size", "Integer", DEF_BOARD_SIZE, t_Int},
85 { &board_x_size, "sizex", "Integer", DEF_SIZEX, t_Int},
86 { &board_y_size, "sizey", "Integer", DEF_SIZEY, t_Int},
87 { &numsquares, "numsquares", "Integer", DEF_NUMSQUARES, t_Int},
88 { &freesquares, "freesquares", "Integer", DEF_NUMSQUARES, t_Int},
89 { &spin, "spin", "Float", DEF_SPIN, t_Float},
90 { &textured, "textured", "Bool", DEF_TEXTURED, t_Bool},
93 ENTRYPOINT ModeSpecOpt flipflop_opts = {countof(opts), opts, countof(vars), vars, NULL};
96 ModStruct flipflop_description =
97 {"flipflop", "init_flipflop", "draw_flipflop", "release_flipflop",
98 "draw_flipflop", "init_flipflop", NULL, &flipflop_opts,
99 1000, 1, 2, 1, 4, 1.0, "",
100 "Flipflop", 0, NULL};
102 #endif /* USE_MODULES */
105 /* array specifying which squares are where (to avoid collisions) */
106 /* -1 means empty otherwise integer represents square index 0 - n-1 */
107 /* occupied[x*board_y_size+y] is the tile [x][y] (i.e. that starts at column x and row y)*/
108 int *occupied; /* size: size_x * size_y */
109 /* an array of xpositions of the squares */
110 int *xpos; /* size: numsquares */
111 /* array of y positions of the squares */
112 int *ypos; /* size: numsquares */
113 /* integer representing the direction of movement of a square */
114 int *direction; /* 0 not, 1 x+, 2 y+, 3 x-, 4 y-*/ /* size: numsquares */
115 /* angle of moving square (during a flip) */
116 float *angle; /* size: numsquares */
117 /* array of colors for a square (RGB) */
118 /* eg. color[ 3*3 + 0 ] is the red component of square 3 */
119 /* eg. color[ 4*3 + 1 ] is the green component of square 4 */
120 /* eg. color[ 5*3 + 2 ] is the blue component of square 5 */
121 /* ^-- n is the number of square */
122 float *color; /* size: numsquares * 3 */
123 /* array of texcoords for each square */
124 /* tex[ n*4 + 0 ] is x texture coordinate of square n's left side */
125 /* tex[ n*4 + 1 ] is y texture coordinate of square n's top side */
126 /* tex[ n*4 + 2 ] is x texture coordinate of square n's right side */
127 /* tex[ n*4 + 3 ] is y texture coordinate of square n's bottom side */
128 float *tex; /* size: numsquares * 4 */
132 GLXContext *glx_context;
134 trackball_state *trackball;
139 float theta; /* angle of rotation of the board */
140 float flipspeed; /* amount of flip; 1 is a entire flip */
141 float reldist; /* relative distace of camera from center */
142 float energy; /* likelyhood that a square will attempt to move */
144 /* texture rectangle */
150 /* id of texture in use */
160 static Flipflopcreen *qs = NULL;
162 #include "grab-ximage.h"
164 static void randsheet_create( randsheet *rs );
165 static void randsheet_initialize( randsheet *rs );
166 static void randsheet_free( randsheet *rs );
167 static int randsheet_new_move( randsheet* rs );
168 static void randsheet_move( randsheet *rs, float rot );
169 static int randsheet_draw( randsheet *rs );
170 static void setup_lights(void);
171 static int drawBoard(Flipflopcreen *);
172 static int display(Flipflopcreen *c);
173 static int draw_sheet(float *tex);
176 /* configure lighting */
180 /* GLfloat position0[] = { board_avg_size*0.5, board_avg_size*0.1, board_avg_size*0.5, 1.0 }; */
182 /* GLfloat position0[] = { -board_avg_size*0.5, 0.2*board_avg_size, -board_avg_size*0.5, 1.0 }; */
183 GLfloat position0[4];
185 position0[1] = board_avg_size*0.3;
191 glEnable(GL_LIGHTING);
192 glLightfv(GL_LIGHT0, GL_POSITION, position0);
197 flipflop_handle_event (ModeInfo *mi, XEvent *event)
199 Flipflopcreen *c = &qs[MI_SCREEN(mi)];
201 if (event->xany.type == ButtonPress &&
202 event->xbutton.button == Button1)
204 c->button_down_p = True;
205 gltrackball_start (c->trackball,
206 event->xbutton.x, event->xbutton.y,
207 MI_WIDTH (mi), MI_HEIGHT (mi));
210 else if (event->xany.type == ButtonRelease &&
211 event->xbutton.button == Button1)
213 c->button_down_p = False;
216 else if (event->xany.type == ButtonPress &&
217 (event->xbutton.button == Button4 ||
218 event->xbutton.button == Button5 ||
219 event->xbutton.button == Button6 ||
220 event->xbutton.button == Button7))
222 gltrackball_mousewheel (c->trackball, event->xbutton.button, 5,
223 !event->xbutton.state);
226 else if (event->xany.type == MotionNotify &&
229 gltrackball_track (c->trackball,
230 event->xmotion.x, event->xmotion.y,
231 MI_WIDTH (mi), MI_HEIGHT (mi));
240 drawBoard(Flipflopcreen *c)
243 for( i=0; i < (c->energy) ; i++ ) {
244 randsheet_new_move( c->sheet );
246 randsheet_move( c->sheet, c->flipspeed * 3.14159 );
247 return randsheet_draw( c->sheet );
252 display(Flipflopcreen *c)
254 GLfloat amb[] = { 0.8, 0.8, 0.8, 1.0 };
259 glMatrixMode(GL_MODELVIEW);
262 glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.2);
263 glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.15/board_avg_size );
264 glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.15/board_avg_size );
265 glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
268 glRotatef(current_device_rotation(), 0, 0, 1);
270 /** setup perspectif */
271 glTranslatef(0.0, 0.0, -c->reldist*board_avg_size);
272 glRotatef(22.5, 1.0, 0.0, 0.0);
273 gltrackball_rotate (c->trackball);
274 glRotatef(c->theta*100, 0.0, 1.0, 0.0);
275 glTranslatef(-0.5*board_x_size, 0.0, -0.5*board_y_size); /* Center the board */
279 glBindTexture(GL_TEXTURE_2D, c->texid);
281 polys = drawBoard(c);
283 if (!c->button_down_p) {
284 c->theta += .01 * spin;
291 reshape_flipflop(ModeInfo *mi, int width, int height)
293 GLfloat h = (GLfloat) height / (GLfloat) width;
294 glViewport(0,0, width, height);
295 glMatrixMode(GL_PROJECTION);
297 gluPerspective(45, 1/h, 1.0, 300.0);
298 glMatrixMode(GL_MODELVIEW);
302 image_loaded_cb (const char *filename, XRectangle *geometry,
303 int image_width, int image_height,
304 int texture_width, int texture_height,
307 Flipflopcreen *c = (Flipflopcreen *)closure;
310 randsheet *rs = c->sheet;
312 c->tex_x = (float)geometry->x / (float)texture_width;
313 c->tex_y = (float)geometry->y / (float)texture_height;
314 c->tex_width = (float)geometry->width / (float)texture_width;
315 c->tex_height = (float)geometry->height / (float)texture_height;
317 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
318 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
319 (c->mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR));
321 if(c->anisotropic >= 1)
322 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, c->anisotropic);
324 glEnable(GL_TEXTURE_2D);
326 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
328 for(i = 0; i < board_x_size && index < numsquares; i++)
329 for(j = 0; j < board_y_size && index < numsquares; j++)
331 /* arrange squares to form loaded image */
332 rs->tex[ index*4 + 0 ] = c->tex_x + c->tex_width / board_x_size * (i + 0);
333 rs->tex[ index*4 + 1 ] = c->tex_y + c->tex_height / board_y_size * (j + 1);
334 rs->tex[ index*4 + 2 ] = c->tex_x + c->tex_width / board_x_size * (i + 1);
335 rs->tex[ index*4 + 3 ] = c->tex_y + c->tex_height / board_y_size * (j + 0);
336 rs->color[ index*3 + 0 ] = 1;
337 rs->color[ index*3 + 1 ] = 1;
338 rs->color[ index*3 + 2 ] = 1;
342 c->got_texture = True;
346 get_texture(ModeInfo *modeinfo)
348 Flipflopcreen *c = &qs[MI_SCREEN(modeinfo)];
350 c->got_texture = False;
352 load_texture_async (modeinfo->xgwa.screen, modeinfo->window,
353 *c->glx_context, 0, 0, c->mipmap, c->texid,
358 init_flipflop(ModeInfo *mi)
363 if (MI_IS_WIREFRAME(mi)) textured = 0;
365 /* Set all constants to their correct values */
366 if (board_avg_size != 0) { /* general size specified by user */
367 board_x_size = board_avg_size;
368 board_y_size = board_avg_size;
370 board_avg_size = (board_x_size + board_y_size) / 2;
372 if ((numsquares == 0) && (freesquares != 0)) {
373 numsquares = board_x_size * board_y_size - freesquares;
375 if (strcmp(flipflopmode_str, "tiles")) {
376 textured = 0; /* textures look dumb in stick mode */
377 half_thick = 1.0 * DEF_STICK_THICK / 100.0;
378 if (numsquares == 0) { /* No value defined by user */
379 numsquares = board_x_size * board_y_size * DEF_STICK_RATIO / 100;
382 half_thick = 1.0 * DEF_TILE_THICK / 100.0;
383 if (numsquares == 0) { /* No value defined by user */
384 numsquares = board_x_size * board_y_size * DEF_TILE_RATIO/ 100;;
387 if (board_avg_size < 2) {
388 fprintf (stderr,"%s: the board must be at least 2x2.\n", progname);
391 if ((board_x_size < 1) || (board_y_size < 1) || (numsquares < 1)) {
392 fprintf (stderr,"%s: the number of elements ('-count') and the dimensions of the board ('-size-x', '-size-y') must be positive integers.\n", progname);
395 if (board_x_size * board_y_size <= numsquares) {
396 fprintf (stderr,"%s: the number of elements ('-count') that you specified is too big \n for the dimensions of the board ('-size-x', '-size-y'). Nothing will move.\n", progname);
399 screen = MI_SCREEN(mi);
400 wire = MI_IS_WIREFRAME(mi);
403 !(qs = (Flipflopcreen *) calloc(MI_NUM_SCREENS(mi), sizeof(Flipflopcreen))))
407 c->window = MI_WINDOW(mi);
408 c->trackball = gltrackball_init ();
414 if((c->glx_context = init_GL(mi)))
415 reshape_flipflop(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
419 /* At this point, all the constants have already been set, */
420 /* so we can create the board */
421 c->sheet = (randsheet*) malloc(sizeof(randsheet));
422 randsheet_create( c->sheet );
424 clearbits = GL_COLOR_BUFFER_BIT;
426 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
427 glEnable(GL_COLOR_MATERIAL);
430 glEnable(GL_DEPTH_TEST);
431 clearbits |= GL_DEPTH_BUFFER_BIT;
432 glEnable(GL_CULL_FACE);
435 randsheet_initialize( c->sheet );
437 /* check for anisotropic filtering */
438 if(strstr((char *)glGetString(GL_EXTENSIONS),
439 "GL_EXT_texture_filter_anisotropic"))
440 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &c->anisotropic);
444 /* allocate a new texture and get it */
445 glGenTextures(1, &c->texid);
451 draw_flipflop(ModeInfo *mi)
453 Flipflopcreen *c = &qs[MI_SCREEN(mi)];
454 Window w = MI_WINDOW(mi);
455 Display *disp = MI_DISPLAY(mi);
457 if(!c->glx_context || (textured && !c->got_texture))
460 glXMakeCurrent(disp, w, *(c->glx_context));
462 mi->polygon_count = display(c);
469 glXSwapBuffers(disp, w);
475 release_flipflop(ModeInfo *mi)
480 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
482 Flipflopcreen *c = &qs[MI_SCREEN(mi)];
486 randsheet_free(c->sheet);
498 /*** ADDED RANDSHEET FUNCTIONS ***/
501 draw_sheet(float *tex)
504 glBegin( wire ? GL_LINE_LOOP : GL_QUADS );
506 glNormal3f( 0, -1, 0 );
507 glTexCoord2f(tex[0], tex[3]);
508 glVertex3f( half_thick, -half_thick, half_thick );
509 glTexCoord2f(tex[2], tex[3]);
510 glVertex3f( 1-half_thick, -half_thick, half_thick );
511 glTexCoord2f(tex[2], tex[1]);
512 glVertex3f( 1-half_thick, -half_thick, 1-half_thick);
513 glTexCoord2f(tex[0], tex[1]);
514 glVertex3f( half_thick, -half_thick, 1-half_thick );
517 if (wire) { glEnd(); glBegin (GL_LINE_LOOP); }
520 glNormal3f( 0, 1, 0 );
521 glTexCoord2f(tex[0], tex[1]);
522 glVertex3f( half_thick, half_thick, 1-half_thick );
523 glTexCoord2f(tex[2], tex[1]);
524 glVertex3f( 1-half_thick, half_thick, 1-half_thick);
525 glTexCoord2f(tex[2], tex[3]);
526 glVertex3f( 1-half_thick, half_thick, half_thick );
527 glTexCoord2f(tex[0], tex[3]);
528 glVertex3f( half_thick, half_thick, half_thick );
531 if (wire) { glEnd(); return polys; }
533 /* 4 edges!!! weee.... */
534 glNormal3f( 0, 0, -1 );
535 glTexCoord2f(tex[0], tex[3]);
536 glVertex3f( half_thick, half_thick, half_thick );
537 glTexCoord2f(tex[2], tex[3]);
538 glVertex3f( 1-half_thick, half_thick, half_thick );
539 glTexCoord2f(tex[2], tex[3]);
540 glVertex3f( 1-half_thick, -half_thick, half_thick );
541 glTexCoord2f(tex[0], tex[3]);
542 glVertex3f( half_thick, -half_thick, half_thick );
544 glNormal3f( 0, 0, 1 );
545 glTexCoord2f(tex[0], tex[1]);
546 glVertex3f( half_thick, half_thick, 1-half_thick );
547 glTexCoord2f(tex[0], tex[1]);
548 glVertex3f( half_thick, -half_thick, 1-half_thick );
549 glTexCoord2f(tex[2], tex[1]);
550 glVertex3f( 1-half_thick, -half_thick, 1-half_thick );
551 glTexCoord2f(tex[2], tex[1]);
552 glVertex3f( 1-half_thick, half_thick, 1-half_thick );
554 glNormal3f( 1, 0, 0 );
555 glTexCoord2f(tex[2], tex[1]);
556 glVertex3f( 1-half_thick, half_thick, 1-half_thick );
557 glTexCoord2f(tex[2], tex[1]);
558 glVertex3f( 1-half_thick, -half_thick, 1-half_thick );
559 glTexCoord2f(tex[2], tex[3]);
560 glVertex3f( 1-half_thick, -half_thick, half_thick );
561 glTexCoord2f(tex[2], tex[3]);
562 glVertex3f( 1-half_thick, half_thick, half_thick );
564 glNormal3f( -1, 0, 0 );
565 glTexCoord2f(tex[0], tex[1]);
566 glVertex3f( half_thick, half_thick, 1-half_thick );
567 glTexCoord2f(tex[0], tex[3]);
568 glVertex3f( half_thick, half_thick, half_thick );
569 glTexCoord2f(tex[0], tex[3]);
570 glVertex3f( half_thick, -half_thick, half_thick );
571 glTexCoord2f(tex[0], tex[1]);
572 glVertex3f( half_thick, -half_thick, 1-half_thick );
579 /* Reserve memory for the randsheet */
581 randsheet_create( randsheet *rs )
583 rs -> occupied = (int*) malloc(board_x_size*board_y_size * sizeof(int));
584 rs -> xpos = (int*) malloc(numsquares * sizeof(int));
585 rs -> ypos = (int*) malloc(numsquares * sizeof(int));
586 rs -> direction = (int*) malloc(numsquares * sizeof(int));
587 rs -> angle = (float*) malloc(numsquares * sizeof(float));
588 rs -> color = (float*) malloc(numsquares*3 * sizeof(float));
589 rs -> tex = (float*) malloc(numsquares*4 * sizeof(float));
592 /* Free reserved memory for the randsheet */
594 randsheet_free( randsheet *rs )
606 randsheet_initialize( randsheet *rs )
610 /* put the moving sheets on the board */
611 for( i = 0; i < board_x_size; i++ )
613 for( j = 0; j < board_y_size; j++ )
615 /* initially fill up a corner with the moving squares */
616 if( index < numsquares )
618 rs->occupied[ i * board_y_size + j ] = index;
619 rs->xpos[ index ] = i;
620 rs->ypos[ index ] = j;
621 /* have the square colors start out as a pattern */
622 rs->color[ index*3 + 0 ] = ((i+j)%3 == 0)||((i+j+1)%3 == 0);
623 rs->color[ index*3 + 1 ] = ((i+j+1)%3 == 0);
624 rs->color[ index*3 + 2 ] = ((i+j+2)%3 == 0);
627 /* leave everything else empty*/
630 rs->occupied[ i * board_y_size + j ] = -1;
634 /* initially everything is at rest */
635 for( i=0; i<numsquares; i++ )
637 rs->direction[ i ] = 0;
642 /* Pick and random square and direction and try to move it. */
643 /* May not actually move anything, just attempt a random move. */
644 /* Returns true if move was sucessful. */
645 /* This could probably be implemented faster in a dequeue */
646 /* to avoid trying to move a square which is already moving */
647 /* but speed is most likely bottlenecked by rendering anyway... */
649 randsheet_new_move( randsheet* rs )
653 /* pick a random square */
654 num = random( ) % numsquares;
657 /* pick a random direction */
658 dir = ( random( )% 4 ) + 1;
660 if( rs->direction[ num ] == 0 )
666 if( ( i + 1 ) < board_x_size )
668 if( rs->occupied[ (i + 1) * board_y_size + j ] == -1 )
670 rs->direction[ num ] = dir;
671 rs->occupied[ (i + 1) * board_y_size + j ] = num;
672 rs->occupied[ i * board_y_size + j ] = -1;
680 if( ( j + 1 ) < board_y_size )
682 if( rs->occupied[ i * board_y_size + (j + 1) ] == -1 )
684 rs->direction[ num ] = dir;
685 rs->occupied[ i * board_y_size + (j + 1) ] = num;
686 rs->occupied[ i * board_y_size + j ] = -1;
696 if( rs->occupied[ (i - 1) * board_y_size + j ] == -1 )
698 rs->direction[ num ] = dir;
699 rs->occupied[ (i - 1) * board_y_size + j ] = num;
700 rs->occupied[ i * board_y_size + j ] = -1;
710 if( rs->occupied[ i * board_y_size + (j - 1) ] == -1 )
712 rs->direction[ num ] = dir;
713 rs->occupied[ i * board_y_size + (j - 1) ] = num;
714 rs->occupied[ i * board_y_size + j ] = -1;
727 /* move a single frame. */
728 /* Pass in the angle in rads the square rotates in a frame. */
730 randsheet_move( randsheet *rs, float rot )
734 for( index = 0 ; index < numsquares; index++ )
736 switch( rs->direction[ index ] )
743 if( textured && rs->angle[ index ] == 0 )
745 tmp = rs->tex[ index * 4 + 0 ];
746 rs->tex[ index * 4 + 0 ] = rs->tex[ index * 4 + 2 ];
747 rs->tex[ index * 4 + 2 ] = tmp;
749 rs->angle[ index ] += rot;
750 /* check to see if we have finished moving */
751 if( rs->angle[ index ] >= M_PI )
753 rs->xpos[ index ] += 1;
754 rs->direction[ index ] = 0;
755 rs->angle[ index ] = 0;
760 if( textured && rs->angle[ index ] == 0 )
762 tmp = rs->tex[ index * 4 + 1 ];
763 rs->tex[ index * 4 + 1 ] = rs->tex[ index * 4 + 3 ];
764 rs->tex[ index * 4 + 3 ] = tmp;
766 rs->angle[ index ] += rot;
767 /* check to see if we have finished moving */
768 if( rs->angle[ index ] >= M_PI )
770 rs->ypos[ index ] += 1;
771 rs->direction[ index ] = 0;
772 rs->angle[ index ] = 0;
777 rs->angle[ index ] += rot;
778 /* check to see if we have finished moving */
779 if( rs->angle[ index ] >= M_PI )
781 rs->xpos[ index ] -= 1;
782 rs->direction[ index ] = 0;
783 rs->angle[ index ] = 0;
786 tmp = rs->tex[ index * 4 + 0 ];
787 rs->tex[ index * 4 + 0 ] = rs->tex[ index * 4 + 2 ];
788 rs->tex[ index * 4 + 2 ] = tmp;
794 rs->angle[ index ] += rot;
795 /* check to see if we have finished moving */
796 if( rs->angle[ index ] >= M_PI )
798 rs->ypos[ index ] -= 1;
799 rs->direction[ index ] = 0;
800 rs->angle[ index ] = 0;
803 tmp = rs->tex[ index * 4 + 1 ];
804 rs->tex[ index * 4 + 1 ] = rs->tex[ index * 4 + 3 ];
805 rs->tex[ index * 4 + 3 ] = tmp;
816 /* draw all the moving squares */
818 randsheet_draw( randsheet *rs )
823 /* for all moving squares ... */
824 for( index = 0; index < numsquares; index++ )
827 glColor3f( rs->color[ index*3 + 0 ],
828 rs->color[ index*3 + 1 ],
829 rs->color[ index*3 + 2 ] );
830 /* find x and y position */
831 i = rs->xpos[ index ];
832 j = rs->ypos[ index ];
834 switch( rs->direction[ index ] )
840 glTranslatef( i, 0, j );
843 glTranslatef( i+1, 0, j );
844 glRotatef( 180 - rs->angle[ index ]*180/M_PI, 0, 0, 1 );
848 glTranslatef( i, 0, j+1 );
849 glRotatef( 180 - rs->angle[ index ]*180/M_PI, -1, 0, 0 );
853 glTranslatef( i, 0, j );
854 glRotatef( rs->angle[ index ]*180/M_PI, 0, 0, 1 );
857 glTranslatef( i, 0, j );
858 glRotatef( rs->angle[ index ]*180/M_PI, -1, 0, 0 );
863 polys += draw_sheet( rs->tex + index*4 );
870 /**** END RANDSHEET_BAK FUNCTIONS ***/
872 XSCREENSAVER_MODULE ("FlipFlop", flipflop)