diff options
Diffstat (limited to 'hacks/glx/starwars.c')
| -rw-r--r-- | hacks/glx/starwars.c | 1082 |
1 files changed, 0 insertions, 1082 deletions
diff --git a/hacks/glx/starwars.c b/hacks/glx/starwars.c deleted file mode 100644 index fbdf39d..0000000 --- a/hacks/glx/starwars.c +++ /dev/null @@ -1,1082 +0,0 @@ -/* starwars, Copyright (c) 1998-2018 Jamie Zawinski <jwz@jwz.org> and - * Claudio Matsuoka <claudio@helllabs.org> - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation. No representations are made about the suitability of this - * software for any purpose. It is provided "as is" without express or - * implied warranty. - * - * Star Wars -- Phosphor meets a well-known scroller from a galaxy far, - * far away. - * - * Feb 2000 Claudio Matsuoka First version. - * Jan 2001 Jamie Zawinski Rewrote large sections to add the ability to - * run a subprocess, customization of the font - * size and other parameters, etc. - * Feb 2001 jepler@inetnebr.com Added anti-aliased lines, and fade-to-black. - * Feb 2005 Jamie Zawinski Added texture fonts. - * - * - * For the fanboys: - * - * starwars -program 'cat starwars.txt' -columns 25 -no-wrap - */ - -#define DEFAULTS "*delay: 40000 \n" \ - "*showFPS: False \n" \ - "*fpsTop: True \n" \ - "*usePty: False \n" \ - "*texFontCacheSize: 300\n" \ - "*font: " DEF_FONT "\n" \ - "*textLiteral: " DEF_TEXT "\n" \ - "*program: xscreensaver-text --cols 0" /* don't wrap */ - -# define release_sws 0 -# define sws_handle_event xlockmore_no_events - -#include "xlockmore.h" -#include "textclient.h" -#include "utf8wc.h" -#include "starwars.h" - -#include <ctype.h> -#include <sys/stat.h> - -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif - -#ifdef USE_GL /* whole file */ - -/* Should be in <GL/glext.h> */ -# ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT -# define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE -# endif -# ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT -# define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF -# endif - - -#define DEF_LINES "125" -#define DEF_STEPS "35" -#define DEF_SPIN "0.03" -#define DEF_SATURATION "0.3" -#define DEF_SIZE "-1" -#define DEF_COLUMNS "-1" -#define DEF_LINE_WRAP "True" -#define DEF_ALIGNMENT "Center" -#define DEF_SMOOTH "True" -#define DEF_THICK "True" -#define DEF_FADE "True" -#define DEF_TEXTURES "True" -#define DEF_DEBUG "False" -#define DEF_FONT "sans-serif 36" - -#define TAB_WIDTH 8 - -#define MAX_THICK_LINES 25 -#define FONT_WEIGHT 14 - -#ifndef HAVE_MOBILE -# define KEEP_ASPECT /* Letterboxing looks dumb on iPhone. */ -#endif - -#include "texfont.h" -#include "glutstroke.h" -#include "glut_roman.h" -#define GLUT_FONT (&glutStrokeRoman) - -typedef struct { - Display *dpy; - GLXContext *glx_context; - - GLuint text_list, star_list; - texture_font_data *texfont; - text_data *tc; - - char *buf; - int buf_size; - int buf_tail; - - char **lines; - int *line_widths; - int total_lines; - - double star_theta; - double char_width; - double line_height; - double descent; - double font_scale; - double intra_line_scroll; - - int line_pixel_width; /* in font units (for wrapping text) */ - int line_pixel_height; /* in screen units (for computing line thickness) */ - GLfloat line_thickness; - -} sws_configuration; - - -static sws_configuration *scs = NULL; - -static int max_lines; -static int scroll_steps; -static float star_spin; -static float star_saturation; -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 int textures_p; -static int debug_p; -static char *alignment_str; -static int alignment; - -static XrmOptionDescRec opts[] = { - {"-lines", ".lines", XrmoptionSepArg, 0 }, - {"-steps", ".steps", XrmoptionSepArg, 0 }, - {"-spin", ".spin", XrmoptionSepArg, 0 }, - {"-saturation", ".saturation",XrmoptionSepArg, 0 }, - {"-size", ".size", XrmoptionSepArg, 0 }, - {"-columns", ".columns", XrmoptionSepArg, 0 }, -/*{"-font", ".font", XrmoptionSepArg, 0 },*/ - {"-program", ".program", XrmoptionSepArg, 0 }, - {"-fade", ".fade", XrmoptionNoArg, "True" }, - {"-no-fade", ".fade", XrmoptionNoArg, "False" }, - {"-textures", ".textures", XrmoptionNoArg, "True" }, - {"-smooth", ".smooth", XrmoptionNoArg, "True" }, - {"-no-smooth", ".smooth", XrmoptionNoArg, "False" }, - {"-thick", ".thick", XrmoptionNoArg, "True" }, - {"-no-thick", ".thick", XrmoptionNoArg, "False" }, - {"-no-textures", ".textures", XrmoptionNoArg, "False" }, - {"-wrap", ".lineWrap", XrmoptionNoArg, "True" }, - {"-no-wrap", ".lineWrap", XrmoptionNoArg, "False" }, - {"-nowrap", ".lineWrap", XrmoptionNoArg, "False" }, - {"-alignment", ".alignment", XrmoptionSepArg, 0 }, - {"-left", ".alignment", XrmoptionNoArg, "Left" }, - {"-right", ".alignment", XrmoptionNoArg, "Right" }, - {"-center", ".alignment", XrmoptionNoArg, "Center" }, - {"-debug", ".debug", XrmoptionNoArg, "True" }, -}; - -static argtype vars[] = { - {&max_lines, "lines", "Integer", DEF_LINES, t_Int}, - {&scroll_steps, "steps", "Integer", DEF_STEPS, t_Int}, - {&star_spin, "spin", "Float", DEF_SPIN, t_Float}, - {&star_saturation,"saturation","Float", DEF_SATURATION,t_Float}, - {&font_size, "size", "Float", DEF_SIZE, t_Float}, - {&target_columns, "columns", "Integer", DEF_COLUMNS, t_Int}, - {&wrap_p, "lineWrap", "Boolean", DEF_LINE_WRAP, t_Bool}, - {&alignment_str, "alignment", "Alignment", DEF_ALIGNMENT, 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}, - {&textures_p, "textures", "Boolean", DEF_TEXTURES, t_Bool}, - {&debug_p, "debug", "Boolean", DEF_DEBUG, t_Bool}, -}; - -ENTRYPOINT ModeSpecOpt sws_opts = {countof(opts), opts, countof(vars), vars, NULL}; - - - -/* Tabs are bad, mmmkay? */ - -static char * -untabify (const char *string) -{ - const char *ostring = string; - char *result = (char *) malloc ((strlen(string) * 8) + 1); - char *out = result; - int col = 0; - while (*string) - { - if (*string == '\t') - { - do { - col++; - *out++ = ' '; - } while (col % TAB_WIDTH); - string++; - } - else if (*string == '\r' || *string == '\n') - { - *out++ = *string++; - col = 0; - } - else if (*string == '\010') /* backspace */ - { - if (string > ostring) - out--, string++; - } - else - { - *out++ = *string++; - col++; - } - } - *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; - } -} - - -static int -sw_string_width (sws_configuration *sc, const char *s) -{ - if (textures_p) - { - XCharStruct e; - texture_string_metrics (sc->texfont, s, &e, 0, 0); - return e.width; - } - else - return glutStrokeLength (GLUT_FONT, (unsigned char *) s); -} - - -static int -sw_string_width2 (sws_configuration *sc, const char *s, size_t size) -{ - char *s2 = (char *) malloc (size + 1); - int result; - - strncpy (s2, s, size); - s2[size] = 0; - - result = sw_string_width (sc, s2); - - free (s2); - return result; -} - - -/* Populates the sc->lines list with as many lines as possible. - */ -static void -get_more_lines (sws_configuration *sc) -{ - /* wrap anyway, if it's absurdly long. */ - int wrap_pix = (wrap_p ? sc->line_pixel_width : 10000); - - char *s = sc->buf; - - int target = sc->buf_size - sc->buf_tail - 2; - - /* Fill as much as we can into sc->buf. - */ - while (target > 0) - { - int c = textclient_getc (sc->tc); - if (c <= 0) - break; - sc->buf[sc->buf_tail++] = (char) c; - sc->buf[sc->buf_tail] = 0; - target--; - } - - while (sc->total_lines < max_lines) - { - char *next_s = s; - unsigned counter = 0; - - /* OS X is really slow to calcuate the bounds for a line of text, - so skip ahead a bit. - - Really though, the right thing to do is probably to wrap - CTLineCreateTruncatedLine, one way or another. */ - for (;;) - { - if (next_s >= sc->buf + sc->buf_tail) - break; - - if (!counter) - { - if (s > sc->buf && - sw_string_width2 (sc, sc->buf, next_s - sc->buf) >= wrap_pix) - break; - - counter = 12; /* <-- Adjust to taste. */ - s = next_s; - } - - if (*next_s == '\r' || *next_s == '\n') - break; - - --counter; - ++next_s; - } - - for (;;) - { - if (s >= sc->buf + sc->buf_tail) - /* Reached end of buffer before end of line. Bail. */ - return; - - /* When checking pixel width, always measure the line from the - beginning, or else multi-byte UTF-8 characters, particularly - combining diacriticals, aren't measured right. */ - - if (*s == '\r' || *s == '\n' || - (s > sc->buf && sw_string_width2 (sc, sc->buf, s - sc->buf) >= wrap_pix)) - { - int L = s - sc->buf; - - 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. */ - char *s2 = s; - int n = 0; - while (s2 > sc->buf && *s2 != ' ' && *s2 != '\t') - s2--, n++; - if (s2 > sc->buf) - { - s = s2; - *s++ = 0; - L = s - sc->buf; - } - } - - 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; - - if (!textures_p) - { - /* The GLUT font only has ASCII characters. */ - char *s1 = utf8_to_latin1 (sc->lines[sc->total_lines], True); - free (sc->lines[sc->total_lines]); - sc->lines[sc->total_lines] = s1; - } - - { - 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); - } - - sc->line_widths[sc->total_lines] = - sw_string_width(sc, sc->lines[sc->total_lines]); - - sc->total_lines++; - - if (sc->buf_tail > (s - sc->buf)) - { - int i = sc->buf_tail - (s - sc->buf); - memmove (sc->buf, s, i); - sc->buf_tail = i; - sc->buf[sc->buf_tail] = 0; - } - else - { - sc->buf_tail = 0; - } - - sc->buf[sc->buf_tail] = 0; - s = sc->buf; - - break; - } - else - { - s++; - } - } - } -} - - -static void -draw_string (sws_configuration *sc, GLfloat x, GLfloat y, const char *s) -{ - const char *os = s; - if (!s || !*s) return; - glPushMatrix (); - glTranslatef (x, y, 0); - - if (textures_p) - print_texture_string (sc->texfont, s); - else - while (*s) - glutStrokeCharacter (GLUT_FONT, *s++); - glPopMatrix (); - - if (debug_p) - { - GLfloat h = sc->line_height / sc->font_scale; - char **chars = utf8_split (os, 0); - int i, w = 0; - char *s2 = (char *) malloc (strlen(s) + 1); - *s2 = 0; - - if (textures_p) glDisable (GL_TEXTURE_2D); - glLineWidth (1); - - glColor3f (0.2, 0.2, 0.5); - - glBegin (GL_LINES); - - for (i = 0; chars[i]; i++) - { - glVertex3f (x + w, y - sc->descent, 0); /* char left */ - glVertex3f (x + w, y - sc->descent + h, 0); - strcat (s2, chars[i]); - w = sw_string_width (sc, s2); - free (chars[i]); - } - - glVertex3f (x + w, y - sc->descent, 0); /* char right */ - glVertex3f (x + w, y - sc->descent + h, 0); - - glVertex3f (x, y - sc->descent + h, 0); /* ascent */ - glVertex3f (x + w, y - sc->descent + h, 0); - - glVertex3f (x - sc->char_width, y, 0); /* baseline */ - glVertex3f (x + sc->char_width + w, y, 0); - - glVertex3f (x, y - sc->descent, 0); /* descent */ - glVertex3f (x + w, y - sc->descent, 0); - - glEnd(); - - free (s2); - free (chars); - - if (textures_p) glEnable (GL_TEXTURE_2D); - } -} - - -static void -grid (double width, double height, double xspacing, double yspacing, double z) -{ - double x, y; - for (y = 0; y <= height/2; y += yspacing) - { - glBegin(GL_LINES); - glVertex3f(-width/2, y, z); - glVertex3f( width/2, y, z); - glVertex3f(-width/2, -y, z); - glVertex3f( width/2, -y, z); - glEnd(); - } - for (x = 0; x <= width/2; x += xspacing) - { - glBegin(GL_LINES); - glVertex3f( x, -height/2, z); - glVertex3f( x, height/2, z); - glVertex3f(-x, -height/2, z); - glVertex3f(-x, height/2, z); - glEnd(); - } - - glBegin(GL_LINES); - glVertex3f(-width, 0, z); - glVertex3f( width, 0, z); - glVertex3f(0, -height, z); - glVertex3f(0, height, z); - glEnd(); -} - -static void -box (double width, double height, double depth) -{ - glBegin(GL_LINE_LOOP); - glVertex3f(-width/2, -height/2, -depth/2); - glVertex3f(-width/2, height/2, -depth/2); - 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); - 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); - 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); - glVertex3f( width/2, height/2, depth/2); - glVertex3f( width/2, height/2, -depth/2); - glEnd(); - - glBegin(GL_LINES); - glVertex3f(-width/2, height/2, depth/2); - glVertex3f(-width/2, -height/2, -depth/2); - - glVertex3f( width/2, height/2, depth/2); - glVertex3f( width/2, -height/2, -depth/2); - - glVertex3f(-width/2, -height/2, depth/2); - glVertex3f(-width/2, height/2, -depth/2); - - glVertex3f( width/2, -height/2, depth/2); - glVertex3f( width/2, height/2, -depth/2); - glEnd(); -} - - -/* Construct stars (number of stars is dependent on size of screen) */ -static void -init_stars (ModeInfo *mi, int width, int height) -{ - sws_configuration *sc = &scs[MI_SCREEN(mi)]; - int i, j; - int size = (width > height ? width : height); - int nstars = size * size / 320; - int max_size = 3; - GLfloat inc = 0.5; - int steps = max_size / inc; - GLfloat scale = 1; - - if (MI_WIDTH(mi) > 2560) { /* Retina displays */ - scale *= 2; - nstars = (size/scale) * (size/scale) / 320; - } - - glDeleteLists (sc->star_list, 1); - sc->star_list = glGenLists (1); - glNewList (sc->star_list, GL_COMPILE); - - glEnable(GL_POINT_SMOOTH); - - for (j = 1; j <= steps; j++) - { - glPointSize(inc * j * scale); - glBegin (GL_POINTS); - for (i = 0; i < nstars / steps; i++) - { - GLfloat brightness = 0.9 - star_saturation; - glColor3f (brightness + frand(star_saturation), - brightness + frand(star_saturation), - brightness + frand(star_saturation)); - glVertex2f (2 * size * (0.5 - frand(1.0)), - 2 * size * (0.5 - frand(1.0))); - } - glEnd (); - } - glEndList (); -} - - -/* Window management, etc - */ -ENTRYPOINT 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; - int yoff = 0; - GLfloat rot = current_device_rotation(); - -#ifdef KEEP_ASPECT - { - int h2 = w * desired_aspect; - yoff = (h - h2) / 2; /* Wide window: letterbox at top and bottom. */ - if (yoff < 0) yoff = 0; /* Tall window: clip off the top. */ - h = h2; - } -#endif - - glViewport (0, yoff, w, h); - - glMatrixMode (GL_PROJECTION); - glLoadIdentity(); - - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); - gluPerspective (80.0, 1/desired_aspect, 1000, 55000); - gluLookAt (0.0, 0.0, 4600.0, - 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0); - - /* Horrible kludge to prevent the text from materializing already - on screen on iPhone in landscape mode. - */ - if ((rot > 45 && rot < 135) || - (rot < -45 && rot > -135)) - { - GLfloat s = 1.1; - glScalef (s, s, s); - } - - glRotatef (-60.0, 1.0, 0.0, 0.0); - -#if 0 - glRotatef (60.0, 1.0, 0.0, 0.0); - glTranslatef (260, 3200, 0); - glScalef (1.85, 1.85, 1); -#endif - - /* 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]; - GLdouble x = 0.5, y1 = 0, z = 0; - GLdouble 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; -} - - -static void -gl_init (ModeInfo *mi) -{ - sws_configuration *sc = &scs[MI_SCREEN(mi)]; - - 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 (); - - sc->star_list = glGenLists (1); - glNewList (sc->star_list, GL_COMPILE); - glEndList (); - - sc->line_thickness = 1.0; -} - - -ENTRYPOINT void -init_sws (ModeInfo *mi) -{ - double font_height; - - sws_configuration *sc = 0; - - MI_INIT (mi, scs); - - sc = &scs[MI_SCREEN(mi)]; - - sc->dpy = MI_DISPLAY(mi); - sc = &scs[MI_SCREEN(mi)]; - /* Unchecked malloc. :( */ - sc->lines = (char **) calloc (max_lines+1, sizeof(char *)); - sc->line_widths = (int *) calloc (max_lines+1, sizeof(int)); - - if ((sc->glx_context = init_GL(mi)) != NULL) { - gl_init(mi); - reshape_sws (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - clear_gl_error(); /* WTF? sometimes "invalid op" from glViewport! */ - - init_stars (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - } - - if (textures_p) - { - XCharStruct e; - int cw, ascent, descent; - sc->texfont = load_texture_font (MI_DISPLAY(mi), "font"); - texture_string_metrics (sc->texfont, "n", &e, &ascent, &descent); - cw = e.width; - sc->char_width = cw; - font_height = ascent + descent; - sc->descent = descent; - glEnable(GL_ALPHA_TEST); - glEnable (GL_TEXTURE_2D); - - check_gl_error ("loading font"); - - /* "Anistropic filtering helps for quadrilateral-angled textures. - A sharper image is accomplished by interpolating and filtering - multiple samples from one or more mipmaps to better approximate - very distorted textures. This is the next level of filtering - after trilinear filtering." */ - if (smooth_p && - strstr ((char *) glGetString(GL_EXTENSIONS), - "GL_EXT_texture_filter_anisotropic")) - { - GLfloat anisotropic = 0.0; - glGetFloatv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &anisotropic); - if (anisotropic >= 1.0) - glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, - anisotropic); - } - } - else - { - font_height = GLUT_FONT->top - GLUT_FONT->bottom; - sc->char_width = glutStrokeWidth (GLUT_FONT, 'z'); /* 'n' seems wide */ - sc->descent = 0; - } - - sc->font_scale = 1.0 / sc->char_width; - - - /* We consider a font that consumes 80 columns to be "18 points". - - If neither -size nor -columns was specified, default to 60 columns - (which is 24 points.) - - If both were specified, -columns has priority. - */ - { - int base_col = 80; - int base_size = 18; - - if (target_columns <= 0 && font_size <= 0) - target_columns = 60; - - if (target_columns > 0) - font_size = base_size * (base_col / (double) target_columns); - else if (font_size > 0) - target_columns = base_col * (base_size / (double) font_size); - } - - sc->line_pixel_width = target_columns * sc->char_width; - - sc->font_scale /= target_columns; - sc->line_height = font_height * sc->font_scale; - - /* Buffer only a few lines of text. - If the buffer is too big, there's a significant delay between - when the program launches and when the text appears, which can be - irritating for time-sensitive output (clock, current music, etc.) - - I'd like to buffer only 2 lines, but we need to assume that we - could get a whole line of N-byte Unicrud, and if we fill the buffer - before hitting the end of the line, we stall. - */ - sc->buf_size = target_columns * 2 * 4; - if (sc->buf_size < 80) sc->buf_size = 80; - sc->buf = (char *) calloc (1, sc->buf_size); - - sc->total_lines = max_lines-1; - - if (random() & 1) - star_spin = -star_spin; - - if (!alignment_str || !*alignment_str || - !strcasecmp(alignment_str, "left")) - alignment = -1; - else if (!strcasecmp(alignment_str, "center") || - !strcasecmp(alignment_str, "middle")) - alignment = 0; - else if (!strcasecmp(alignment_str, "right")) - alignment = 1; - else - { - fprintf (stderr, - "%s: alignment must be left, center, or right, not \"%s\"\n", - progname, alignment_str); - exit (1); - } - - sc->tc = textclient_open (sc->dpy); - - /* 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); - if (textures_p) glDisable (GL_TEXTURE_2D); - - glCallList (sc->star_list); - if (textures_p) glEnable (GL_TEXTURE_2D); - } - glPopMatrix (); - } - glMatrixMode (GL_PROJECTION); - glPopMatrix (); -} - -ENTRYPOINT void -draw_sws (ModeInfo *mi) -{ - sws_configuration *sc = &scs[MI_SCREEN(mi)]; -/* XtAppContext app = XtDisplayToApplicationContext (sc->dpy);*/ - Display *dpy = MI_DISPLAY(mi); - Window window = MI_WINDOW(mi); - int i; - - if (!sc->glx_context) - return; - - glDrawBuffer (GL_BACK); - glXMakeCurrent (dpy, window, *sc->glx_context); - - glClear (GL_COLOR_BUFFER_BIT); - - draw_stars (mi); - - glMatrixMode (GL_MODELVIEW); - glPushMatrix (); - -# ifdef HAVE_MOBILE - /* Need to do this every time to get device rotation right */ - reshape_sws (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); -# endif - - if (debug_p) - { - int i; - glPushMatrix (); - if (textures_p) glDisable (GL_TEXTURE_2D); - glLineWidth (1); - glTranslatef (0,-1, 0); - - glColor3f(1, 0, 0); /* Red line is where text appears */ - glPushMatrix(); - glTranslatef(0, -0.028, 0); - glLineWidth (4); - glBegin(GL_LINES); - glVertex3f(-0.5, 1, 0); - glVertex3f( 0.5, 1, 0); - glVertex3f(-0.5, -1, 0); - glVertex3f( 0.5, -1, 0); - glEnd(); - glLineWidth (1); - glPopMatrix(); - - glColor3f (0.2, 0.2, 0.2); - for (i = 0; i < 16; i++) - { - box (1, 1, 1); - grid (1, 1, sc->char_width * sc->font_scale, sc->line_height, 0); - glTranslatef(0, 1, 0); - } - if (textures_p) glEnable (GL_TEXTURE_2D); - glPopMatrix (); - check_gl_error ("debug render"); - } - - /* Scroll to current position */ - glTranslatef (0.0, sc->intra_line_scroll, 0.0); - - glColor3f (1.0, 1.0, 0.4); - - mi->polygon_count = 0; - - glPushMatrix (); - glScalef (sc->font_scale, sc->font_scale, sc->font_scale); - for (i = 0; i < sc->total_lines; i++) - { - double fade = (fade_p ? 1.0 * i / sc->total_lines : 1.0); - int offscreen_lines = 2; - - double x = -0.5; - double y = ((sc->total_lines - (i + offscreen_lines) - 1) - * sc->line_height); - double xoff = 0; - char *line = sc->lines[i]; - - if (debug_p) - { - double xx = x * 1.4; /* a little more to the left */ - char n[20]; - sprintf(n, "%d:", i); - glColor3f (1.0, 1.0, 1.0); - draw_string (sc, xx / sc->font_scale, y / sc->font_scale, n); - } - - if (!line || !*line) - continue; - - if (sc->line_thickness != 1 && !textures_p) - { - 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) - { - int n = sc->line_widths[i]; - xoff = 1.0 - (n * sc->font_scale); - } - - if (alignment == 0) - xoff /= 2; - - glColor3f (fade, fade, 0.5 * fade); - draw_string (sc, (x + xoff) / sc->font_scale, y / sc->font_scale, - line); - if (textures_p) - mi->polygon_count += strlen (line); - } - glPopMatrix (); - - - - sc->intra_line_scroll += sc->line_height / scroll_steps; - - if (sc->intra_line_scroll >= sc->line_height) - { - sc->intra_line_scroll = 0; - - /* Drop the oldest line off the end. */ - if (sc->lines[0]) - free (sc->lines[0]); - - /* Scroll the contents of the lines array toward 0. */ - if (sc->total_lines > 0) - { - for (i = 1; i < sc->total_lines; i++) { - sc->lines[i-1] = sc->lines[i]; - sc->line_widths[i-1] = sc->line_widths[i]; - } - sc->lines[--sc->total_lines] = 0; - } - - /* Bring in new lines at the end. */ - get_more_lines (sc); - - if (sc->total_lines < max_lines) - /* Oops, we ran out of text... well, insert some blank lines - here so that new text still pulls in from the bottom of - the screen, isntead of just appearing. */ - sc->total_lines = max_lines; - } - - glPopMatrix (); - - if (mi->fps_p) do_fps (mi); - glFinish(); - glXSwapBuffers(dpy, window); - - sc->star_theta += star_spin; -} - -ENTRYPOINT void -free_sws (ModeInfo *mi) -{ - sws_configuration *sc = &scs[MI_SCREEN(mi)]; - int i; - if (!sc->glx_context) return; - glXMakeCurrent (MI_DISPLAY(mi), MI_WINDOW(mi), *sc->glx_context); - if (sc->tc) textclient_close (sc->tc); - if (sc->texfont) free_texture_font (sc->texfont); - if (sc->buf) free (sc->buf); - if (sc->line_widths) free (sc->line_widths); - for (i = 0; i < sc->total_lines; i++) - if (sc->lines[i]) free (sc->lines[i]); - if (sc->lines) free (sc->lines); - if (glIsList(sc->star_list)) glDeleteLists(sc->star_list, 1); - if (glIsList(sc->text_list)) glDeleteLists(sc->text_list, 1); -} - - -#ifdef __GNUC__ - __extension__ /* don't warn about "string length is greater than the length - ISO C89 compilers are required to support" when including - "starwars.txt" in the defaults... */ -#endif - -XSCREENSAVER_MODULE_2 ("StarWars", starwars, sws) - -#endif /* USE_GL */ |
