X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fmoebiusgears.c;h=0716cdcb858dc566de96560b5272a19636adf6d0;hp=03381b70d6ae9b81849e34324230f0afadc2f77c;hb=4361b69d3178d7fc98d0388f9a223af6c2651aba;hpb=6f5482d73adb0165c0130bb47d852644ab0c4869 diff --git a/hacks/glx/moebiusgears.c b/hacks/glx/moebiusgears.c index 03381b70..0716cdcb 100644 --- a/hacks/glx/moebiusgears.c +++ b/hacks/glx/moebiusgears.c @@ -1,4 +1,4 @@ -/* moebiusgears, Copyright (c) 2007-2008 Jamie Zawinski +/* moebiusgears, Copyright (c) 2007-2014 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -13,6 +13,7 @@ "*count: 17 \n" \ "*showFPS: False \n" \ "*wireframe: False \n" \ + "*suppressRotationAnimation: True\n" \ # define refresh_mgears 0 # define release_mgears 0 @@ -104,52 +105,129 @@ reshape_mgears (ModeInfo *mi, int width, int height) 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); +# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */ + { + int o = (int) current_device_rotation(); + if (o != 0 && o != 180 && o != -180) + glScalef (1/h, 1/h, 1/h); + } +# endif + glClear(GL_COLOR_BUFFER_BIT); } -ENTRYPOINT Bool -mgears_handle_event (ModeInfo *mi, XEvent *event) +static void +reset_mgears (ModeInfo *mi) { mgears_configuration *bp = &bps[MI_SCREEN(mi)]; + int wire = MI_IS_WIREFRAME(mi); + int total_gears = MI_COUNT(mi); + double gears_per_turn; + double gear_r, tw, th, thick, slope; + int i, nubs, size; - if (event->xany.type == ButtonPress && - event->xbutton.button == Button1) - { - bp->button_down_p = True; - gltrackball_start (bp->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) - { - bp->button_down_p = False; - return True; - } - else if (event->xany.type == ButtonPress && - (event->xbutton.button == Button4 || - event->xbutton.button == Button5 || - event->xbutton.button == Button6 || - event->xbutton.button == Button7)) + if (! (total_gears & 1)) + total_gears++; /* must be odd or gears intersect */ + + /* Number of teeth must be odd if number of gears is odd, or teeth don't + mesh when the loop closes. And since number of gears must be odd... + */ + if (! (teeth_arg & 1)) teeth_arg++; + if (teeth_arg < 7) teeth_arg = 7; + + if (total_gears < 13) /* gear mesh angle is too steep with less */ + total_gears = 13; + + thick = 0.2; + nubs = (random() & 3) ? 0 : (random() % teeth_arg) / 2; + + slope = 0; + + /* Sloping gears are incompatible with "-roll" ... */ + /* slope= -M_PI * 2 / total_gears; */ + + gears_per_turn = total_gears / 2.0; + + bp->ring_r = 3; + gear_r = M_PI * bp->ring_r / gears_per_turn; + tw = 0; + th = gear_r * 2.5 / teeth_arg; + + /* If the gears are small, use a lower density mesh. */ + size = (gear_r > 0.60 ? INVOLUTE_HUGE : + gear_r > 0.32 ? INVOLUTE_LARGE : + gear_r > 0.13 ? INVOLUTE_MEDIUM : + INVOLUTE_SMALL); + + /* If there are lots of teeth, use a lower density mesh. */ + if (teeth_arg > 77) + size = INVOLUTE_SMALL; + if (teeth_arg > 45 && size >= INVOLUTE_HUGE) + size = INVOLUTE_MEDIUM; + + if (bp->gears) { - gltrackball_mousewheel (bp->trackball, event->xbutton.button, 10, - !!event->xbutton.state); - return True; + for (i = 0; i < bp->ngears; i++) + glDeleteLists (bp->gears[i].g.dlist, 1); + free (bp->gears); + bp->gears = 0; } - else if (event->xany.type == MotionNotify && - bp->button_down_p) + + bp->ngears = total_gears; + + bp->gears = (mogear *) calloc (bp->ngears, sizeof(*bp->gears)); + for (i = 0; i < bp->ngears; i++) { - gltrackball_track (bp->trackball, - event->xmotion.x, event->xmotion.y, - MI_WIDTH (mi), MI_HEIGHT (mi)); - return True; - } + mogear *mg = &bp->gears[i]; + gear *g = &mg->g; - return False; -} + g->r = gear_r; + g->size = size; + g->nteeth = teeth_arg; + g->tooth_w = tw; + g->tooth_h = th; + g->tooth_slope = slope; + g->thickness = g->r * thick; + g->thickness2 = g->thickness * 0.1; + g->thickness3 = g->thickness; + g->inner_r = g->r * 0.80; + g->inner_r2 = g->r * 0.60; + g->inner_r3 = g->r * 0.55; + g->nubs = nubs; + mg->pos_th = (M_PI * 2 / gears_per_turn) * i; + mg->pos_thz = (M_PI / 2 / gears_per_turn) * i; + + g->th = ((i & 1) + ? (M_PI * 2 / g->nteeth) + : 0); + + /* Colorize + */ + g->color[0] = 0.7 + frand(0.3); + g->color[1] = 0.7 + frand(0.3); + g->color[2] = 0.7 + frand(0.3); + g->color[3] = 1.0; + + g->color2[0] = g->color[0] * 0.85; + g->color2[1] = g->color[1] * 0.85; + g->color2[2] = g->color[2] * 0.85; + g->color2[3] = g->color[3]; + + /* Now render the gear into its display list. + */ + g->dlist = glGenLists (1); + if (! g->dlist) + { + check_gl_error ("glGenLists"); + abort(); + } + glNewList (g->dlist, GL_COMPILE); + g->polygons += draw_involute_gear (g, wire); + glEndList (); + } +} ENTRYPOINT void @@ -157,16 +235,8 @@ init_mgears (ModeInfo *mi) { mgears_configuration *bp; int wire = MI_IS_WIREFRAME(mi); - int i; - if (!bps) { - bps = (mgears_configuration *) - calloc (MI_NUM_SCREENS(mi), sizeof (mgears_configuration)); - if (!bps) { - fprintf(stderr, "%s: out of memory\n", progname); - exit(1); - } - } + MI_INIT (mi, bps, NULL); bp = &bps[MI_SCREEN(mi)]; @@ -204,106 +274,55 @@ init_mgears (ModeInfo *mi) do_wander ? wander_speed : 0, False /* don't randomize */ ); - bp->trackball = gltrackball_init (); + bp->trackball = gltrackball_init (True); } - { - int total_gears = MI_COUNT(mi); - double gears_per_turn; - double gear_r, tw, th, thick, slope; - int nubs, size; - - if (! (total_gears & 1)) - total_gears++; /* must be odd or gears intersect */ - - /* Number of teeth must be odd if number of gears is odd, or teeth don't - mesh when the loop closes. And since number of gears must be odd... - */ - if (! (teeth_arg & 1)) teeth_arg++; - if (teeth_arg < 7) teeth_arg = 7; - - if (total_gears < 13) /* gear mesh angle is too steep with less */ - total_gears = 13; - - thick = 0.2; - nubs = (random() & 3) ? 0 : (random() % teeth_arg) / 2; - - slope = 0; - - /* Sloping gears are incompatible with "-roll" ... */ - /* slope= -M_PI * 2 / total_gears; */ - - gears_per_turn = total_gears / 2.0; - - bp->ring_r = 3; - gear_r = M_PI * bp->ring_r / gears_per_turn; - tw = 0; - th = gear_r * 2.5 / teeth_arg; - - /* If the gears are small, use a lower density mesh. */ - size = (gear_r > 0.32 ? INVOLUTE_LARGE : - gear_r > 0.13 ? INVOLUTE_MEDIUM : - INVOLUTE_SMALL); - - /* If there are lots of teeth, use a lower density mesh. */ - if (teeth_arg > 77) - size = INVOLUTE_SMALL; - if (teeth_arg > 45 && size == INVOLUTE_LARGE) - size = INVOLUTE_MEDIUM; - - bp->ngears = total_gears; - bp->gears = (mogear *) calloc (bp->ngears, sizeof(*bp->gears)); - for (i = 0; i < bp->ngears; i++) - { - mogear *mg = &bp->gears[i]; - gear *g = &mg->g; - - g->r = gear_r; - g->size = size; - g->nteeth = teeth_arg; - g->tooth_w = tw; - g->tooth_h = th; - g->tooth_slope = slope; - g->thickness = g->r * thick; - g->thickness2 = g->thickness * 0.1; - g->thickness3 = g->thickness; - g->inner_r = g->r * 0.80; - g->inner_r2 = g->r * 0.60; - g->inner_r3 = g->r * 0.55; - g->nubs = nubs; - mg->pos_th = (M_PI * 2 / gears_per_turn) * i; - mg->pos_thz = (M_PI / 2 / gears_per_turn) * i; - - g->th = ((i & 1) - ? (M_PI * 2 / g->nteeth) - : 0); - - /* Colorize - */ - g->color[0] = 0.7 + frand(0.3); - g->color[1] = 0.7 + frand(0.3); - g->color[2] = 0.7 + frand(0.3); - g->color[3] = 1.0; - - g->color2[0] = g->color[0] * 0.85; - g->color2[1] = g->color[1] * 0.85; - g->color2[2] = g->color[2] * 0.85; - g->color2[3] = g->color[3]; - - /* Now render the gear into its display list. - */ - g->dlist = glGenLists (1); - if (! g->dlist) - { - check_gl_error ("glGenLists"); - abort(); - } - - glNewList (g->dlist, GL_COMPILE); - g->polygons += draw_involute_gear (g, wire); - glEndList (); - } - } + reset_mgears (mi); +} + + +ENTRYPOINT Bool +mgears_handle_event (ModeInfo *mi, XEvent *event) +{ + mgears_configuration *bp = &bps[MI_SCREEN(mi)]; + + if (gltrackball_event_handler (event, bp->trackball, + MI_WIDTH (mi), MI_HEIGHT (mi), + &bp->button_down_p)) + return True; + else if (event->xany.type == KeyPress) + { + KeySym keysym; + char c = 0; + XLookupString (&event->xkey, &c, 1, &keysym, 0); + if (c == '+' || c == '=' || + keysym == XK_Up || keysym == XK_Right || keysym == XK_Next) + { + MI_COUNT(mi) += 2; + reset_mgears (mi); + return True; + } + else if (c == '-' || c == '_' || + keysym == XK_Down || keysym == XK_Left || keysym == XK_Prior) + { + if (MI_COUNT(mi) <= 13) + return False; + MI_COUNT(mi) -= 2; + reset_mgears (mi); + return True; + } + else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event)) + goto DEF; + } + else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event)) + { + DEF: + MI_COUNT(mi) = 13 + (2 * (random() % 10)); + reset_mgears (mi); + return True; + } + + return False; } @@ -339,10 +358,7 @@ draw_mgears (ModeInfo *mi) (y - 0.5) * 4, (z - 0.5) * 7); - /* Do it twice because we don't track the device's orientation. */ - glRotatef( current_device_rotation(), 0, 0, 1); gltrackball_rotate (bp->trackball); - glRotatef(-current_device_rotation(), 0, 0, 1); get_rotation (bp->rot, &x, &y, &z, !bp->button_down_p);