X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fdnalogo.c;h=36246176aac7a25f695db27a18559487da933790;hb=39809ded547bdbb08207d3e514950425215b4410;hp=2d3bbb2c8df383e8ffc3370d6901cff20c82afb7;hpb=88cfe534a698a0562e81345957a50714af1453bc;p=xscreensaver diff --git a/hacks/glx/dnalogo.c b/hacks/glx/dnalogo.c index 2d3bbb2c..36246176 100644 --- a/hacks/glx/dnalogo.c +++ b/hacks/glx/dnalogo.c @@ -1,4 +1,4 @@ -/* DNA Logo, Copyright (c) 2001-2015 Jamie Zawinski +/* DNA Logo, Copyright (c) 2001-2017 Jamie Zawinski * * DNA Lounge * @@ -8,7 +8,7 @@ * San Francisco, CA * 94103 * - * http://www.dnalounge.com/ + * https://www.dnalounge.com/ * http://www.dnapizza.com/ * * Permission to use, copy, modify, distribute, and sell this software and its @@ -61,18 +61,17 @@ "*cwFont: " CWFONT "\n" \ "*geometry: =640x640\n" \ -# if defined(HAVE_COCOA) +# if defined(HAVE_COCOA) || defined(HAVE_ANDROID) # define CWFONT "Yearling 28, OCR A Std 24" # else # define CWFONT "-*-helvetica-medium-r-normal-*-*-240-*-*-*-*-*-*" # endif -# define refresh_logo 0 +# define free_logo 0 # define release_logo 0 #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) -#undef LINEAR #undef DXF_OUTPUT_HACK #ifdef DXF_OUTPUT_HACK /* When this is defined, instead of rendering @@ -108,14 +107,18 @@ typedef enum { HELIX_IN, HELIX, HELIX_OUT, PIZZA_IN, PIZZA, PIZZA_OUT, HELIX_AND_PIZZA, +# ifdef CW CODEWORD_IN, CODEWORD, CODEWORD_OUT, CODEWORD_BLANK +# endif } glyph_mode; typedef struct { Bool spinning_p; - GLfloat position; /* 0.0 - 1.0 */ - GLfloat speed; /* how far along the path (may be negative) */ - GLfloat probability; /* relative likelyhood to start spinning */ + GLfloat position; /* 0.0 - 1.0 */ + GLfloat position_eased; /* 0.0 - 1.0, eased in and out */ + GLfloat easement; /* portion of path that is eased. <= 0.5 */ + GLfloat speed; /* how far along the path (may be negative) */ + GLfloat probability; /* relative likelyhood to start spinning */ } spinner; typedef struct { @@ -149,6 +152,7 @@ typedef struct { GLfloat frame_thickness; GLfloat triangle_size; +# ifdef CW int codeword_facets, codeword_disc_facets; GLfloat codeword_spread, codeword_line_width, codeword_thickness; GLfloat codeword_cap_size; @@ -161,6 +165,7 @@ typedef struct { XYZ *codeword_guides; GLfloat codeword_color[4], codeword_bg[4]; texture_font_data *font; +# endif GLfloat speed; glyph_mode mode; @@ -169,7 +174,9 @@ typedef struct { spinner gasket_spinnerx, gasket_spinnery, gasket_spinnerz; spinner scene_spinnerx, scene_spinnery; /* for DNA */ +# ifdef CW rotator *scene_rot; /* for Codeword */ +# endif spinner helix_spinnerz; spinner pizza_spinnery, pizza_spinnerz; spinner frame_spinner; @@ -189,9 +196,11 @@ static XrmOptionDescRec opts[] = { { "-pizza", ".mode", XrmoptionNoArg, "pizza" }, { "-helix", ".mode", XrmoptionNoArg, "helix" }, { "-both", ".mode", XrmoptionNoArg, "both" }, +# ifdef CW { "-codeword", ".mode", XrmoptionNoArg, "codeword" }, { "-cw", ".mode", XrmoptionNoArg, "codeword" }, { "-text", ".text", XrmoptionSepArg, 0 }, +# endif }; ENTRYPOINT ModeSpecOpt logo_opts = {countof(opts), opts, 0, NULL, NULL}; @@ -500,6 +509,9 @@ vector_angle (double ax, double ay, double az, return (angle); } + +# ifdef CW + static void normalize (XYZ *p) { @@ -523,6 +535,8 @@ dot (const XYZ u, const XYZ v) return (u.x * v.x) + (u.y * v.y) + (u.z * v.z); } +#endif /* CW */ + /* Make the helix */ @@ -1519,7 +1533,6 @@ make_pizza (logo_configuration *dc, int facetted, int wire) GLfloat th, x, y, s; int i, j, k; int endpoints; - int endedge1; # ifdef HAVE_TESS tess_out TO, *to = &TO; @@ -1571,7 +1584,6 @@ make_pizza (logo_configuration *dc, int facetted, int wire) points[j++] = edge[i*2]; points[j++] = 0; } - endedge1 = i; } s = 0.798; /* radius of end of slice, before crust gap */ @@ -1759,21 +1771,39 @@ make_pizza (logo_configuration *dc, int facetted, int wire) # else /* !HAVE_TESS */ if (! wire) { + glTranslatef(0, 0, thick2); + glNormal3f (0, 0, 1); + glFrontFace (GL_CW); + + /* Sadly, jwzgl's glVertexPointer seems not to be recordable inside + display lists. */ +# if 0 glDisableClientState (GL_COLOR_ARRAY); glDisableClientState (GL_NORMAL_ARRAY); glDisableClientState (GL_TEXTURE_COORD_ARRAY); glEnableClientState (GL_VERTEX_ARRAY); glVertexPointer (3, GL_FLOAT, 0, dnapizza_triangles); - - glTranslatef(0, 0, thick2); - glNormal3f (0, 0, 1); - glFrontFace (GL_CW); glDrawArrays (GL_TRIANGLES, 0, countof (dnapizza_triangles) / 3); +# else + glBegin (GL_TRIANGLES); + for (i = 0; i < countof (dnapizza_triangles); i += 3) + glVertex3fv (dnapizza_triangles + i); + glEnd(); +# endif glTranslatef(0, 0, -thick2*2); glNormal3f (0, 0, -1); glFrontFace (GL_CCW); + +# if 0 glDrawArrays (GL_TRIANGLES, 0, countof (dnapizza_triangles) / 3); +# else + int i; + glBegin (GL_TRIANGLES); + for (i = 0; i < countof (dnapizza_triangles); i += 3) + glVertex3fv (dnapizza_triangles + i); + glEnd(); +# endif glTranslatef(0, 0, thick2); } @@ -1899,6 +1929,8 @@ make_pizza (logo_configuration *dc, int facetted, int wire) } +# ifdef CW + /* Upcase string, convert Unicrud to ASCII, remove any non-letters. */ static char * @@ -1935,7 +1967,7 @@ make_codeword_path (ModeInfo *mi) int dial = 0; int letter; - GLfloat last_r; + GLfloat last_r = 0; GLfloat inner_circum = M_PI * 2 * (iradius + rtick * 2); GLfloat outer_circum = M_PI * 2 * (iradius + rtick * (letters + 1)); @@ -2328,7 +2360,7 @@ codeword_text_output (ModeInfo *mi, GLfloat anim_ratio) buf[1] = 0; texture_string_metrics (dc->font, buf, &e, &ascent, &descent); -# ifdef USE_IPHONE +# ifdef HAVE_MOBILE /* #### Magic magic magic WTF... */ glScalef (0.5, 0.5, 0.5); # endif @@ -2497,7 +2529,7 @@ draw_codeword_path (ModeInfo *mi) glColor4fv (dc->codeword_color); glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, dc->codeword_color); -# ifdef USE_IPHONE /* Make the whole thing fit on the phone screen */ +# ifdef HAVE_MOBILE /* Make the whole thing fit on the phone screen */ { GLfloat size = MI_WIDTH(mi) < MI_HEIGHT(mi) ? MI_WIDTH(mi) : MI_HEIGHT(mi); glScalef (0.9, 0.9, 0.9); @@ -2643,7 +2675,7 @@ draw_codeword_path (ModeInfo *mi) /* Draw the start and end caps */ { int i; - GLfloat x, y, z, x2, y2, z2, X, Y, Z, L; + GLfloat x, y, z, x2, y2, z2, X, Y, Z; GLfloat r = dc->codeword_spread * dc->codeword_cap_size; i = 0; @@ -2676,7 +2708,6 @@ draw_codeword_path (ModeInfo *mi) X = (x2 - x); Y = (y2 - y); Z = (z2 - z); - L = sqrt (X*X + Y*Y + Z*Z); glPushMatrix(); glTranslatef (x, y, z); @@ -2697,6 +2728,7 @@ draw_codeword_path (ModeInfo *mi) return polys; } +#endif /* CW */ /* Window management, etc @@ -2718,6 +2750,14 @@ reshape_logo (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); /* #### Why does this change the lighting? */ + } +# endif + glClear(GL_COLOR_BUFFER_BIT); } @@ -2766,14 +2806,7 @@ init_logo (ModeInfo *mi) exit (1); } - if (!dcs) { - dcs = (logo_configuration *) - calloc (MI_NUM_SCREENS(mi), sizeof (logo_configuration)); - if (!dcs) { - fprintf(stderr, "%s: out of memory\n", progname); - exit(1); - } - } + MI_INIT (mi, dcs); dc = &dcs[MI_SCREEN(mi)]; @@ -2803,6 +2836,7 @@ init_logo (ModeInfo *mi) dc->triangle_size = get_float_resource(mi->dpy, "triangleSize", "Float"); dc->speed = get_float_resource(mi->dpy, "speed", "Float"); +# ifdef CW dc->codeword_text = get_string_resource(mi->dpy, "text", "String"); dc->codeword_text = codeword_simplify_text (dc->codeword_text); dc->codeword_text_out = @@ -2818,6 +2852,7 @@ init_logo (ModeInfo *mi) dc->codeword_line_width = get_float_resource(mi->dpy, "cwLineWidth", "Float"); dc->codeword_thickness = get_float_resource(mi->dpy, "cwThickness", "Float"); dc->codeword_cap_size = get_float_resource(mi->dpy, "cwCapSize", "Float"); +# endif { char *s = get_string_resource (MI_DISPLAY (mi), "mode", "String"); @@ -2827,12 +2862,14 @@ init_logo (ModeInfo *mi) dc->mode = PIZZA; else if (!strcasecmp (s, "both")) dc->mode = HELIX_AND_PIZZA; +# ifdef CW else if (!strcasecmp (s, "codeword")) dc->mode = CODEWORD_IN; +# endif else { fprintf (stderr, - "%s: mode must be helix, pizza, both or codeword, not \"%s\"\n", + "%s: mode must be helix, pizza or both, not \"%s\"\n", progname, s); exit (1); } @@ -2844,8 +2881,10 @@ init_logo (ModeInfo *mi) dc->anim_ratio = 0; } +# ifdef CW if (dc->mode == CODEWORD_IN) dc->font = load_texture_font (MI_DISPLAY(mi), "cwFont"); +# endif { XColor xcolor; @@ -2883,6 +2922,7 @@ init_logo (ModeInfo *mi) exit (1); } +# ifdef CW dc->codeword_color[0] = xcolor.red / 65535.0; dc->codeword_color[1] = xcolor.green / 65535.0; dc->codeword_color[2] = xcolor.blue / 65535.0; @@ -2905,6 +2945,7 @@ init_logo (ModeInfo *mi) dc->codeword_bg[1] = xcolor.green / 65535.0; dc->codeword_bg[2] = xcolor.blue / 65535.0; dc->codeword_bg[3] = 1.0; +# endif /* CW */ } dc->trackball = gltrackball_init (False); @@ -2912,22 +2953,33 @@ init_logo (ModeInfo *mi) dc->gasket_spinnerx.probability = 0.1; dc->gasket_spinnery.probability = 0.1; dc->gasket_spinnerz.probability = 1.0; + dc->gasket_spinnerx.easement = 0.08; + dc->gasket_spinnery.easement = 0.08; + dc->gasket_spinnerz.easement = 0.08; dc->helix_spinnerz.probability = 0.6; + dc->helix_spinnerz.easement = 0.2; dc->pizza_spinnerz.probability = 0.6; dc->pizza_spinnery.probability = 0.6; + dc->pizza_spinnerz.easement = 0.2; + dc->pizza_spinnery.easement = 0.2; dc->frame_spinner.probability = 5.0; + dc->frame_spinner.easement = 0.2; dc->scene_spinnerx.probability = 0.1; dc->scene_spinnery.probability = 0.0; + dc->scene_spinnerx.easement = 0.1; + dc->scene_spinnery.easement = 0.1; +# ifdef CW if (dc->mode == CODEWORD_IN) { double tilt_speed = 0.003; dc->scene_rot = make_rotator (0, 0, 0, 0, tilt_speed, True); } +# endif /* start the frame off-screen */ dc->frame_spinner.spinning_p = True; @@ -3050,8 +3102,9 @@ init_logo (ModeInfo *mi) if (do_frame) dc->polys[6] += make_frame (dc, 1); glEndList (); +# ifdef CW make_codeword_path (mi); - +# endif /* When drawing both solid and wireframe objects, make sure the wireframe actually shows up! */ @@ -3085,10 +3138,12 @@ logo_handle_event (ModeInfo *mi, XEvent *event) dc->anim_state = PIZZA_OUT; dc->anim_ratio = 0.0; return True; +# ifdef CW case CODEWORD: dc->anim_state = CODEWORD_OUT; dc->anim_ratio = 0.0; return True; +# endif default: break; } @@ -3099,6 +3154,14 @@ logo_handle_event (ModeInfo *mi, XEvent *event) } +static GLfloat +spinner_ease (GLfloat x) +{ + /* Smooth curve up, ending at slope = 1. */ + return cos ((x/2 + 1) * M_PI) + 1; +} + + static void tick_spinner (ModeInfo *mi, spinner *s) { @@ -3110,12 +3173,20 @@ tick_spinner (ModeInfo *mi, spinner *s) if (s->spinning_p) { s->position += s->speed; - if (s->position >= 1.0 || s->position <= -1.0) - + if (s->position >= 1.0 || s->position <= 0.0) { s->position = 0; + s->position_eased = 0; s->spinning_p = False; } + else if (s->easement > 0 && s->position <= s->easement) + s->position_eased = (s->easement * + spinner_ease (s->position / s->easement)); + else if (s->easement > 0 && s->position >= 1-s->easement) + s->position_eased = (1 - s->easement * + spinner_ease ((1 - s->position) / s->easement)); + else + s->position_eased = s->position; } else if (s->probability && (random() % (int) (PROBABILITY_SCALE / s->probability)) == 0) @@ -3127,7 +3198,10 @@ tick_spinner (ModeInfo *mi, spinner *s) s->speed = dc->speed * (frand(ss/3) + frand(ss/3) + frand(ss/3)); } while (s->speed <= 0); if (random() & 1) - s->speed = -s->speed; + { + s->speed = -s->speed; + s->position = 1.0; + } } } @@ -3156,7 +3230,9 @@ draw_logo (ModeInfo *mi) GLfloat specular[] = {0.8, 0.8, 0.8, 1.0}; GLfloat shininess = 50.0; Bool pizza_p; +# ifdef CW Bool codeword_p; +# endif if (!dc->glx_context) return; @@ -3182,28 +3258,6 @@ draw_logo (ModeInfo *mi) tick_spinner (mi, &dc->frame_spinner); link_spinners (mi, &dc->scene_spinnerx, &dc->scene_spinnery); -# ifdef LINEAR - { - static double i = 0.0; - dc->anim_state = HELIX; - dc->wire_overlay = 0; - dc->gasket_spinnerx.spinning_p = 0; - dc->gasket_spinnery.spinning_p = 0; - dc->gasket_spinnerz.spinning_p = 0; - dc->helix_spinnerz.spinning_p = 0; - dc->pizza_spinnery.spinning_p = 0; - dc->pizza_spinnerz.spinning_p = 0; - dc->scene_spinnerx.spinning_p = 0; - dc->scene_spinnery.spinning_p = 0; - dc->frame_spinner.spinning_p = 0; - dc->frame_spinner.position = 0.3; - dc->gasket_spinnerz.position = i; - dc->helix_spinnerz.position = i; - i += 0.005; - if (i > 1) i = 0; - } -# endif /* LINEAR */ - switch (dc->anim_state) { case HELIX: @@ -3255,6 +3309,7 @@ draw_logo (ModeInfo *mi) break; +# ifdef CW case CODEWORD_IN: dc->scene_spinnerx.probability = 0.2; dc->scene_spinnery.probability = 0.05; @@ -3268,7 +3323,7 @@ draw_logo (ModeInfo *mi) break; case CODEWORD: - dc->scene_spinnerx.probability = 2.5; + dc->scene_spinnerx.probability = 0.5; dc->scene_spinnery.probability = 0.2; if (! dc->button_down_p) dc->anim_ratio += (0.0005 + frand(0.002)) * dc->speed; @@ -3302,6 +3357,7 @@ draw_logo (ModeInfo *mi) dc->anim_state = CODEWORD_IN; } break; +# endif /* CW */ default: abort(); @@ -3312,10 +3368,12 @@ draw_logo (ModeInfo *mi) dc->anim_state == PIZZA_IN || dc->anim_state == PIZZA_OUT); +# ifdef CW codeword_p = (dc->anim_state == CODEWORD || dc->anim_state == CODEWORD_IN || dc->anim_state == CODEWORD_OUT || dc->anim_state == CODEWORD_BLANK); +# endif glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -3323,20 +3381,19 @@ draw_logo (ModeInfo *mi) glRotatef(current_device_rotation(), 0, 0, 1); { GLfloat scale = 1.8; -# ifdef LINEAR - scale = 3.85; -# endif glScalef(scale, scale, scale); glColor3f(dc->color[0], dc->color[1], dc->color[2]); /* Draw frame before trackball rotation */ +# ifdef CW if (! codeword_p) +# endif { - GLfloat p = (dc->frame_spinner.position >= 0 - ? dc->frame_spinner.position - : -dc->frame_spinner.position); + GLfloat p = (dc->frame_spinner.position_eased >= 0 + ? dc->frame_spinner.position_eased + : -dc->frame_spinner.position_eased); GLfloat size = (p > 0.5 ? 1-p : p); scale = 1 + (size * 10); glPushMatrix(); @@ -3373,22 +3430,18 @@ draw_logo (ModeInfo *mi) glRotatef(90, 1, 0, 0); glRotatef(90, 0, 0, 1); -# ifdef LINEAR -# define SINIFY(I) (I) -# else -# define SINIFY(I) sin (M_PI/2 * (I)) -# endif - +# ifdef CW if (! codeword_p) +# endif { - glRotatef (360 * SINIFY (dc->scene_spinnerx.position), 0, 1, 0); - glRotatef (360 * SINIFY (dc->scene_spinnery.position), 0, 0, 1); + glRotatef (360 * dc->scene_spinnerx.position_eased, 0, 1, 0); + glRotatef (360 * dc->scene_spinnery.position_eased, 0, 0, 1); glPushMatrix(); - glRotatef (360 * SINIFY (dc->gasket_spinnerx.position), 0, 1, 0); - glRotatef (360 * SINIFY (dc->gasket_spinnery.position), 0, 0, 1); - glRotatef (360 * SINIFY (dc->gasket_spinnerz.position), 1, 0, 0); + glRotatef (360 * dc->gasket_spinnerx.position_eased, 0, 1, 0); + glRotatef (360 * dc->gasket_spinnery.position_eased, 0, 0, 1); + glRotatef (360 * dc->gasket_spinnerz.position_eased, 1, 0, 0); memcpy (gcolor, dc->color, sizeof (dc->color)); if (dc->wire_overlay != 0) @@ -3426,12 +3479,12 @@ draw_logo (ModeInfo *mi) if (pizza_p) { - glRotatef (360 * SINIFY (dc->pizza_spinnery.position), 1, 0, 0); - glRotatef (360 * SINIFY (dc->pizza_spinnerz.position), 0, 0, 1); + glRotatef (360 * dc->pizza_spinnery.position_eased, 1, 0, 0); + glRotatef (360 * dc->pizza_spinnerz.position_eased, 0, 0, 1); } else { - glRotatef (360 * SINIFY (dc->helix_spinnerz.position), 0, 0, 1); + glRotatef (360 * dc->helix_spinnerz.position_eased, 0, 0, 1); } scale = ((dc->anim_state == PIZZA_IN || dc->anim_state == HELIX_IN) @@ -3478,19 +3531,20 @@ draw_logo (ModeInfo *mi) mi->polygon_count += dc->polys[0]; } } +# ifdef CW else /* codeword_p */ { -# if 0 +# if 0 double max = 70; /* face front */ double x, y, z; get_position (dc->scene_rot, &x, &y, &z, !dc->button_down_p); glRotatef (max/2 - x*max, 0, 0, 1); glRotatef (max/2 - y*max, 0, 1, 0); /* glRotatef (max/2 - z*max, 1, 0, 0); */ -# else - glRotatef (360 * SINIFY (dc->scene_spinnerx.position), 0, 1, 0); - glRotatef (360 * SINIFY (dc->scene_spinnery.position), 0, 0, 1); -# endif +# else + glRotatef (360 * dc->scene_spinnerx.position_eased, 0, 1, 0); + glRotatef (360 * dc->scene_spinnery.position_eased, 0, 0, 1); +# endif glClearColor (dc->codeword_bg[0], dc->codeword_bg[1], @@ -3498,6 +3552,7 @@ draw_logo (ModeInfo *mi) dc->codeword_bg[3]); mi->polygon_count += draw_codeword_path (mi); } +# endif /* CW */ } glPopMatrix();