X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fstarwars.c;h=60f766a72514e576e63a11aa105901f098e0dc79;hp=afbefc8624912485fc0870c3d124ee61ff1b72ae;hb=ffd8c0873576a9e3065696a624dce6b766b77062;hpb=ebc241816cc8e3eec7270a594bb1a607df32bcd6 diff --git a/hacks/glx/starwars.c b/hacks/glx/starwars.c index afbefc86..60f766a7 100644 --- a/hacks/glx/starwars.c +++ b/hacks/glx/starwars.c @@ -1,6 +1,6 @@ /* - * starwars, Copyright (c) 1998-2001 Jamie Zawinski and - * Claudio Matauoka + * starwars, Copyright (c) 1998-2001, 2004 Jamie Zawinski and + * Claudio Matsuoka * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -29,6 +29,8 @@ * 20010124 jwz Rewrote large sections to add the ability to * run a subprocess, customization of the font * size and other parameters, etc. + * 20010224 jepler@mail.inetnebr.com made the lines be anti-aliased, + * made the text fade to black at the end. */ #include @@ -38,28 +40,41 @@ extern XtAppContext app; #define PROGCLASS "StarWars" #define HACK_INIT init_sws #define HACK_DRAW draw_sws +#define HACK_RESHAPE reshape_sws #define sws_opts xlockmore_opts -#define DEF_PROGRAM ZIPPY_PROGRAM -#define DEF_LINES "500" +#define DEF_PROGRAM "(default)" +#define DEF_LINES "125" #define DEF_STEPS "35" #define DEF_SPIN "0.03" #define DEF_FONT_SIZE "-1" #define DEF_COLUMNS "-1" #define DEF_WRAP "True" #define DEF_ALIGN "Center" +#define DEF_SMOOTH "True" +#define DEF_THICK "True" +#define DEF_FADE "True" #define TAB_WIDTH 8 #define BASE_FONT_SIZE 18 /* magic */ #define BASE_FONT_COLUMNS 80 /* magic */ +#define MAX_THICK_LINES 25 +#define FONT_WEIGHT 14 +#define KEEP_ASPECT +#undef DEBUG #define DEFAULTS "*delay: 40000 \n" \ + "*showFPS: False \n" \ + "*fpsTop: True \n" \ "*program: " DEF_PROGRAM "\n" \ "*lines: " DEF_LINES "\n" \ "*spin: " DEF_SPIN "\n" \ "*steps: " DEF_STEPS "\n" \ + "*smooth: " DEF_SMOOTH "\n" \ + "*thick: " DEF_THICK "\n" \ + "*fade: " DEF_FADE "\n" \ "*starwars.fontSize: " DEF_FONT_SIZE "\n" \ "*starwars.columns: " DEF_COLUMNS "\n" \ "*starwars.lineWrap: " DEF_WRAP "\n" \ @@ -72,11 +87,17 @@ extern XtAppContext app; #ifdef USE_GL /* whole file */ +#include #include +#include #include "glutstroke.h" #include "glut_roman.h" #define GLUT_FONT (&glutStrokeRoman) +#ifdef HAVE_UNAME +# include +#endif /* HAVE_UNAME */ + typedef struct { GLXContext *glx_context; @@ -98,6 +119,9 @@ typedef struct { double font_scale; double intra_line_scroll; + int line_pixel_height; + GLfloat line_thickness; + } sws_configuration; @@ -110,33 +134,45 @@ static float star_spin; static float font_size; static int target_columns; static int wrap_p; +static int smooth_p; +static int thick_p; +static int fade_p; static char *alignment_str; static int alignment; static XrmOptionDescRec opts[] = { - {"-program", ".starwars.program", XrmoptionSepArg, (caddr_t) 0 }, - {"-lines", ".starwars.lines", XrmoptionSepArg, (caddr_t) 0 }, - {"-steps", ".starwars.steps", XrmoptionSepArg, (caddr_t) 0 }, - {"-spin", ".starwars.spin", XrmoptionSepArg, (caddr_t) 0 }, - {"-size", ".starwars.fontSize", XrmoptionSepArg, (caddr_t) 0 }, - {"-columns", ".starwars.columns", XrmoptionSepArg, (caddr_t) 0 }, - {"-wrap", ".starwars.lineWrap", XrmoptionNoArg, (caddr_t) "True" }, - {"-no-wrap", ".starwars.lineWrap", XrmoptionNoArg, (caddr_t) "False" }, - {"-nowrap", ".starwars.lineWrap", XrmoptionNoArg, (caddr_t) "False" }, - {"-left", ".starwars.alignment",XrmoptionNoArg, (caddr_t) "Left" }, - {"-right", ".starwars.alignment",XrmoptionNoArg, (caddr_t) "Right" }, - {"-center", ".starwars.alignment",XrmoptionNoArg, (caddr_t) "Center" }, + {"-program", ".starwars.program", XrmoptionSepArg, 0 }, + {"-lines", ".starwars.lines", XrmoptionSepArg, 0 }, + {"-steps", ".starwars.steps", XrmoptionSepArg, 0 }, + {"-spin", ".starwars.spin", XrmoptionSepArg, 0 }, + {"-size", ".starwars.fontSize", XrmoptionSepArg, 0 }, + {"-columns", ".starwars.columns", XrmoptionSepArg, 0 }, + {"-smooth", ".starwars.smooth", XrmoptionNoArg, "True" }, + {"-no-smooth", ".starwars.smooth", XrmoptionNoArg, "False" }, + {"-thick", ".starwars.thick", XrmoptionNoArg, "True" }, + {"-no-thick", ".starwars.thick", XrmoptionNoArg, "False" }, + {"-fade", ".starwars.fade", XrmoptionNoArg, "True" }, + {"-no-fade", ".starwars.fade", XrmoptionNoArg, "False" }, + {"-wrap", ".starwars.lineWrap", XrmoptionNoArg, "True" }, + {"-no-wrap", ".starwars.lineWrap", XrmoptionNoArg, "False" }, + {"-nowrap", ".starwars.lineWrap", XrmoptionNoArg, "False" }, + {"-left", ".starwars.alignment",XrmoptionNoArg, "Left" }, + {"-right", ".starwars.alignment",XrmoptionNoArg, "Right" }, + {"-center", ".starwars.alignment",XrmoptionNoArg, "Center" }, }; static argtype vars[] = { - {(caddr_t *) &program, "program", "Program", DEF_PROGRAM, t_String}, - {(caddr_t *) &max_lines, "lines", "Integer", DEF_LINES, t_Int}, - {(caddr_t *) &scroll_steps, "steps", "Integer", DEF_STEPS, t_Int}, - {(caddr_t *) &star_spin, "spin", "Float", DEF_SPIN, t_Float}, - {(caddr_t *) &font_size, "fontSize","Float", DEF_STEPS, t_Float}, - {(caddr_t *) &target_columns, "columns", "Integer", DEF_COLUMNS, t_Int}, - {(caddr_t *) &wrap_p, "lineWrap","Boolean", DEF_COLUMNS, t_Bool}, - {(caddr_t *) &alignment_str, "alignment","Alignment",DEF_ALIGN, t_String}, + {&program, "program", "Program", DEF_PROGRAM, t_String}, + {&max_lines, "lines", "Integer", DEF_LINES, t_Int}, + {&scroll_steps, "steps", "Integer", DEF_STEPS, t_Int}, + {&star_spin, "spin", "Float", DEF_SPIN, t_Float}, + {&font_size, "fontSize", "Float", DEF_STEPS, t_Float}, + {&target_columns, "columns", "Integer", DEF_COLUMNS, t_Int}, + {&wrap_p, "lineWrap", "Boolean", DEF_COLUMNS, t_Bool}, + {&alignment_str, "alignment", "Alignment", DEF_ALIGN, t_String}, + {&smooth_p, "smooth", "Boolean", DEF_SMOOTH, t_Bool}, + {&thick_p, "thick", "Boolean", DEF_THICK, t_Bool}, + {&fade_p, "fade", "Boolean", DEF_FADE, t_Bool}, }; ModeSpecOpt sws_opts = {countof(opts), opts, countof(vars), vars, NULL}; @@ -148,6 +184,7 @@ ModeSpecOpt sws_opts = {countof(opts), opts, countof(vars), vars, NULL}; static char * untabify (const char *string) { + const char *ostring = string; char *result = (char *) malloc ((strlen(string) * 8) + 1); char *out = result; int col = 0; @@ -166,6 +203,11 @@ untabify (const char *string) *out++ = *string++; col = 0; } + else if (*string == '\010') /* backspace */ + { + if (string > ostring) + out--, string++; + } else { *out++ = *string++; @@ -173,9 +215,55 @@ untabify (const char *string) } } *out = 0; + return result; } +static void +strip (char *s, Bool leading, Bool trailing) +{ + int L = strlen(s); + if (trailing) + while (L > 0 && (s[L-1] == ' ' || s[L-1] == '\t')) + s[L--] = 0; + if (leading) + { + char *s2 = s; + while (*s2 == ' ' || *s2 == '\t') + s2++; + if (s == s2) + return; + while (*s2) + *s++ = *s2++; + *s = 0; + } +} + + +/* The GLUT font only has ASCII characters in them, so do what we can to + convert Latin1 characters to the nearest ASCII equivalent... + */ +static void +latin1_to_ascii (char *s) +{ + unsigned char *us = (unsigned char *) s; + const unsigned char ascii[95] = { + '!', 'C', '#', '#', 'Y', '|', 'S', '_', 'C', '?', '<', '=', '-', 'R', '_', + '?', '?', '2', '3', '\'','u', 'P', '.', ',', '1', 'o', '>', '?', '?', '?', + '?', 'A', 'A', 'A', 'A', 'A', 'A', 'E', 'C', 'E', 'E', 'E', 'E', 'I', 'I', + 'I', 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'x', '0', 'U', 'U', 'U', 'U', + 'Y', 'p', 'S', 'a', 'a', 'a', 'a', 'a', 'a', 'e', 'c', 'e', 'e', 'e', 'e', + 'i', 'i', 'i', 'i', 'o', 'n', 'o', 'o', 'o', 'o', 'o', '/', 'o', 'u', 'u', + 'u', 'u', 'y', 'p', 'y' }; + while (*us) + { + if (*us >= 161) + *us = ascii[*us - 161]; + else if (*us > 127) + *us = '?'; + us++; + } +} /* Subprocess. @@ -196,8 +284,59 @@ static void launch_text_generator (sws_configuration *sc) { char *oprogram = get_string_resource ("program", "Program"); - char *program = (char *) malloc (strlen (oprogram) + 10); + char *program; + + if (!strcasecmp(oprogram, "(default)")) + { + oprogram = FORTUNE_PROGRAM; + +#if defined(__linux__) && defined(HAVE_UNAME) + { + static int done_once = 0; + if (!done_once) + { + struct utsname uts; + struct stat st; + done_once = 1; + if (uname (&uts) == 0) + { + static char cmd[200]; + char *s; + /* strip version at the first non-digit-dash-dot, to + lose any "SMP" crap at the end. */ + for (s = uts.release; *s; s++) + if (!isdigit(*s) && *s != '.' && *s != '-') + *s = 0; + sprintf (cmd, "cat /usr/src/linux-%s/README", uts.release); + if (!stat (cmd+4, &st)) + oprogram = cmd; + else + { + /* kernel source not installed? try X... */ + strcpy (cmd, "cat /usr/X11R6/lib/X11/doc/README"); + if (!stat (cmd+4, &st)) + oprogram = cmd; + } + } + } + } +#endif /* __linux__ && HAVE_UNAME */ +#ifdef __APPLE__ /* MacOS X + XDarwin */ + { + static int done_once = 0; + if (!done_once) + { + struct stat st; + static char *cmd = "cat /usr/X11R6/README"; + if (!stat (cmd+4, &st)) + oprogram = cmd; + } + } +#endif /* __APPLE__ */ + } + + program = (char *) malloc (strlen (oprogram) + 10); strcpy (program, "( "); strcat (program, oprogram); strcat (program, " ) 2>&1"); @@ -285,12 +424,17 @@ get_more_lines (sws_configuration *sc) return; } - if (*s == '\n' || col > sc->columns) + if (*s == '\r' || *s == '\n' || col > sc->columns) { int L = s - sc->buf; - if (*s == '\n') - *s++ = 0; + if (*s == '\r' || *s == '\n') + { + if (*s == '\r' && s[1] == '\n') /* swallow CRLF too */ + *s++ = 0; + + *s++ = 0; + } else { /* We wrapped -- try to back up to the previous word boundary. */ @@ -309,10 +453,13 @@ get_more_lines (sws_configuration *sc) sc->lines[sc->total_lines] = (char *) malloc (L+1); memcpy (sc->lines[sc->total_lines], sc->buf, L); sc->lines[sc->total_lines][L] = 0; + latin1_to_ascii (sc->lines[sc->total_lines]); { char *t = sc->lines[sc->total_lines]; char *ut = untabify (t); + strip (ut, (alignment == 0), 1); /* if centering, strip + leading whitespace too */ sc->lines[sc->total_lines] = ut; free (t); } @@ -322,7 +469,7 @@ get_more_lines (sws_configuration *sc) if (sc->buf_tail > (s - sc->buf)) { int i = sc->buf_tail - (s - sc->buf); - memcpy (sc->buf, s, i); + memmove (sc->buf, s, i); sc->buf_tail = i; sc->buf[sc->buf_tail] = 0; } @@ -352,45 +499,40 @@ draw_string (int x, int y, const char *s) if (!s || !*s) return; glPushMatrix (); glTranslatef (x, y, 0); + while (*s) glutStrokeCharacter (GLUT_FONT, *s++); glPopMatrix (); } -#if 0 +#ifdef DEBUG static void grid (double width, double height, double spacing, double z) { double x, y; for (y = 0; y <= height/2; y += spacing) { - glBegin(GL_LINE_LOOP); + glBegin(GL_LINES); glVertex3f(-width/2, y, z); glVertex3f( width/2, y, z); - glEnd(); - glBegin(GL_LINE_LOOP); glVertex3f(-width/2, -y, z); glVertex3f( width/2, -y, z); glEnd(); } for (x = 0; x <= width/2; x += spacing) { - glBegin(GL_LINE_LOOP); + glBegin(GL_LINES); glVertex3f( x, -height/2, z); glVertex3f( x, height/2, z); - glEnd(); - glBegin(GL_LINE_LOOP); glVertex3f(-x, -height/2, z); glVertex3f(-x, height/2, z); glEnd(); } - glBegin(GL_LINE_LOOP); + glBegin(GL_LINES); glVertex3f(-width, 0, z); glVertex3f( width, 0, z); - glEnd(); - glBegin(GL_LINE_LOOP); glVertex3f(0, -height, z); glVertex3f(0, height, z); glEnd(); @@ -425,54 +567,124 @@ box (double width, double height, double depth) glEnd(); glEnd(); - glBegin(GL_LINE_LOOP); + glBegin(GL_LINES); glVertex3f(-width/2, height/2, depth/2); glVertex3f(-width/2, -height/2, -depth/2); - glEnd(); - glBegin(GL_LINE_LOOP); + glVertex3f( width/2, height/2, depth/2); glVertex3f( width/2, -height/2, -depth/2); - glEnd(); - glBegin(GL_LINE_LOOP); + glVertex3f(-width/2, -height/2, depth/2); glVertex3f(-width/2, height/2, -depth/2); - glEnd(); - glBegin(GL_LINE_LOOP); + glVertex3f( width/2, -height/2, depth/2); glVertex3f( width/2, height/2, -depth/2); glEnd(); } -#endif /* 0 */ +#endif /* DEBUG */ -/* Window management, etc - */ +/* Construct stars (number of stars is dependent on size of screen) */ static void -reshape (sws_configuration *sc, int width, int height) +init_stars (ModeInfo *mi, int width, int height) { - static Bool stars_done = False; + sws_configuration *sc = &scs[MI_SCREEN(mi)]; + int i, j; + int nstars = width * height / 320; + int max_size = 3; + GLfloat inc = 0.5; + int steps = max_size / inc; + + glDeleteLists (sc->star_list, 1); + sc->star_list = glGenLists (1); + glNewList (sc->star_list, GL_COMPILE); + + glEnable(GL_POINT_SMOOTH); - glViewport (0, 0, (GLint) width, (GLint) height); - if (!stars_done) + for (j = 1; j <= steps; j++) { - int i; - int nstars = width * height / 320; - glDeleteLists (sc->star_list, 1); - sc->star_list = glGenLists (1); - glNewList (sc->star_list, GL_COMPILE); + glPointSize(inc * j); glBegin (GL_POINTS); - for (i = 0; i < nstars; i++) + for (i = 0; i < nstars / steps; i++) { - GLfloat c = 0.6 + 0.3 * random() / RAND_MAX; - glColor3f (c, c, c); - glVertex3f (2 * width * (0.5 - 1.0 * random() / RAND_MAX), - 2 * height * (0.5 - 1.0 * random() / RAND_MAX), - 0.0); + glColor3f (0.6 + frand(0.3), + 0.6 + frand(0.3), + 0.6 + frand(0.3)); + glVertex2f (2 * width * (0.5 - frand(1.0)), + 2 * height * (0.5 - frand(1.0))); } glEnd (); - glEndList (); - stars_done = True; } + glEndList (); +} + + +/* Window management, etc + */ +void +reshape_sws (ModeInfo *mi, int width, int height) +{ + sws_configuration *sc = &scs[MI_SCREEN(mi)]; + + /* Set up matrices for perspective text display + */ + { + GLfloat desired_aspect = (GLfloat) 3/4; + int w = mi->xgwa.width; + int h = mi->xgwa.height; + +#ifdef KEEP_ASPECT + h = w * desired_aspect; +#endif + + glMatrixMode (GL_PROJECTION); + glViewport (0, 0, w, h); + + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + gluPerspective (80.0, 1/desired_aspect, 10, 500000); + gluLookAt (0.0, 0.0, 4600.0, + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0); + glRotatef (-60.0, 1.0, 0.0, 0.0); + + /* The above gives us an arena where the bottom edge of the screen is + represented by the line (-2100,-3140,0) - ( 2100,-3140,0). */ + + /* Now let's move the origin to the front of the screen. */ + glTranslatef (0.0, -3140, 0.0); + + /* And then let's scale so that the bottom of the screen is 1.0 wide. */ + glScalef (4200, 4200, 4200); + } + + + /* Compute the height in pixels of the line at the bottom of the screen. */ + { + GLdouble mm[17], pm[17]; + GLint vp[5]; + GLfloat x = 0.5, y1 = 0, z = 0; + GLfloat y2 = sc->line_height; + GLdouble wx=-1, wy1=-1, wy2=-1, wz=-1; + + glGetDoublev (GL_MODELVIEW_MATRIX, mm); + glGetDoublev (GL_PROJECTION_MATRIX, pm); + glGetIntegerv (GL_VIEWPORT, vp); + gluProject (x, y1, z, mm, pm, vp, &wx, &wy1, &wz); + gluProject (x, y2, z, mm, pm, vp, &wx, &wy2, &wz); + sc->line_pixel_height = (wy2 - wy1); + glLineWidth (1); + } + + /* Compute the best looking line thickness for the bottom line. + */ + if (!thick_p) + sc->line_thickness = 1.0; + else + sc->line_thickness = (GLfloat) sc->line_pixel_height / FONT_WEIGHT; + + if (sc->line_thickness < 1.2) + sc->line_thickness = 1.0; } @@ -483,11 +695,17 @@ gl_init (ModeInfo *mi) program = get_string_resource ("program", "Program"); - glMatrixMode (GL_MODELVIEW); - glDisable (GL_LIGHTING); glDisable (GL_DEPTH_TEST); + if (smooth_p) + { + glEnable (GL_LINE_SMOOTH); + glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable (GL_BLEND); + } + sc->text_list = glGenLists (1); glNewList (sc->text_list, GL_COMPILE); glEndList (); @@ -495,6 +713,8 @@ gl_init (ModeInfo *mi) sc->star_list = glGenLists (1); glNewList (sc->star_list, GL_COMPILE); glEndList (); + + sc->line_thickness = 1.0; } @@ -521,11 +741,11 @@ init_sws (ModeInfo *mi) if ((sc->glx_context = init_GL(mi)) != NULL) { gl_init(mi); - reshape(sc, MI_WIDTH(mi), MI_HEIGHT(mi)); + reshape_sws (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); + init_stars (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); } - font_height = GLUT_FONT->top - GLUT_FONT->bottom; sc->font_scale = 1.0 / glutStrokeWidth (GLUT_FONT, 'z'); /* 'n' seems too wide */ @@ -548,7 +768,6 @@ init_sws (ModeInfo *mi) sc->subproc_relaunch_delay = 2 * 1000; sc->total_lines = max_lines-1; - launch_text_generator (sc); if (random() & 1) star_spin = -star_spin; @@ -568,9 +787,40 @@ init_sws (ModeInfo *mi) progname, alignment_str); exit (1); } + + launch_text_generator (sc); + + /* one more reshape, after line_height has been computed */ + reshape_sws (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); } +static void +draw_stars (ModeInfo *mi) +{ + sws_configuration *sc = &scs[MI_SCREEN(mi)]; + + glMatrixMode (GL_PROJECTION); + glPushMatrix (); + { + glLoadIdentity (); + + glMatrixMode (GL_MODELVIEW); + glPushMatrix (); + { + glLoadIdentity (); + glOrtho (-0.5 * MI_WIDTH(mi), 0.5 * MI_WIDTH(mi), + -0.5 * MI_HEIGHT(mi), 0.5 * MI_HEIGHT(mi), + -100.0, 100.0); + glRotatef (sc->star_theta, 0.0, 0.0, 1.0); + glCallList (sc->star_list); + } + glPopMatrix (); + } + glMatrixMode (GL_PROJECTION); + glPopMatrix (); +} + void draw_sws (ModeInfo *mi) { @@ -590,33 +840,20 @@ draw_sws (ModeInfo *mi) glClear (GL_COLOR_BUFFER_BIT); - glPushMatrix (); + draw_stars (mi); - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); - glOrtho (-0.5 * MI_WIDTH(mi), 0.5 * MI_WIDTH(mi), - -0.5 * MI_HEIGHT(mi), 0.5 * MI_HEIGHT(mi), - -100.0, 100.0); - glRotatef (sc->star_theta, 0.0, 0.0, 1.0); - glCallList (sc->star_list); - - glLoadIdentity (); - gluPerspective (80.0, 4.0/3.0, 10, 500000); glMatrixMode (GL_MODELVIEW); - gluLookAt (0.0, 0.0, 4600.0, - 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0); - - glRotatef (-60.0, 1.0, 0.0, 0.0); - - /* The above gives us an arena where the bottom edge of the screen is - represented by the line (-2100,-3140,0) - ( 2100,-3140,0). */ - - /* Now let's move the origin to the front of the screen. */ - glTranslatef (0.0, -3140, 0.0); + glPushMatrix (); - /* And then let's scale so that the bottom of the screen is 1.0 wide. */ - glScalef (4200, 4200, 4200); +#ifdef DEBUG + glColor3f (0.4, 0.4, 0.4); + glLineWidth (1); + glTranslatef(0, 1, 0); + box (1, 1, 1); + glTranslatef(0, -1, 0); + box (1, 1, 1); + grid (1, 1, sc->line_height, 0); +#endif /* DEBUG */ /* Scroll to current position */ glTranslatef (0.0, sc->intra_line_scroll, 0.0); @@ -628,15 +865,6 @@ draw_sws (ModeInfo *mi) if (sc->intra_line_scroll >= sc->line_height) { - static time_t reshape_time = 0; - time_t now = time((time_t) 0); - if (reshape_time != now) /* only poll for reshape once a second */ - { - reshape_time = now; - XGetWindowAttributes (dpy, window, &mi->xgwa); - reshape(sc, MI_WIDTH(mi), MI_HEIGHT(mi)); - } - sc->intra_line_scroll = 0; /* Drop the oldest line off the end. */ @@ -674,19 +902,47 @@ draw_sws (ModeInfo *mi) * sc->line_height); double xoff = 0; char *line = sc->lines[i]; -#if 0 +#ifdef DEBUG char n[20]; sprintf(n, "%d:", i); draw_string (x / sc->font_scale, y / sc->font_scale, n); -#endif +#endif /* DEBUG */ if (!line || !*line) continue; + if (sc->line_thickness != 1) + { + int max_thick_lines = MAX_THICK_LINES; + GLfloat thinnest_line = 1.0; + GLfloat thickest_line = sc->line_thickness; + GLfloat range = thickest_line - thinnest_line; + GLfloat thickness; + + int j = sc->total_lines - i - 1; + + if (j > max_thick_lines) + thickness = thinnest_line; + else + thickness = (thinnest_line + + (range * ((max_thick_lines - j) / + (GLfloat) max_thick_lines))); + + glLineWidth (thickness); + } + if (alignment >= 0) - xoff = 1.0 - (glutStrokeLength(GLUT_FONT, line) * sc->font_scale); + xoff = 1.0 - (glutStrokeLength(GLUT_FONT, + (unsigned char *) line) + * sc->font_scale); if (alignment == 0) xoff /= 2; + if (fade_p) + { + double factor = 1.0 * i / sc->total_lines; + glColor3f (factor, factor, 0.5 * factor); + } + draw_string ((x + xoff) / sc->font_scale, y / sc->font_scale, line); } glPopMatrix (); @@ -695,6 +951,7 @@ draw_sws (ModeInfo *mi) glPopMatrix (); + if (mi->fps_p) do_fps (mi); glFinish(); glXSwapBuffers(dpy, window);