X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fflipflop.c;h=f38385e4072026d0b42925876fa5b5cee3bf20c4;hp=af671ca802aa3f52899c153b2ea1f91de5accd95;hb=07faf451b99879183ed7e909e43a0e065be1ee7f;hpb=2d04c4f22466851aedb6ed0f2919d148f726b889 diff --git a/hacks/glx/flipflop.c b/hacks/glx/flipflop.c index af671ca8..f38385e4 100644 --- a/hacks/glx/flipflop.c +++ b/hacks/glx/flipflop.c @@ -1,4 +1,5 @@ /* flipflop, Copyright (c) 2003 Kevin Ogden + * (c) 2006 Sergio GutiƩrrez "Sergut" * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -7,119 +8,136 @@ * documentation. No representations are made about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. + * + * + * 2003 Kevin Odgen First version + * 2006 Sergio GutiƩrrez "Sergut" Made several parameters dynamic and selectable + * from the command line: size of the board, + * rotation speed and number of free squares; also + * added the "sticks" mode. + * */ -#include +#define DEF_FLIPFLOP_MODE "tiles" /* Default mode (options: "tiles", "sticks") */ +#define DEF_BOARD_X_SIZE "9" /* Default width of the board */ +#define DEF_BOARD_Y_SIZE "9" /* Default length of the board */ -#include -#include -#include -#include +#define DEF_BOARD_SIZE "0" /* "0" means "no value selected by user". It is changed */ +#define DEF_NUMSQUARES "0" /* in function init_flipflop() to its correct value (that */ +#define DEF_FREESQUARES "0" /* is a function of the size of the board and the mode)*/ -#define BOARDSIZE 9 -#define NUMSQUARES 76 -#define HALFTHICK 0.04 +#define DEF_SPIN "0.1" /* Default angular velocity: PI/10 rads/s */ + +#define DEF_STICK_THICK 54 /* Thickness for the sticks mode (over 100) */ +#define DEF_STICK_RATIO 80 /* Ratio of sticks/total squares (over 100) */ +#define DEF_TILE_THICK 4 /* Thickness for the tiles mode (over 100) */ +#define DEF_TILE_RATIO 95 /* Ratio of tiles/total squares (over 100) */ #ifdef STANDALONE -# define PROGCLASS "Flipflop" -# define HACK_INIT init_flipflop -# define HACK_DRAW draw_flipflop -# define HACK_RESHAPE reshape_flipflop -# define HACK_HANDLE_EVENT flipflop_handle_event -# define EVENT_MASK PointerMotionMask -# define flipflop_opts xlockmore_opts - -#define DEFAULTS "*delay: 20000 \n" \ - "*showFPS: False \n" \ - "*wireframe: False \n" +#define DEFAULTS "*delay: 20000 \n" \ + "*showFPS: False \n" \ + "*wireframe: False \n" +# define refresh_flipflop 0 # include "xlockmore.h" #else # include "xlock.h" -#endif +#endif /* STANDALONE */ #ifdef USE_GL -#include #include "gltrackball.h" #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) static XrmOptionDescRec opts[] = { - {"+rotate", ".flipflop.rotate", XrmoptionNoArg, "false" }, - {"-rotate", ".flipflop.rotate", XrmoptionNoArg, "true" }, + {"-sticks", ".mode", XrmoptionNoArg, "sticks"}, + {"-tiles", ".mode", XrmoptionNoArg, "tiles" }, + {"-mode", ".mode", XrmoptionSepArg, 0 }, + {"-size", ".size", XrmoptionSepArg, 0 }, + {"-size-x", ".size_x", XrmoptionSepArg, 0 }, + {"-size-y", ".size_y", XrmoptionSepArg, 0 }, + {"-count", ".numsquares", XrmoptionSepArg, 0 }, + {"-free", ".freesquares", XrmoptionSepArg, 0 }, + {"-spin", ".spin", XrmoptionSepArg, 0 }, }; - - -static int rotate, wire, clearbits; +static int wire, clearbits; +static int board_x_size, board_y_size, board_avg_size; +static int numsquares, freesquares; +static float half_thick; +static float spin; +static char* flipflopmode_str="tiles"; static argtype vars[] = { - { &rotate, "rotate", "Rotate", "True", t_Bool}, + { &flipflopmode_str, "mode", "Mode", DEF_FLIPFLOP_MODE, t_String}, + { &board_avg_size, "size", "Integer", DEF_BOARD_SIZE, t_Int}, + { &board_x_size, "size_x", "Integer", DEF_BOARD_X_SIZE, t_Int}, + { &board_y_size, "size_y", "Integer", DEF_BOARD_Y_SIZE, t_Int}, + { &numsquares, "numsquares", "Integer", DEF_NUMSQUARES, t_Int}, + { &freesquares, "freesquares", "Integer", DEF_NUMSQUARES, t_Int}, + { &spin, "spin", "Float", DEF_SPIN, t_Float}, }; -ModeSpecOpt flipflop_opts = {countof(opts), opts, countof(vars), vars, NULL}; +ENTRYPOINT ModeSpecOpt flipflop_opts = {countof(opts), opts, countof(vars), vars, NULL}; #ifdef USE_MODULES ModStruct flipflop_description = -{"flipflop", "init_flipflop", "draw_flipflop", "release_flipflop", - "draw_flipflop", "init_flipflop", NULL, &flipflop_opts, - 1000, 1, 2, 1, 4, 1.0, "", - "Flipflop", 0, NULL}; + {"flipflop", "init_flipflop", "draw_flipflop", "release_flipflop", + "draw_flipflop", "init_flipflop", NULL, &flipflop_opts, + 1000, 1, 2, 1, 4, 1.0, "", + "Flipflop", 0, NULL}; -#endif +#endif /* USE_MODULES */ typedef struct { - GLXContext *glx_context; - Window window; - trackball_state *trackball; - Bool button_down_p; -} Flipflopcreen; + /* array specifying which squares are where (to avoid collisions) */ + /* -1 means empty otherwise integer represents square index 0 - n-1 */ + /* occupied[x*board_y_size+y] is the tile [x][y] (i.e. that starts at column x and row y)*/ + int *occupied; /* size: size_x * size_y */ + /* an array of xpositions of the squares */ + int *xpos; /* size: numsquares */ + /* array of y positions of the squares */ + int *ypos; /* size: numsquares */ + /* integer representing the direction of movement of a square */ + int *direction; /* 0 not, 1 x+, 2 y+, 3 x-, 4 y-*/ /* size: numsquares */ + /* angle of moving square (during a flip) */ + float *angle; /* size: numsquares */ + /* array of colors for a square (RGB) */ + /* eg. color[ 3*3 + 0 ] is the red component of square 3 */ + /* eg. color[ 4*3 + 1 ] is the green component of square 4 */ + /* eg. color[ 5*3 + 2 ] is the blue component of square 5 */ + /* ^-- n is the number of square */ + float *color; /* size: numsquares * 3 */ +} randsheet; -static Flipflopcreen *qs = NULL; +typedef struct { + GLXContext *glx_context; + Window window; + trackball_state *trackball; + Bool button_down_p; -typedef struct{ - /* 2D array specifying which squares are where (to avoid collisions) */ - /* -1 means empty otherwise integer represents square index 0 - n-1 */ - int occupied[ BOARDSIZE ][ BOARDSIZE ]; - /* an array of xpositions of the squares */ - int xpos[ NUMSQUARES ]; - /* array of y positions of the squares */ - int ypos[ NUMSQUARES ]; - /* integer representing the direction of movement of a square */ - int direction[ NUMSQUARES ]; /* 0 not, 1 x+, 2 y+, 3 x-, 4 y-*/ - /* angle of moving square (during a flip) */ - float angle[ NUMSQUARES ]; - /* array of colors for a square. rgb */ - /* eg. color[ 4 ][ 0 ] is the red component of square 4 */ - /* eg. color[ 5 ][ 2 ] is the blue component of square 5 */ - float color[ NUMSQUARES ][ 3 ]; - /* n is the number of square */ -} randsheet; - - -/*** ADDED RANDSHEET VARS ***/ - -static randsheet MyRandSheet; - -static double theta = 0.0; -/* amount which the square flips. 1 is a entire flip */ -static float flipspeed = 0.03; -/* relative distace of camera from center */ -static float reldist = 1; -/* likelehood a square will attempt a move */ -static float energy = 40; + randsheet *sheet; + float theta; /* angle of rotation of the board */ + float flipspeed; /* amount of flip; 1 is a entire flip */ + float reldist; /* relative distace of camera from center */ + float energy; /* likelyhood that a square will attempt to move */ +} Flipflopcreen; + +static Flipflopcreen *qs = NULL; + +static void randsheet_create( randsheet *rs ); static void randsheet_initialize( randsheet *rs ); -static int randsheet_new_move( randsheet* rs ); -static int randsheet_new_move( randsheet* rs ); +static void randsheet_free( randsheet *rs ); +static int randsheet_new_move( randsheet* rs ); static void randsheet_move( randsheet *rs, float rot ); static void randsheet_draw( randsheet *rs ); static void setup_lights(void); -static void drawBoard(void); +static void drawBoard(Flipflopcreen *); static void display(Flipflopcreen *c); static void draw_sheet(void); @@ -128,179 +146,242 @@ static void draw_sheet(void); static void setup_lights(void) { -/* GLfloat position0[] = { BOARDSIZE*0.5, BOARDSIZE*0.1, BOARDSIZE*0.5, 1.0 }; */ + /* GLfloat position0[] = { board_avg_size*0.5, board_avg_size*0.1, board_avg_size*0.5, 1.0 }; */ -/* GLfloat position0[] = { -BOARDSIZE*0.5, 0.2*BOARDSIZE, -BOARDSIZE*0.5, 1.0 }; */ - GLfloat position0[] = { 0, BOARDSIZE*0.3, 0, 1.0 }; + /* GLfloat position0[] = { -board_avg_size*0.5, 0.2*board_avg_size, -board_avg_size*0.5, 1.0 }; */ + GLfloat position0[4]; + position0[0] = 0; + position0[1] = board_avg_size*0.3; + position0[2] = 0; + position0[3] = 1; - if (wire) return; + if (wire) return; - glEnable(GL_LIGHTING); - glLightfv(GL_LIGHT0, GL_POSITION, position0); - glEnable(GL_LIGHT0); - } + glEnable(GL_LIGHTING); + glLightfv(GL_LIGHT0, GL_POSITION, position0); + glEnable(GL_LIGHT0); +} -Bool +ENTRYPOINT Bool flipflop_handle_event (ModeInfo *mi, XEvent *event) { - Flipflopcreen *c = &qs[MI_SCREEN(mi)]; - - if (event->xany.type == ButtonPress && - event->xbutton.button == Button1) - { - c->button_down_p = True; - gltrackball_start (c->trackball, - event->xbutton.x, event->xbutton.y, - MI_WIDTH (mi), MI_HEIGHT (mi)); - return True; - } - else if (event->xany.type == ButtonRelease && - event->xbutton.button == Button1) - { - c->button_down_p = False; - return True; - } - else if (event->xany.type == ButtonPress && - (event->xbutton.button == Button4 || - event->xbutton.button == Button5)) - { - gltrackball_mousewheel (c->trackball, event->xbutton.button, 5, - !event->xbutton.state); - return True; - } - else if (event->xany.type == MotionNotify && - c->button_down_p) - { - gltrackball_track (c->trackball, - event->xmotion.x, event->xmotion.y, - MI_WIDTH (mi), MI_HEIGHT (mi)); - return True; - } - - return False; + Flipflopcreen *c = &qs[MI_SCREEN(mi)]; + + if (event->xany.type == ButtonPress && + event->xbutton.button == Button1) + { + c->button_down_p = True; + gltrackball_start (c->trackball, + event->xbutton.x, event->xbutton.y, + MI_WIDTH (mi), MI_HEIGHT (mi)); + return True; + } + else if (event->xany.type == ButtonRelease && + event->xbutton.button == Button1) + { + c->button_down_p = False; + return True; + } + else if (event->xany.type == ButtonPress && + (event->xbutton.button == Button4 || + event->xbutton.button == Button5)) + { + gltrackball_mousewheel (c->trackball, event->xbutton.button, 5, + !event->xbutton.state); + return True; + } + else if (event->xany.type == MotionNotify && + c->button_down_p) + { + gltrackball_track (c->trackball, + event->xmotion.x, event->xmotion.y, + MI_WIDTH (mi), MI_HEIGHT (mi)); + return True; + } + + return False; } /* draw board */ static void -drawBoard(void) +drawBoard(Flipflopcreen *c) { - int i; - for( i=0; i < (energy) ; i++ ) - randsheet_new_move( &MyRandSheet ); - randsheet_move( &MyRandSheet, flipspeed * 3.14159 ); - randsheet_draw( &MyRandSheet ); + int i; + for( i=0; i < (c->energy) ; i++ ) { + randsheet_new_move( c->sheet ); + } + randsheet_move( c->sheet, c->flipspeed * 3.14159 ); + randsheet_draw( c->sheet ); } static void display(Flipflopcreen *c) { - GLfloat amb[] = { 0.8, 0.8, 0.8, 1.0 }; + GLfloat amb[] = { 0.8, 0.8, 0.8, 1.0 }; - glClear(clearbits); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + glClear(clearbits); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); - glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.2); - glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.15/BOARDSIZE ); - glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.15/BOARDSIZE ); - glLightfv(GL_LIGHT0, GL_AMBIENT, amb); + glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.2); + glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.15/board_avg_size ); + glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.15/board_avg_size ); + glLightfv(GL_LIGHT0, GL_AMBIENT, amb); - /** setup perspectif */ - glTranslatef(0.0, 0.0, -reldist*BOARDSIZE); - glRotatef(22.5, 1.0, 0.0, 0.0); - gltrackball_rotate (c->trackball); - glRotatef(theta*100, 0.0, 1.0, 0.0); - glTranslatef(-0.5*BOARDSIZE, 0.0, -0.5*BOARDSIZE); + /** setup perspectif */ + glTranslatef(0.0, 0.0, -c->reldist*board_avg_size); + glRotatef(22.5, 1.0, 0.0, 0.0); + gltrackball_rotate (c->trackball); + glRotatef(c->theta*100, 0.0, 1.0, 0.0); + glTranslatef(-0.5*board_x_size, 0.0, -0.5*board_y_size); /* Center the board */ - drawBoard(); + drawBoard(c); - if (!c->button_down_p) - theta += .001; + if (!c->button_down_p) { + c->theta += .01 * spin; + } } -void +ENTRYPOINT void reshape_flipflop(ModeInfo *mi, int width, int height) { - GLfloat h = (GLfloat) height / (GLfloat) width; - glViewport(0,0, width, height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(45, 1/h, 1.0, 300.0); - glMatrixMode(GL_MODELVIEW); + GLfloat h = (GLfloat) height / (GLfloat) width; + glViewport(0,0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45, 1/h, 1.0, 300.0); + glMatrixMode(GL_MODELVIEW); } -void +ENTRYPOINT void init_flipflop(ModeInfo *mi) { - int screen = MI_SCREEN(mi); - Flipflopcreen *c; - wire = MI_IS_WIREFRAME(mi); + int screen; + Flipflopcreen *c; + + /* Set all constants to their correct values */ + if (board_avg_size != 0) { /* general size specified by user */ + board_x_size = board_avg_size; + board_y_size = board_avg_size; + } else { + board_avg_size = (board_x_size + board_y_size) / 2; + } + if ((numsquares == 0) && (freesquares != 0)) { + numsquares = board_x_size * board_y_size - freesquares; + } + if (strcmp(flipflopmode_str, "tiles")) { + half_thick = 1.0 * DEF_STICK_THICK / 100.0; + if (numsquares == 0) { /* No value defined by user */ + numsquares = board_x_size * board_y_size * DEF_STICK_RATIO / 100; + } + } else { + half_thick = 1.0 * DEF_TILE_THICK / 100.0; + if (numsquares == 0) { /* No value defined by user */ + numsquares = board_x_size * board_y_size * DEF_TILE_RATIO/ 100;; + } + } + if (board_avg_size < 2) { + fprintf (stderr,"%s: the board must be at least 2x2.\n", progname); + exit(1); + } + if ((board_x_size < 1) || (board_y_size < 1) || (numsquares < 1)) { + fprintf (stderr,"%s: the number of elements ('-count') and the dimensions of the board ('-size-x', '-size-y') must be positive integers.\n", progname); + exit(1); + } + if (board_x_size * board_y_size <= numsquares) { + 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); + } + + screen = MI_SCREEN(mi); + wire = MI_IS_WIREFRAME(mi); - if(!qs && - !(qs = (Flipflopcreen *) calloc(MI_NUM_SCREENS(mi), sizeof(Flipflopcreen)))) - return; + if(!qs && + !(qs = (Flipflopcreen *) calloc(MI_NUM_SCREENS(mi), sizeof(Flipflopcreen)))) + return; - c = &qs[screen]; - c->window = MI_WINDOW(mi); - c->trackball = gltrackball_init (); + c = &qs[screen]; + c->window = MI_WINDOW(mi); + c->trackball = gltrackball_init (); - if((c->glx_context = init_GL(mi))) - reshape_flipflop(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - else - MI_CLEARWINDOW(mi); + c->flipspeed = 0.03; + c->reldist = 1; + c->energy = 40; - glClearColor(0.0, 0.0, 0.0, 0.0); + if((c->glx_context = init_GL(mi))) + reshape_flipflop(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); + else + MI_CLEARWINDOW(mi); - clearbits = GL_COLOR_BUFFER_BIT; + /* At this point, all the constants have already been set, */ + /* so we can create the board */ + c->sheet = (randsheet*) malloc(sizeof(randsheet)); + randsheet_create( c->sheet ); - glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); - setup_lights(); + glClearColor(0.0, 0.0, 0.0, 0.0); - glEnable(GL_DEPTH_TEST); - clearbits |= GL_DEPTH_BUFFER_BIT; - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - randsheet_initialize( &MyRandSheet ); + clearbits = GL_COLOR_BUFFER_BIT; + glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + setup_lights(); + glEnable(GL_DEPTH_TEST); + clearbits |= GL_DEPTH_BUFFER_BIT; + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + randsheet_initialize( c->sheet ); } -void +ENTRYPOINT void draw_flipflop(ModeInfo *mi) { - Flipflopcreen *c = &qs[MI_SCREEN(mi)]; - Window w = MI_WINDOW(mi); - Display *disp = MI_DISPLAY(mi); + Flipflopcreen *c = &qs[MI_SCREEN(mi)]; + Window w = MI_WINDOW(mi); + Display *disp = MI_DISPLAY(mi); - if(!c->glx_context) - return; + if(!c->glx_context) + return; - glXMakeCurrent(disp, w, *(c->glx_context)); + glXMakeCurrent(disp, w, *(c->glx_context)); - display(c); + display(c); - if(mi->fps_p){ - do_fps(mi); - } + if(mi->fps_p){ + do_fps(mi); + } - glFinish(); - glXSwapBuffers(disp, w); + glFinish(); + glXSwapBuffers(disp, w); } -void +ENTRYPOINT void release_flipflop(ModeInfo *mi) { - if(qs) - free((void *) qs); + if(qs) { + int screen; - FreeAllGL(MI); + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + { + Flipflopcreen *c = &qs[MI_SCREEN(mi)]; + if (c->glx_context) + c->glx_context = 0; + if (c->sheet) { + randsheet_free(c->sheet); + free (c->sheet); + c->sheet = 0; + } + } + free(qs); + qs = 0; + } + + FreeAllGL(mi); } /*** ADDED RANDSHEET FUNCTIONS ***/ @@ -308,84 +389,108 @@ release_flipflop(ModeInfo *mi) static void draw_sheet(void) { - glBegin( wire ? GL_LINE_LOOP : GL_QUADS ); - - glNormal3f( 0, -1, 0 ); - glVertex3f( HALFTHICK, -HALFTHICK, HALFTHICK ); - glVertex3f( 1-HALFTHICK, -HALFTHICK, HALFTHICK ); - glVertex3f( 1-HALFTHICK, -HALFTHICK, 1-HALFTHICK); - glVertex3f( HALFTHICK, -HALFTHICK, 1-HALFTHICK ); - - if (wire) { glEnd(); glBegin (GL_LINE_LOOP); } - - /* back */ - glNormal3f( 0, 1, 0 ); - glVertex3f( HALFTHICK, HALFTHICK, 1-HALFTHICK ); - glVertex3f( 1-HALFTHICK, HALFTHICK, 1-HALFTHICK); - glVertex3f( 1-HALFTHICK, HALFTHICK, HALFTHICK ); - glVertex3f( HALFTHICK, HALFTHICK, HALFTHICK ); - - if (wire) { glEnd(); return; } - - /* 4 edges!!! weee.... */ - glNormal3f( 0, 0, -1 ); - glVertex3f( HALFTHICK, HALFTHICK, HALFTHICK ); - glVertex3f( 1-HALFTHICK, HALFTHICK, HALFTHICK ); - glVertex3f( 1-HALFTHICK, -HALFTHICK, HALFTHICK ); - glVertex3f( HALFTHICK, -HALFTHICK, HALFTHICK ); - glNormal3f( 0, 0, 1 ); - glVertex3f( HALFTHICK, HALFTHICK, 1-HALFTHICK ); - glVertex3f( HALFTHICK, -HALFTHICK, 1-HALFTHICK ); - glVertex3f( 1-HALFTHICK, -HALFTHICK, 1-HALFTHICK ); - glVertex3f( 1-HALFTHICK, HALFTHICK, 1-HALFTHICK ); - glNormal3f( 1, 0, 0 ); - glVertex3f( 1-HALFTHICK, HALFTHICK, 1-HALFTHICK ); - glVertex3f( 1-HALFTHICK, -HALFTHICK, 1-HALFTHICK ); - glVertex3f( 1-HALFTHICK, -HALFTHICK, HALFTHICK ); - glVertex3f( 1-HALFTHICK, HALFTHICK, HALFTHICK ); - glNormal3f( -1, 0, 0 ); - glVertex3f( HALFTHICK, HALFTHICK, 1-HALFTHICK ); - glVertex3f( HALFTHICK, HALFTHICK, HALFTHICK ); - glVertex3f( HALFTHICK, -HALFTHICK, HALFTHICK ); - glVertex3f( HALFTHICK, -HALFTHICK, 1-HALFTHICK ); - glEnd(); + glBegin( wire ? GL_LINE_LOOP : GL_QUADS ); + + glNormal3f( 0, -1, 0 ); + glVertex3f( half_thick, -half_thick, half_thick ); + glVertex3f( 1-half_thick, -half_thick, half_thick ); + glVertex3f( 1-half_thick, -half_thick, 1-half_thick); + glVertex3f( half_thick, -half_thick, 1-half_thick ); + + if (wire) { glEnd(); glBegin (GL_LINE_LOOP); } + + /* back */ + glNormal3f( 0, 1, 0 ); + glVertex3f( half_thick, half_thick, 1-half_thick ); + glVertex3f( 1-half_thick, half_thick, 1-half_thick); + glVertex3f( 1-half_thick, half_thick, half_thick ); + glVertex3f( half_thick, half_thick, half_thick ); + + if (wire) { glEnd(); return; } + + /* 4 edges!!! weee.... */ + glNormal3f( 0, 0, -1 ); + glVertex3f( half_thick, half_thick, half_thick ); + glVertex3f( 1-half_thick, half_thick, half_thick ); + glVertex3f( 1-half_thick, -half_thick, half_thick ); + glVertex3f( half_thick, -half_thick, half_thick ); + glNormal3f( 0, 0, 1 ); + glVertex3f( half_thick, half_thick, 1-half_thick ); + glVertex3f( half_thick, -half_thick, 1-half_thick ); + glVertex3f( 1-half_thick, -half_thick, 1-half_thick ); + glVertex3f( 1-half_thick, half_thick, 1-half_thick ); + glNormal3f( 1, 0, 0 ); + glVertex3f( 1-half_thick, half_thick, 1-half_thick ); + glVertex3f( 1-half_thick, -half_thick, 1-half_thick ); + glVertex3f( 1-half_thick, -half_thick, half_thick ); + glVertex3f( 1-half_thick, half_thick, half_thick ); + glNormal3f( -1, 0, 0 ); + glVertex3f( half_thick, half_thick, 1-half_thick ); + glVertex3f( half_thick, half_thick, half_thick ); + glVertex3f( half_thick, -half_thick, half_thick ); + glVertex3f( half_thick, -half_thick, 1-half_thick ); + glEnd(); +} + +/* Reserve memory for the randsheet */ +static void +randsheet_create( randsheet *rs ) +{ + rs -> occupied = (int*) malloc(board_x_size*board_y_size * sizeof(int)); + rs -> xpos = (int*) malloc(numsquares * sizeof(int)); + rs -> ypos = (int*) malloc(numsquares * sizeof(int)); + rs -> direction = (int*) malloc(numsquares * sizeof(int)); + rs -> angle = (float*) malloc(numsquares * sizeof(float)); + rs -> color = (float*) malloc(numsquares*3 * sizeof(float)); +} + +/* Free reserved memory for the randsheet */ +static void +randsheet_free( randsheet *rs ) +{ + free(rs->occupied); + free(rs->xpos); + free(rs->ypos); + free(rs->direction); + free(rs->angle); + free(rs->color); } static void randsheet_initialize( randsheet *rs ) { - int i, j, index; - index = 0; - /* put the moving sheets on the board */ - for( i = 0; i < BOARDSIZE; i++ ) - { - for( j = 0; j < BOARDSIZE; j++ ) - { - /* initially fill up a corner with the moving squares */ - if( index < NUMSQUARES ) - { - rs->occupied[ i ][ j ] = index; - rs->xpos[ index ] = i; - rs->ypos[ index ] = j; - /* have the square colors start out as a pattern */ - rs->color[ index ][ 0 ] = ((i+j)%3 == 0)||((i+j+1)%3 == 0); - rs->color[ index ][ 1 ] = ((i+j+1)%3 == 0); - rs->color[ index ][ 2 ] = ((i+j+2)%3 == 0); - ++index; - } - /* leave everything else empty*/ - else - { - rs->occupied[ i ][ j ] = -1; - } - } - } - /* initially everything is at rest */ - for( i=0; idirection[ i ] = 0; - rs->angle[ i ] = 0; - } + int i, j, index; + index = 0; + /* put the moving sheets on the board */ + for( i = 0; i < board_x_size; i++ ) + { + for( j = 0; j < board_y_size; j++ ) + { + /* initially fill up a corner with the moving squares */ + if( index < numsquares ) + { + rs->occupied[ i * board_y_size + j ] = index; + rs->xpos[ index ] = i; + rs->ypos[ index ] = j; + /* have the square colors start out as a pattern */ + rs->color[ index*3 + 0 ] = ((i+j)%3 == 0)||((i+j+1)%3 == 0); + rs->color[ index*3 + 1 ] = ((i+j+1)%3 == 0); + rs->color[ index*3 + 2 ] = ((i+j+2)%3 == 0); + index++; + } + /* leave everything else empty*/ + else + { + rs->occupied[ i * board_y_size + j ] = -1; + } + } + } + /* initially everything is at rest */ + for( i=0; idirection[ i ] = 0; + rs->angle[ i ] = 0; + } } /* Pick and random square and direction and try to move it. */ @@ -397,80 +502,80 @@ randsheet_initialize( randsheet *rs ) static int randsheet_new_move( randsheet* rs ) { - int i, j; - int num, dir; - /* pick a random square */ - num = random( ) % NUMSQUARES; - i = rs->xpos[ num ]; - j = rs->ypos[ num ]; - /* pick a random direction */ - dir = ( random( )% 4 ) + 1; - - if( rs->direction[ num ] == 0 ) - { - switch( dir ) - { - case 1: - /* move up in x */ - if( ( i + 1 ) < BOARDSIZE ) - { - if( rs->occupied[ i + 1 ][ j ] == -1 ) - { - rs->direction[ num ] = dir; - rs->occupied[ i + 1 ][ j ] = num; - rs->occupied[ i ][ j ] = -1; - return 1; - } - } - return 0; - break; - case 2: - /* move up in y */ - if( ( j + 1 ) < BOARDSIZE ) - { - if( rs->occupied[ i ][ j + 1 ] == -1 ) - { - rs->direction[ num ] = dir; - rs->occupied[ i ][ j + 1 ] = num; - rs->occupied[ i ][ j ] = -1; - return 1; - } - } - return 0; - break; - case 3: - /* move down in x */ - if( ( i - 1 ) >= 0 ) - { - if( rs->occupied[ i - 1][ j ] == -1 ) - { - rs->direction[ num ] = dir; - rs->occupied[ i - 1][ j ] = num; - rs->occupied[ i ][ j ] = -1; - return 1; - } - } - return 0; - break; - case 4: - /* move down in y */ - if( ( j - 1 ) >= 0 ) - { - if( rs->occupied[ i ][ j - 1 ] == -1 ) - { - rs->direction[ num ] = dir; - rs->occupied[ i ][ j - 1 ] = num; - rs->occupied[ i ][ j ] = -1; - return 1; - } - } - return 0; - break; - default: - break; - } - } - return 0; + int i, j; + int num, dir; + /* pick a random square */ + num = random( ) % numsquares; + i = rs->xpos[ num ]; + j = rs->ypos[ num ]; + /* pick a random direction */ + dir = ( random( )% 4 ) + 1; + + if( rs->direction[ num ] == 0 ) + { + switch( dir ) + { + case 1: + /* move up in x */ + if( ( i + 1 ) < board_x_size ) + { + if( rs->occupied[ (i + 1) * board_y_size + j ] == -1 ) + { + rs->direction[ num ] = dir; + rs->occupied[ (i + 1) * board_y_size + j ] = num; + rs->occupied[ i * board_y_size + j ] = -1; + return 1; + } + } + return 0; + break; + case 2: + /* move up in y */ + if( ( j + 1 ) < board_y_size ) + { + if( rs->occupied[ i * board_y_size + (j + 1) ] == -1 ) + { + rs->direction[ num ] = dir; + rs->occupied[ i * board_y_size + (j + 1) ] = num; + rs->occupied[ i * board_y_size + j ] = -1; + return 1; + } + } + return 0; + break; + case 3: + /* move down in x */ + if( ( i - 1 ) >= 0 ) + { + if( rs->occupied[ (i - 1) * board_y_size + j ] == -1 ) + { + rs->direction[ num ] = dir; + rs->occupied[ (i - 1) * board_y_size + j ] = num; + rs->occupied[ i * board_y_size + j ] = -1; + return 1; + } + } + return 0; + break; + case 4: + /* move down in y */ + if( ( j - 1 ) >= 0 ) + { + if( rs->occupied[ i * board_y_size + (j - 1) ] == -1 ) + { + rs->direction[ num ] = dir; + rs->occupied[ i * board_y_size + (j - 1) ] = num; + rs->occupied[ i * board_y_size + j ] = -1; + return 1; + } + } + return 0; + break; + default: + break; + } + } + return 0; } /* move a single frame. */ @@ -478,119 +583,121 @@ randsheet_new_move( randsheet* rs ) static void randsheet_move( randsheet *rs, float rot ) { - int i, j, index; - for( index = 0 ; index < NUMSQUARES; index++ ) - { - i = rs->xpos[ index ]; - j = rs->ypos[ index ]; - switch( rs->direction[ index ] ) - { - case 0: - /* not moving */ - break; - case 1: - /* move up in x */ - rs->angle[ index ] += rot; - /* check to see if we have finished moving */ - if( rs->angle[ index ] >= M_PI ) - { - rs->xpos[ index ] += 1; - rs->direction[ index ] = 0; - rs->angle[ index ] = 0; - } - break; - case 2: - /* move up in y */ - rs->angle[ index ] += rot; - /* check to see if we have finished moving */ - if( rs->angle[ index ] >= M_PI ) - { - rs->ypos[ index ] += 1; - rs->direction[ index ] = 0; - rs->angle[ index ] = 0; - } - break; - case 3: - /* down in x */ - rs->angle[ index ] += rot; - /* check to see if we have finished moving */ - if( rs->angle[ index ] >= M_PI ) - { - rs->xpos[ index ] -= 1; - rs->direction[ index ] = 0; - rs->angle[ index ] = 0; - } - break; - case 4: - /* up in x */ - rs->angle[ index ] += rot; - /* check to see if we have finished moving */ - if( rs->angle[ index ] >= M_PI ) - { - rs->ypos[ index ] -= 1; - rs->direction[ index ] = 0; - rs->angle[ index ] = 0; - } - break; - default: - break; - } - } + int i, j, index; + for( index = 0 ; index < numsquares; index++ ) + { + i = rs->xpos[ index ]; + j = rs->ypos[ index ]; + switch( rs->direction[ index ] ) + { + case 0: + /* not moving */ + break; + case 1: + /* move up in x */ + rs->angle[ index ] += rot; + /* check to see if we have finished moving */ + if( rs->angle[ index ] >= M_PI ) + { + rs->xpos[ index ] += 1; + rs->direction[ index ] = 0; + rs->angle[ index ] = 0; + } + break; + case 2: + /* move up in y */ + rs->angle[ index ] += rot; + /* check to see if we have finished moving */ + if( rs->angle[ index ] >= M_PI ) + { + rs->ypos[ index ] += 1; + rs->direction[ index ] = 0; + rs->angle[ index ] = 0; + } + break; + case 3: + /* down in x */ + rs->angle[ index ] += rot; + /* check to see if we have finished moving */ + if( rs->angle[ index ] >= M_PI ) + { + rs->xpos[ index ] -= 1; + rs->direction[ index ] = 0; + rs->angle[ index ] = 0; + } + break; + case 4: + /* up in x */ + rs->angle[ index ] += rot; + /* check to see if we have finished moving */ + if( rs->angle[ index ] >= M_PI ) + { + rs->ypos[ index ] -= 1; + rs->direction[ index ] = 0; + rs->angle[ index ] = 0; + } + break; + default: + break; + } + } } - /* draw all the moving squares */ +/* draw all the moving squares */ static void randsheet_draw( randsheet *rs ) { - int i, j; - int index; - /* for all moving squares ... */ - for( index = 0; index < NUMSQUARES; index++ ) - { - /* set color */ - glColor3f( rs->color[ index ][ 0 ], - rs->color[ index ][ 1 ], - rs->color[ index ][ 2 ] ); - /* find x and y position */ - i = rs->xpos[ index ]; - j = rs->ypos[ index ]; - glPushMatrix(); - switch( rs->direction[ index ] ) - { - case 0: - - /* not moving */ - /* front */ - glTranslatef( i, 0, j ); - break; - case 1: - glTranslatef( i+1, 0, j ); - glRotatef( 180 - rs->angle[ index ]*180/M_PI, 0, 0, 1 ); - - break; - case 2: - glTranslatef( i, 0, j+1 ); - glRotatef( 180 - rs->angle[ index ]*180/M_PI, -1, 0, 0 ); - - break; - case 3: - glTranslatef( i, 0, j ); - glRotatef( rs->angle[ index ]*180/M_PI, 0, 0, 1 ); - break; - case 4: - glTranslatef( i, 0, j ); - glRotatef( rs->angle[ index ]*180/M_PI, -1, 0, 0 ); - break; - default: - break; - } - draw_sheet(); - glPopMatrix(); - - } + int i, j; + int index; + /* for all moving squares ... */ + for( index = 0; index < numsquares; index++ ) + { + /* set color */ + glColor3f( rs->color[ index*3 + 0 ], + rs->color[ index*3 + 1 ], + rs->color[ index*3 + 2 ] ); + /* find x and y position */ + i = rs->xpos[ index ]; + j = rs->ypos[ index ]; + glPushMatrix(); + switch( rs->direction[ index ] ) + { + case 0: + + /* not moving */ + /* front */ + glTranslatef( i, 0, j ); + break; + case 1: + glTranslatef( i+1, 0, j ); + glRotatef( 180 - rs->angle[ index ]*180/M_PI, 0, 0, 1 ); + + break; + case 2: + glTranslatef( i, 0, j+1 ); + glRotatef( 180 - rs->angle[ index ]*180/M_PI, -1, 0, 0 ); + + break; + case 3: + glTranslatef( i, 0, j ); + glRotatef( rs->angle[ index ]*180/M_PI, 0, 0, 1 ); + break; + case 4: + glTranslatef( i, 0, j ); + glRotatef( rs->angle[ index ]*180/M_PI, -1, 0, 0 ); + break; + default: + break; + } + draw_sheet(); + glPopMatrix(); + + } } -/**** END RANDSHEET FUNCTIONS ***/ +/**** END RANDSHEET_BAK FUNCTIONS ***/ + +XSCREENSAVER_MODULE ("Flipflop", flipflop) -#endif +#endif /* USE_GL */