summaryrefslogtreecommitdiffstats
path: root/hacks/glx/gibson.c
diff options
context:
space:
mode:
authorSimon Rettberg2024-09-06 14:42:37 +0200
committerSimon Rettberg2024-09-06 14:42:37 +0200
commitbadef32037f52f79abc1f1440b786cd71afdf270 (patch)
tree412b792d4cab4a7a110db82fcf74fe8a1ac55ec1 /hacks/glx/gibson.c
parentDelete pre-6.00 files (diff)
downloadxscreensaver-master.tar.gz
xscreensaver-master.tar.xz
xscreensaver-master.zip
Diffstat (limited to 'hacks/glx/gibson.c')
-rw-r--r--hacks/glx/gibson.c1333
1 files changed, 0 insertions, 1333 deletions
diff --git a/hacks/glx/gibson.c b/hacks/glx/gibson.c
deleted file mode 100644
index e90d8d2..0000000
--- a/hacks/glx/gibson.c
+++ /dev/null
@@ -1,1333 +0,0 @@
-/* gibson, Copyright (c) 2020-2021 Jamie Zawinski <jwz@jwz.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.
- *
- * Hacking the Gibson, as per the 1995 classic film, HACKERS.
- *
- * In the movie, this was primarily a practical effect: the towers were
- * edge-lit etched perspex, each about four feet tall.
- */
-
-#define TOWER_FONT "sans-serif bold 48"
-
-#define DEFAULTS "*delay: 20000 \n" \
- "*groundColor: #8A2BE2" "\n" \
- "*towerColor: #4444FF" "\n" \
- "*towerText: #DDDDFF" "\n" \
- "*towerText2: #FF0000" "\n" \
- "*towerFont: " TOWER_FONT "\n" \
- "*showFPS: False \n" \
- "*wireframe: False \n" \
-
-# define release_gibson 0
-
-#include "xlockmore.h"
-#include "colors.h"
-#include "rotator.h"
-#include "texfont.h"
-#include <ctype.h>
-
-#ifdef USE_GL /* whole file */
-
-
-#define DEF_SPEED "1.0"
-#define DEF_TEXTURE "True"
-#define DEF_GRID_WIDTH "6"
-#define DEF_GRID_HEIGHT "7"
-#define DEF_GRID_DEPTH "6"
-#define DEF_GRID_SPACING "2.0"
-#define DEF_COLUMNS "5"
-
-#define GROUND_QUAD_SIZE 30
-
-typedef struct {
- GLfloat x, y, h;
- GLuint fg_dlists[5], bg_dlists[5];
- int fg_polys, bg_polys;
- unsigned int face_mode; /* 5 bit field */
-} tower;
-
-typedef struct {
- GLXContext *glx_context;
- Bool button_down_p;
- rotator *rot, *rot2;
- GLfloat xscroll, yscroll;
- GLfloat oxscroll, oyscroll;
-
- GLuint ground_dlist;
- GLuint tower_dlist;
- int ground_polys, tower_polys;
- GLfloat ground_y;
- GLfloat billboard_y;
- const char *billboard_text;
-
- int ntowers;
- tower *towers;
- GLfloat tower_color[4];
- GLfloat tower_color2[4];
- GLfloat edge_color[4];
- GLfloat bg_color[4];
- Bool startup_p;
-
- struct {
- GLuint texid;
- XCharStruct metrics;
- int width, height;
- texture_font_data *font_data;
- int ascent, descent, em_width;
- char *text;
- } text[2];
-
-} gibson_configuration;
-
-static gibson_configuration *ccs = NULL;
-
-static GLfloat speed;
-static Bool do_tex;
-static int grid_width;
-static int grid_height;
-static int grid_depth;
-static GLfloat grid_spacing;
-static int columns;
-
-static XrmOptionDescRec opts[] = {
- { "-speed", ".speed", XrmoptionSepArg, 0 },
- { "-texture", ".texture", XrmoptionNoArg, "True" },
- { "+texture", ".texture", XrmoptionNoArg, "False" },
- { "-grid-width", ".gridWidth", XrmoptionSepArg, 0 },
- { "-grid-height", ".gridHeight", XrmoptionSepArg, 0 },
- { "-grid-depth", ".gridDepth", XrmoptionSepArg, 0 },
- { "-spacing", ".gridSpacing", XrmoptionSepArg, 0 },
- { "-columns", ".columns", XrmoptionSepArg, 0 },
-};
-
-static argtype vars[] = {
- {&speed, "speed", "Speed", DEF_SPEED, t_Float},
- {&do_tex, "texture", "Texture", DEF_TEXTURE, t_Bool},
- {&grid_width, "gridWidth", "GridWidth", DEF_GRID_WIDTH, t_Int},
- {&grid_height, "gridHeight", "GridHeight", DEF_GRID_HEIGHT, t_Int},
- {&grid_depth, "gridDepth", "GridDepth", DEF_GRID_DEPTH, t_Int},
- {&grid_spacing, "gridSpacing", "GridSpacing", DEF_GRID_SPACING, t_Float},
- {&columns, "columns", "Columns", DEF_COLUMNS, t_Int},
-};
-
-ENTRYPOINT ModeSpecOpt gibson_opts = {
- countof(opts), opts, countof(vars), vars, NULL};
-
-
-ENTRYPOINT void
-reshape_gibson (ModeInfo *mi, int width, int height)
-{
- GLfloat h = (GLfloat) height / (GLfloat) width;
- int y = 0;
-
- glViewport (0, y, (GLint) width, (GLint) height);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-# ifdef DEBUG
- gluPerspective (30, 1/h, 1, 100);
-# else
- gluPerspective (100, 1/h/4,
- 1.0,
- 20 * grid_depth * 1.5 * (1 + grid_spacing));
-# endif
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- gluLookAt( 0, 0, 1,
- 0, 0, 0,
- 0, 1, 0);
-
- glClear(GL_COLOR_BUFFER_BIT);
-}
-
-
-/* Copied from gltrackball.c */
-static void
-adjust_for_device_rotation (double *x, double *y, double *w, double *h)
-{
- int rot = (int) current_device_rotation();
- int swap;
-
- while (rot <= -180) rot += 360;
- while (rot > 180) rot -= 360;
-
- if (rot > 135 || rot < -135) /* 180 */
- {
- *x = *w - *x;
- *y = *h - *y;
- }
- else if (rot > 45) /* 90 */
- {
- swap = *x; *x = *y; *y = swap;
- swap = *w; *w = *h; *h = swap;
- *x = *w - *x;
- }
- else if (rot < -45) /* 270 */
- {
- swap = *x; *x = *y; *y = swap;
- swap = *w; *w = *h; *h = swap;
- *y = *h - *y;
- }
-}
-
-
-ENTRYPOINT Bool
-gibson_handle_event (ModeInfo *mi, XEvent *event)
-{
- gibson_configuration *bp = &ccs[MI_SCREEN(mi)];
- double w = MI_WIDTH(mi);
- double h = MI_HEIGHT(mi);
- double xoff = 0, yoff = 0;
-
- if (event->xany.type == ButtonPress ||
- event->xany.type == ButtonRelease)
- {
- double x = event->xbutton.x;
- double y = event->xbutton.y;
- adjust_for_device_rotation (&x, &y, &w, &h);
- xoff = (x / w) - 0.5;
- yoff = (event->xbutton.y / h) - 0.5;
- bp->button_down_p = (event->xany.type == ButtonPress);
- bp->oxscroll = xoff;
- bp->oyscroll = yoff;
-
- return True;
- }
- else if (event->xany.type == MotionNotify)
- {
- double x = event->xmotion.x;
- double y = event->xmotion.y;
- adjust_for_device_rotation (&x, &y, &w, &h);
- xoff = (x / w) - 0.5;
- yoff = (y / h) - 0.5;
- if (bp->button_down_p)
- {
- bp->xscroll += xoff - bp->oxscroll;
- bp->yscroll += yoff - bp->oyscroll;
- bp->oxscroll = xoff;
- bp->oyscroll = yoff;
- }
- return True;
- }
-
- return False;
-}
-
-
-static void
-parse_color (ModeInfo *mi, char *key, GLfloat color[4])
-{
- XColor xcolor;
- char *string = get_string_resource (mi->dpy, key, "Color");
- if (!XParseColor (mi->dpy, mi->xgwa.colormap, string, &xcolor))
- {
- fprintf (stderr, "%s: unparsable color in %s: %s\n", progname,
- key, string);
- exit (1);
- }
- free (string);
-
- color[0] = xcolor.red / 65536.0;
- color[1] = xcolor.green / 65536.0;
- color[2] = xcolor.blue / 65536.0;
- color[3] = 1;
-}
-
-
-static int
-draw_ground (ModeInfo *mi)
-{
- int wire = MI_IS_WIREFRAME(mi);
- int polys = 0;
- int x, y;
- int cells = 20;
- GLfloat color[4];
- GLfloat color0[4];
- GLfloat cell_size = 1.0;
- GLfloat z = -0.005;
-
- parse_color (mi, "groundColor", color);
- parse_color (mi, "towerColor", color0);
- color0[0] *= 0.05;
- color0[1] *= 0.05;
- color0[2] *= 0.3;
- color0[3] = 1;
-
- if (!wire)
- {
- GLfloat fog_color[4] = { 0, 0, 0, 1 };
-
- glFogi (GL_FOG_MODE, GL_EXP2);
- glFogfv (GL_FOG_COLOR, fog_color);
- glFogf (GL_FOG_DENSITY, 0.015);
- glFogf (GL_FOG_START, -cells/2 * cell_size);
- glEnable (GL_FOG);
- }
-
- glPushMatrix();
- glScalef (1.0/cells, 1.0/cells, 1);
- glTranslatef (-cells/2.0, -cells/2.0, 0);
- glTranslatef (0.5, 0, 0);
-
- glBegin (GL_QUADS); /* clipping quad */
- glColor4fv (color0);
- glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color0);
-
- glVertex3f (0, 0, z);
- glVertex3f (cells * cell_size, 0, z);
- glVertex3f (cells * cell_size, cells * cell_size, z);
- glVertex3f (0, cells * cell_size, z);
- glEnd();
- polys++;
-
- glColor4fv (color);
- glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
-
- for (y = 0; y < cells; y++)
- for (x = 0; x < cells; x++)
- {
- GLfloat a = 0;
- GLfloat b = 1.0/3;
- GLfloat c = 2.0/3;
- GLfloat d = 1.0;
- GLfloat w = 0.02;
-
- glPushMatrix();
- glTranslatef (x, y, 0);
-
- glNormal3f (0, 0, 1);
-
- switch (random() % 4) {
- case 0:
- glRotatef (90, 0, 0, 1);
- glTranslatef (0, -1, 0);
- break;
- case 1:
- glRotatef (-90, 0, 0, 1);
- glTranslatef (-1, 0, 0);
- break;
- case 2:
- glRotatef (180, 0, 0, 1);
- glTranslatef (-1, -1, 0);
- break;
- default: break;
- }
-
- switch (random() % 2) {
- case 0:
- glScalef (-1, -1, 1);
- glTranslatef (-1, -1, 0);
- break;
- default: break;
- }
-
- switch (random() % 2) {
- case 0:
-
- glBegin (wire ? GL_LINE_LOOP : GL_QUAD_STRIP);
- glVertex3f (a, b+w, 0);
- glVertex3f (a, b-w, 0); polys++;
- glVertex3f (b+w, a, 0); polys++;
- glVertex3f (b-w, a, 0); polys++;
- glEnd();
-
- glBegin (wire ? GL_LINE_LOOP : GL_QUAD_STRIP);
- glVertex3f (a, c+w, 0);
- glVertex3f (a, c-w, 0); polys++;
- glVertex3f (b+w, c+w, 0); polys++;
- glVertex3f (b, c-w, 0); polys++;
- glVertex3f (c+w, b+w, 0); polys++;
- glVertex3f (c-w, b, 0); polys++;
- glVertex3f (c+w, a, 0); polys++;
- glVertex3f (c-w, a, 0); polys++;
- glEnd();
-
-/*
- glBegin (wire ? GL_LINE_LOOP : GL_QUAD_STRIP);
- glVertex3f (c+w, d, 0);
- glVertex3f (c-w, d, 0); polys++;
- glVertex3f (d, c+w, 0); polys++;
- glVertex3f (d, c-w, 0); polys++;
- glEnd();
-*/
- break;
-
- default:
- glBegin (wire ? GL_LINE_LOOP : GL_QUAD_STRIP);
- glVertex3f (a+w, d, 0);
- glVertex3f (a, d, 0); polys++;
- glVertex3f (a+w, d, 0);
- glVertex3f (a, d-w, 0); polys++;
- glVertex3f (b+w, c-w, 0); polys++;
- glVertex3f (b-w, c-w, 0); polys++;
- glVertex3f (b+w, a, 0); polys++;
- glVertex3f (b-w, a, 0); polys++;
- glEnd();
-
- glBegin (wire ? GL_LINE_LOOP : GL_QUAD_STRIP);
- glVertex3f (b+w, d, 0);
- glVertex3f (b-w, d, 0); polys++;
- glVertex3f (c+w, c-w, 0); polys++;
- glVertex3f (c-w, c-w, 0); polys++;
- glVertex3f (c+w, a, 0); polys++;
- glVertex3f (c-w, a, 0); polys++;
- glEnd();
- break;
- }
-
- glPopMatrix();
- }
- glPopMatrix();
-
- if (!wire)
- {
- glDisable (GL_BLEND);
- glDisable (GL_FOG);
- }
-
- return polys;
-}
-
-
-/* qsort comparator for sorting towers by y position */
-static int
-cmp_towers (const void *aa, const void *bb)
-{
- const tower *a = (tower *) aa;
- const tower *b = (tower *) bb;
- return ((int) (b->y * 10000) -
- (int) (a->y * 10000));
-}
-
-
-static GLfloat
-ease_fn (GLfloat r)
-{
- return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */
-}
-
-
-static GLfloat
-ease_ratio (GLfloat r)
-{
- GLfloat ease = 0.5;
- if (r <= 0) return 0;
- else if (r >= 1) return 1;
- else if (r <= ease) return ease * ease_fn (r / ease);
- else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease);
- else return r;
-}
-
-
-/* Draws the text quads on the face.
- First pass is for the small background text, second is for the big block.
- */
-static int
-draw_tower_face_text (ModeInfo *mi, GLfloat height, Bool which)
-{
- gibson_configuration *bp = &ccs[MI_SCREEN(mi)];
- int wire = MI_IS_WIREFRAME(mi);
- int polys = 0;
- Bool wire2 = False; /* Debugging quads */
- Bool bg_p = (which == 1 && do_tex && !wire);
-
- /* The texture is a tex_width x tex_height rectangle, of which we
- only use the rbearing+lbearing x ascent+descent sub-rectangle.
- Texture coordinates reference the tex_width x tex_height rectangle
- as a 0.0 - 1.0 coordinate.
- */
- int n = which ? 1 : 0;
- GLfloat twratio = ((bp->text[n].metrics.rbearing +
- bp->text[n].metrics.lbearing) /
- (GLfloat) bp->text[n].width);
- GLfloat thratio = ((bp->text[n].metrics.ascent +
- bp->text[n].metrics.descent) /
- (GLfloat) bp->text[n].height);
- GLfloat aspect = ((bp->text[n].ascent + bp->text[n].descent) /
- (GLfloat) bp->text[n].em_width);
-
- GLfloat sx = 1.0 / (which ? 1 : columns);
- GLfloat sy = (which
- ? height * 0.8
- : sx * 4); /* Tweaked to match gluPerspective */
-
- GLfloat lines_in_tex = ((bp->text[n].metrics.ascent +
- bp->text[n].metrics.descent) /
- (GLfloat)
- (bp->text[n].ascent + bp->text[n].descent));
- GLfloat tex_lines = (which ? 3 : 8); /* Put this many lines in each quad */
-
- GLfloat tsx = sx * twratio;
- GLfloat tsy = sy * thratio * tex_lines / lines_in_tex * aspect;
- GLfloat x1, tx1;
- GLfloat margin = 0.2;
- GLfloat m2 = margin/2 / (which ? 1 : columns);
- GLfloat m3 = m2 / (which ? 1 : height);
- GLfloat h2 = height * (which ? 1-margin : 1);
-
- glColor4fv (which ? bp->tower_color2 : bp->tower_color);
- glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
- which ? bp->tower_color2 : bp->tower_color);
-
- glBindTexture (GL_TEXTURE_2D, bp->text[n].texid);
-
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
- if (!wire && !wire2 && !bg_p) glBegin (GL_QUADS);
- for (x1 = 0, tx1 = 0; x1 < 1.0; x1 += sx, tx1 += tsx)
- {
- GLfloat x2 = x1 + sx;
- GLfloat tx2 = tx1 + tsx;
- GLfloat y2, ty2;
- GLfloat z = (which ? 0.05 : 0);
-
- tx1 = 0;
- tx2 = twratio;
-
- for (y2 = h2, ty2 = thratio;
- y2 > 0;
- y2 -= sy, ty2 -= tsy)
- {
- GLfloat y1 = y2 - sy * (1-margin);
- GLfloat ty1 = ty2 - tsy;
- GLfloat toff = frand ((bp->text[n].metrics.ascent +
- bp->text[n].metrics.descent)
- * 0.8);
-
- if (y1 < 0) /* Clip the panel to the bottom of the tower face */
- {
- tsy = y2 / (y2 - y1);
- y1 = 0;
- }
-
- ty1 = toff;
- ty2 = ty1 + tsy;
-
- if (wire2 && which) glColor3f (1,0,0);
- if (wire || wire2 || bg_p)
- glBegin (!wire && (wire2 || bg_p) ? GL_QUADS : GL_LINE_LOOP);
- glTexCoord2f(tx1, ty2); glVertex3f (x1+m2, y1+m3, z);
- glTexCoord2f(tx2, ty2); glVertex3f (x2-m2, y1+m3, z);
- glTexCoord2f(tx2, ty1); glVertex3f (x2-m2, y2-m3, z);
- glTexCoord2f(tx1, ty1); glVertex3f (x1+m2, y2-m3, z);
- if (wire || wire2 || bg_p)
- glEnd();
- polys++;
-
- if (bg_p)
- {
- GLfloat bg[4] = { 1, 1, 1, 0.2 };
- z -= 0.1;
- m2 -= 0.03;
- m3 -= 0.03;
- glColor4fv (bg);
- glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, bg);
- }
-
- if ((wire2 || bg_p) && !wire)
- {
- if (do_tex) glDisable(GL_TEXTURE_2D);
- glBegin (bg_p ? GL_QUADS : GL_LINE_LOOP);
- glVertex3f (x1+m2, y1+m3, z);
- glVertex3f (x2-m2, y1+m3, z);
- glVertex3f (x2-m2, y2-m3, z);
- glVertex3f (x1+m2, y2-m3, z);
- glEnd();
- polys++;
- if (do_tex) glEnable(GL_TEXTURE_2D);
- }
-
- if (which) break;
- }
- }
- if (!wire && !wire2 && !bg_p) glEnd();
-
- return polys;
-}
-
-
-/* Draws the wall of the face, and the edges, then the text quads on it.
- */
-static int
-draw_tower_face (ModeInfo *mi, GLfloat height, int mode)
-{
- gibson_configuration *bp = &ccs[MI_SCREEN(mi)];
- int wire = MI_IS_WIREFRAME(mi);
- int polys = 0;
-
- switch (mode) {
- case 0:
- if (! wire)
- {
- GLfloat m = 0.015;
- GLfloat z = -0.0005;
- if (do_tex) glDisable (GL_TEXTURE_2D);
-
- glNormal3f (0, 0, 1);
-
- glColor4fv (bp->bg_color);
- glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
- bp->bg_color);
-
- glBegin (GL_QUADS);
- glVertex3f (0, 0, z*2); /* background */
- glVertex3f (1, 0, z*2);
- glVertex3f (1, height, z*2);
- glVertex3f (0, height, z*2);
- polys++;
- glEnd();
-
- glColor4fv (bp->edge_color);
- glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
- bp->edge_color);
-
- glBegin (GL_QUADS);
- glVertex3f (0, 0, z); /* left */
- glVertex3f (m, 0, z);
- glVertex3f (m, height, z);
- glVertex3f (0, height, z);
- polys++;
-
- glVertex3f (1-m, 0, 0); /* right */
- glVertex3f (1, 0, 0);
- glVertex3f (1, height, z);
- glVertex3f (1-m, height, z);
- polys++;
-
- glVertex3f (m, 0, 0); /* bottom */
- glVertex3f (1-m, 0, 0);
- glVertex3f (1-m, m, 0);
- glVertex3f (m, m, 0);
- polys++;
-
- glVertex3f (m, height-m, z); /* top */
- glVertex3f (1-m, height-m, z);
- glVertex3f (1-m, height, z);
- glVertex3f (m, height, z);
- polys++;
- glEnd();
-
- if (do_tex) glEnable (GL_TEXTURE_2D);
- }
- break;
- case 1:
- polys += draw_tower_face_text (mi, height, 0);
- break;
- case 2:
- polys += draw_tower_face_text (mi, height * 0.7, 1);
- break;
- default:
- abort();
- break;
- }
-
- return polys;
-}
-
-
-/* Mode 0: draws 5 sides of the box
- Mode 1: just background text
- Mode 2: just foreground text
- */
-static int
-draw_tower (ModeInfo *mi, tower *t, int mode, int face)
-{
- GLfloat height = grid_height;
-
- int polys = 0;
-
- glPushMatrix();
- glTranslatef (-0.5, 0.5, 0);
-
- if (face == 0 || face == -1)
- {
- glPushMatrix(); /* top */
- glTranslatef (0, 0, height);
- polys += draw_tower_face (mi, 1.0, mode);
- glPopMatrix();
- }
-
- if (face == 1 || face == -1)
- {
- glPushMatrix(); /* left */
- glRotatef ( 90, 1, 0, 0);
- glRotatef (-90, 0, 1, 0);
- glTranslatef (-1, 0, 0);
- polys += draw_tower_face (mi, height, mode);
- glPopMatrix();
- }
-
- if (face == 2 || face == -1)
- {
- glPushMatrix(); /* back */
- glRotatef ( 90, 1, 0, 0);
- glRotatef (180, 0, 1, 0);
- glTranslatef (-1, 0, 1);
- polys += draw_tower_face (mi, height, mode);
- glPopMatrix();
- }
-
- if (face == 3 || face == -1)
- {
- glPushMatrix(); /* right */
- glRotatef ( 90, 1, 0, 0);
- glRotatef ( 90, 0, 1, 0);
- glTranslatef (0, 0, 1);
- polys += draw_tower_face (mi, height, mode);
- glPopMatrix();
- }
-
- if (face == 4 || face == -1)
- {
- glPushMatrix(); /* front */
- glRotatef ( 90, 1, 0, 0);
- polys += draw_tower_face (mi, height, mode);
- glPopMatrix();
- }
-
- if (face < -1 || face > 4) abort();
-
- glPopMatrix();
- return polys;
-}
-
-
-static void
-animate_towers (ModeInfo *mi)
-{
- gibson_configuration *bp = &ccs[MI_SCREEN(mi)];
- int ii;
- GLfloat min = -3;
- GLfloat max = grid_depth * (1 + grid_spacing) - grid_spacing - 1;
- GLfloat yspeed = speed * 0.05;
-
- for (ii = 0; ii < 20; ii++)
- {
- int jj, kk;
-
- /* randomly trade two towers' fg dlists */
- if (0 == (random() % 20))
- {
- int i = random() % bp->ntowers;
- int j = random() % bp->ntowers;
- int k = random() % countof(bp->towers[i].fg_dlists);
- GLuint d1 = bp->towers[i].bg_dlists[k];
- GLuint d2 = bp->towers[j].bg_dlists[k];
- bp->towers[i].bg_dlists[k] = d2;
- bp->towers[j].bg_dlists[k] = d1;
- }
-
- /* randomly trade two towers' bg dlists */
- if (1) /* (0 == (random() % 3)) */
- {
- int i = random() % bp->ntowers;
- int j = random() % bp->ntowers;
- int k = random() % countof(bp->towers[i].fg_dlists);
- GLuint d1 = bp->towers[i].fg_dlists[k];
- GLuint d2 = bp->towers[j].fg_dlists[k];
- bp->towers[i].fg_dlists[k] = d2;
- bp->towers[j].fg_dlists[k] = d1;
- }
-
- /* Randomize whether it's displaying fg text or bg text */
- for (jj = 0; jj < bp->ntowers; jj++)
- for (kk = 0; kk < countof(bp->towers[jj].fg_dlists); kk++)
- {
- /* Re-choose every N frames. Display fg 1 in M. */
- int frames = 500;
- int fg_chance = (kk == 0 ? 100000 : 10);
- unsigned int o = !!(bp->towers[jj].face_mode & (1 << kk));
- unsigned int n = !!((random() % frames) ? o :
- (0 == (random() % fg_chance)));
- bp->towers[jj].face_mode =
- ((bp->towers[jj].face_mode & ~(1 << kk)) | (n << kk));
- }
- }
-
- for (ii = 0; ii < bp->ntowers; ii++)
- {
- tower *t = &bp->towers[ii];
- t->h += speed * 0.01;
- if (t->h > 1) t->h = 1;
-
- t->y -= yspeed;
-
- if (t->y < min)
- {
- t->h = 0;
- t->y = max;
- }
- }
-
- /* Sorting by depth improves frame rate slightly. */
- qsort (bp->towers, bp->ntowers, sizeof(*bp->towers), cmp_towers);
-
- bp->ground_y -= yspeed / GROUND_QUAD_SIZE;
- if (bp->ground_y < 1)
- bp->ground_y += 1;
-
- bp->billboard_y -= yspeed;
- if (bp->billboard_y < min || !bp->billboard_text)
- {
- const char *const ss[] = {
- "ACCESS GRANTED",
- "ACCESS GRANTED",
- "ACCESS DENIED",
- "ACCESS DENIED",
- "ACCESS DENIED",
- "ACCESS DENIED",
- "ACCESS DENIED",
- "PASSWORD ACCEPTED",
- " GIVE ME\nA COOKIE",
- "MESS WITH THE BEST\n DIE LIKE THE REST",
- };
-
- bp->billboard_y = max * (1 + frand(8));
- bp->billboard_text = ss[random() % countof(ss)];
- }
-}
-
-
-static int
-draw_billboard (ModeInfo *mi)
-{
- gibson_configuration *bp = &ccs[MI_SCREEN(mi)];
- int polys = 0;
- int wire = MI_IS_WIREFRAME(mi);
- GLfloat w, h, s, margin, margin2;
- XCharStruct metrics;
- int ascent, descent;
- texture_font_data *font = bp->text[1].font_data;
- GLfloat color[4];
- GLfloat y = grid_height * 0.3;
-
- texture_string_metrics (font, bp->billboard_text,
- &metrics, &ascent, &descent);
- w = metrics.lbearing + metrics.rbearing;
- h = metrics.ascent + metrics.descent;
- s = 1.0 / w;
- s *= 0.95;
-
- margin = w * 0.1;
- margin2 = margin * 1.7;
-
- glPushMatrix();
-
- glTranslatef (-0.5, bp->billboard_y, y);
- glRotatef (90, 1, 0, 0);
- glScalef (s, s * 1.5, s);
-
- memcpy (color, bp->tower_color2, sizeof(color));
- color[3] = 0.6;
- glColor4fv (color);
- glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
-
- if (do_tex && !wire)
- glDisable (GL_TEXTURE_2D);
-
- glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
- glNormal3f (0, 0, 1);
- glVertex3f (-margin, -margin2, 0);
- glVertex3f (-margin, h+margin2, 0);
- glVertex3f (w+margin, h+margin2, 0);
- glVertex3f (w+margin, -margin2, 0);
- glEnd();
- polys++;
-
- if (do_tex && !wire)
- {
- color[3] = 1;
- glColor4fv (color);
- glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
- glEnable (GL_TEXTURE_2D);
- glTranslatef (-metrics.lbearing, metrics.descent, 0);
- print_texture_string (font, bp->billboard_text);
- polys++;
- }
-
- glPopMatrix();
- return polys;
-}
-
-
-static void
-init_text (ModeInfo *mi)
-{
- gibson_configuration *bp = &ccs[MI_SCREEN(mi)];
- int lines = 20;
- int i;
- char *s;
-
- const char *const ss[] = {
- "\n"
- "ACCESS TO THIS COMPUTER AND\n"
- "ITS DATA IS RESTRICTED TO\n"
- "AUTHORIZED PERSONNEL ONLY\n"
- "\n",
- "\n"
- " PASSWORD ACCEPTED\n"
- " GOD\n"
- "\n",
- "PERSONNEL >>>\n",
- "SEA ROUTINGS >>>\n",
- "GARBAGE >>>\n",
- "COMP. SERVICING >>>\n",
- "COMPANY BUDGETS >>>\n",
- "SCIENTIFIC BUDGETS >>>\n",
- "COMPANY POLICIES >>>\n",
- "ANNUAL RETURNS >>>\n",
- "MINE RESEARCH >>>\n",
- "CENTRAL LIBRARY >>>\n",
- "QUANTATIVE SPEC. >>>\n",
- "PAYMENT LEVELS >>>\n",
- "CENTRAL SERVER >>>\n",
- "GARBAGE >>>\n",
- "KNMTS. DVPNT. >>>\n",
- "LICENSING >>>\n",
- "RELATIONS >>>\n",
- "TIME SHEET RECS. >>>\n",
- "RD. PRT. ROUTINGS >>>\n",
- "RECRUITMENT >>>\n",
- "TNKR. EXPENDITURE >>>\n",
- "MINE DEVELOPMENT >>>\n",
- "GARBAGE >>>\n",
- "ANNUAL BUDGETS >>>\n",
- "OIL LOCATIONS >>>\n",
- "TIME SHEET RECS. >>>\n",
- "RD. PRT. ROUTINGS >>>\n",
- "KINEMATICS >>>\n",
- "TPS. REPORTS >>>\n",
- "BLAST FRNC. STATUS >>>\n",
- "ACCOUNTANTS >>>\n",
- "SHIPPING FORCASTS >>>\n",
- "INDST. REPORTS >>>\n",
- "EXPLOR. DVLT. >>>\n",
- "WRHSE. EXPEND. >>>\n",
- "GARBAGE >>>\n",
- "RELOCATIONS >>>\n",
- "AIRFREIGHT STATUS >>>\n",
- "TPGC. EXPEND. >>>\n",
- "SEA-BOARD LAWS >>>\n",
- "COMPOSITE PLANTS >>>\n",
- "NUCLEAR RESEARCH >>>\n",
- "BALLAST REPORTS >>>\n",
- "\n"
- "CONFIDENTAL\n"
- "FILES\n"
- "DO NOT DELETE\n"
- "BEFORE FINAL\n"
- "BACKUP IS COMPLETED\n"
- "\n",
- "\n"
- "FILE 1\n"
- "WAITING FOR BACK-UP\n"
- "\n"
- "FILE 2\n"
- "WAITING FOR BACK-UP\n"
- "\n"
- "FILE 3\n"
- "WAITING FOR BACK-UP\n"
- "\n"
- "FILE 4\n"
- "WAITING FOR BACK-UP\n"
- "\n"
- };
-
-
- bp->text[1].text = s = calloc (countof(ss) * 2 * 40, 1);
- for (i = 0; i < countof(ss); i++)
- {
- int n = random() % countof(ss);
- strcat (s, ss[n]);
- s += strlen(s);
- }
-
- bp->text[0].text = s = calloc (lines * 40, 1);
- for (i = 0; i < lines; i++)
- {
- switch (random() % 11) {
- case 0: sprintf (s, "%X\n", random() % 0xFFFFFFFF); break;
- case 1: sprintf (s, "%X\n", random() % 0xFFFFFF); break;
- case 2: sprintf (s, "%X\n", random() % 0xFFFF); break;
- case 3: sprintf (s, "%d\n", random() % 0xFFFFFF); break;
- case 4: sprintf (s, "%d\n", random() % 0xFFFF); break;
- case 5: sprintf (s, "%d\n", random() % 0xFFF); break;
- case 6: strcat (s, "00000000\n"); break;
- case 7: sprintf (s, "{{{{{{{{\n"); break;
- case 8: sprintf (s, "[][][][][][]\n"); break;
- case 9: sprintf (s, "DEFAULT\n"); break;
- case 10: sprintf (s, "\n"); break;
- }
- s += strlen(s);
- }
-}
-
-
-static void
-init_textures (ModeInfo *mi)
-{
- gibson_configuration *bp = &ccs[MI_SCREEN(mi)];
- int i;
- for (i = 0; i < countof(bp->text); i++)
- {
- glGenTextures (1, &bp->text[i].texid);
- glBindTexture (GL_TEXTURE_2D, bp->text[i].texid);
- texture_string_metrics (bp->text[i].font_data, " ",
- &bp->text[i].metrics,
- &bp->text[i].ascent,
- &bp->text[i].descent);
- bp->text[i].em_width = bp->text[i].metrics.width;
- string_to_texture (bp->text[i].font_data, bp->text[i].text,
- &bp->text[i].metrics,
- &bp->text[i].width,
- &bp->text[i].height);
- }
- glBindTexture (GL_TEXTURE_2D, 0);
-}
-
-
-ENTRYPOINT void
-init_gibson (ModeInfo *mi)
-{
- gibson_configuration *bp;
-
- MI_INIT (mi, ccs);
-
- bp = &ccs[MI_SCREEN(mi)];
-
- if ((bp->glx_context = init_GL(mi)) != NULL) {
- reshape_gibson (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
- }
-
- parse_color (mi, "towerText", bp->tower_color);
- parse_color (mi, "towerText2", bp->tower_color2);
- parse_color (mi, "towerColor", bp->bg_color);
- memcpy (bp->edge_color, bp->bg_color, sizeof(bp->tower_color));
- bp->edge_color [3] = 0.7;
- bp->bg_color [3] = 1.0;
- bp->tower_color [3] = 1.0;
- bp->tower_color2[3] = 1.0;
-
- if (grid_spacing < 1) grid_spacing = 1;
- if (grid_width < 1) grid_width = 1;
- if (grid_height < 1) grid_height = 1;
- if (grid_depth < 1) grid_depth = 1;
- if (columns < 1) columns = 1;
- bp->ntowers = grid_width * grid_depth;
- bp->towers = (tower *) calloc (sizeof(tower), bp->ntowers);
- bp->startup_p = True;
-
- {
- double wander_speed = 0.007 * speed;
- double tilt_speed = 0.01 * speed;
- bp->rot = make_rotator (0, 0, 0, 0, wander_speed, True);
- bp->rot2 = make_rotator (0, 0, 0, 0, tilt_speed, True);
- }
-
- bp->text[0].font_data = load_texture_font (mi->dpy, "towerFont");
- bp->text[1].font_data = load_texture_font (mi->dpy, "towerFont");
- init_text (mi);
- init_textures (mi);
-
- bp->ground_dlist = glGenLists (1);
- glNewList (bp->ground_dlist, GL_COMPILE);
- bp->ground_polys = draw_ground (mi);
- glEndList ();
-
- bp->tower_dlist = glGenLists (1);
- glNewList (bp->tower_dlist, GL_COMPILE);
- bp->tower_polys = draw_tower (mi, &bp->towers[0], 0, -1);
- glEndList ();
-
- {
- int x, y;
- GLfloat ww = grid_width * (1 + grid_spacing) - grid_spacing;
- GLfloat hh = grid_depth * (1 + grid_spacing) - grid_spacing;
- for (y = 0; y < grid_depth; y++)
- for (x = 0; x < grid_width; x++)
- {
- int i;
- tower *t = &bp->towers[y * grid_width + x];
- t->x = (x * ww / (grid_width - 1)) - ww/2;
- t->y = (y * hh / grid_depth) + 6;
- t->h = 0 - y / (GLfloat) grid_depth / 2;
-
- for (i = 0; i < countof(t->fg_dlists); i++)
- {
- t->bg_dlists[i] = glGenLists (1);
- glNewList (t->bg_dlists[i], GL_COMPILE);
- t->bg_polys = draw_tower (mi, t, 1, i);
- glEndList ();
-
- t->fg_dlists[i] = glGenLists (1);
- glNewList (t->fg_dlists[i], GL_COMPILE);
- t->fg_polys += draw_tower (mi, t, 2, i);
- glEndList ();
- }
- }
- }
-
- animate_towers (mi);
-}
-
-
-ENTRYPOINT void
-draw_gibson (ModeInfo *mi)
-{
- gibson_configuration *bp = &ccs[MI_SCREEN(mi)];
- Display *dpy = MI_DISPLAY(mi);
- Window window = MI_WINDOW(mi);
- int wire = MI_IS_WIREFRAME(mi);
- GLfloat s;
- int i;
-
- static const GLfloat bspec[4] = {1.0, 1.0, 1.0, 1.0};
- static const GLfloat bshiny = 128.0;
- GLfloat bcolor[4] = { 0.7, 0.7, 1.0, 1.0 };
-
- if (!bp->glx_context)
- return;
-
- mi->polygon_count = 0;
- glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *bp->glx_context);
-
- glShadeModel (GL_SMOOTH);
- glEnable (GL_NORMALIZE);
- glEnable (GL_CULL_FACE);
- glDisable (GL_TEXTURE_2D);
- glEnable (GL_DEPTH_TEST);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- if (!wire)
- {
- GLfloat pos[4] = {0.4, 0.2, 0.4, 0.0};
- GLfloat amb[4] = {0.2, 0.2, 0.2, 1.0};
- GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0};
- GLfloat spc[4] = {1.0, 1.0, 1.0, 1.0};
-
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glLightfv(GL_LIGHT0, GL_POSITION, pos);
- glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, dif);
- glLightfv(GL_LIGHT0, GL_SPECULAR, spc);
- }
-
- glPushMatrix ();
-
- glRotatef(current_device_rotation(), 0, 0, 1);
-
-# ifdef DEBUG
- s = 0.02;
-# else
- s = 10;
-# endif
-
- glScalef (s, s, s);
-
- glTranslatef (0, -1, 0);
-
-# ifndef DEBUG
- glRotatef (-82, 1, 0, 0);
-
- {
- double maxx = 40; /* up/down */
- double maxy = 1.5; /* tilt */
- double maxz = 100; /* left/right */
-
- double x, y, z;
- double minh = -(grid_height / 2.0);
- double maxh = -(grid_height / 20.0);
-
- get_position (bp->rot, &x, &y, &z, !bp->button_down_p);
- x -= 0.5;
- z = minh + (z * (maxh - minh));
- glTranslatef(x * grid_spacing * 0.005, 0, z);
-
- get_position (bp->rot2, &x, &y, &z, !bp->button_down_p);
-
- z += (bp->xscroll / 2.0);
- x += (bp->yscroll / 2.0);
-
- glRotatef (maxx/2 - x*maxx, 1, 0, 0);
- glRotatef (maxy/2 - y*maxy, 0, 1, 0);
- glRotatef (maxz/2 - z*maxz, 0, 0, 1);
- }
-# endif /* DEBUG */
-
- glPushMatrix();
- glScalef (GROUND_QUAD_SIZE, GROUND_QUAD_SIZE, 1);
-
- glTranslatef (0, bp->ground_y - 1.5, 0);
- glCallList (bp->ground_dlist);
- mi->polygon_count += bp->ground_polys;
-
- glTranslatef (0, 1, 0);
- glCallList (bp->ground_dlist);
- mi->polygon_count += bp->ground_polys;
- glPopMatrix();
-
- glMaterialfv (GL_FRONT, GL_SPECULAR, bspec);
- glMateriali (GL_FRONT, GL_SHININESS, bshiny);
- glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, bcolor);
-
- glPushMatrix();
-
- if (grid_width & 1) /* Stay between towers */
- glTranslatef ((grid_spacing + 1) / 2.0, 0, 0);
-
-
- if (!wire)
- {
- GLfloat fog_color[4] = { 0, 0, 0, 1 };
- glFogfv (GL_FOG_COLOR, fog_color);
- /* I so don't understand how to choose the fog parameters. */
- glFogi (GL_FOG_MODE, GL_LINEAR);
- glFogf (GL_FOG_START, 0);
- glFogf (GL_FOG_END, 100);
- glEnable (GL_FOG);
- }
-
- /* Clear the floor under the tower bases */
-
- {
- GLfloat color0[4] = { 0, 0, 0, 1 };
- GLfloat z = 0.01;
-
- if (do_tex && !wire) glDisable (GL_TEXTURE_2D);
- glColor4fv (color0);
- glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color0);
- glDisable (GL_BLEND);
- glDisable (GL_DEPTH_TEST);
-
- for (i = 0; i < bp->ntowers; i++)
- {
- tower *t = &bp->towers[i];
- glPushMatrix();
- glTranslatef (t->x, t->y, 0);
-
- glNormal3f (0, 0, 1);
- glBegin (wire ? GL_LINE_LOOP : GL_QUADS); /* clipping quad */
- glVertex3f (-0.5, -0.5, z);
- glVertex3f ( 0.5, -0.5, z);
- glVertex3f ( 0.5, 0.5, z);
- glVertex3f (-0.5, 0.5, z);
- glEnd();
- mi->polygon_count++;
- glPopMatrix();
- }
- }
-
- glEnable (GL_DEPTH_TEST);
-
- if (!wire)
- {
- if (do_tex)
- {
- glEnable (GL_TEXTURE_2D);
- enable_texture_string_parameters (bp->text[0].font_data);
- }
- glEnable (GL_BLEND);
- glBlendFunc (GL_SRC_ALPHA, GL_ONE);
- glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
- glDisable (GL_CULL_FACE);
- if (bp->startup_p)
- glEnable (GL_DEPTH_TEST);
- else
- glDisable (GL_DEPTH_TEST);
- }
-
- /* Draw the towers */
-
- for (i = 0; i < bp->ntowers; i++)
- {
- tower *t = &bp->towers[i];
- glPushMatrix();
- glTranslatef (t->x, t->y-1, -grid_height * ease_ratio (1 - t->h));
-
- glCallList (bp->tower_dlist);
- mi->polygon_count += bp->tower_polys;
-
- if (wire || do_tex)
- {
- int j;
- for (j = 0; j < countof(t->fg_dlists); j++)
- {
- if (! (t->face_mode & (1 << j)))
- {
- glCallList (t->bg_dlists[j]);
- mi->polygon_count += t->bg_polys;
- }
- else
- {
- glCallList (t->fg_dlists[j]);
- mi->polygon_count += t->fg_polys;
- }
- }
- }
- glPopMatrix();
- }
-
- glPopMatrix();
-
- mi->polygon_count += draw_billboard (mi);
- glPopMatrix();
-
- if (!bp->button_down_p)
- animate_towers (mi);
-
- if (bp->startup_p && bp->towers[bp->ntowers-1].h >= 1)
- bp->startup_p = False;
-
- if (mi->fps_p) do_fps (mi);
- glFinish();
-
- glXSwapBuffers(dpy, window);
-}
-
-
-ENTRYPOINT void
-free_gibson (ModeInfo *mi)
-{
- int i, j;
- gibson_configuration *bp = &ccs[MI_SCREEN(mi)];
- if (!bp->glx_context) return;
- glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *bp->glx_context);
-
- if (bp->rot) free_rotator (bp->rot);
- if (bp->rot2) free_rotator (bp->rot2);
- if (glIsList(bp->ground_dlist)) glDeleteLists(bp->ground_dlist, 1);
- if (glIsList(bp->tower_dlist)) glDeleteLists(bp->tower_dlist, 1);
- for (i = 0; i < countof(bp->text); i++)
- {
- if (bp->text[i].font_data) free_texture_font (bp->text[i].font_data);
- if (bp->text[i].text) free (bp->text[i].text);
- }
- if (bp->towers)
- for (i = 0; i < bp->ntowers; i++)
- {
- for (j = 0; j < countof(bp->towers[i].fg_dlists); j++)
- {
- if (glIsList(bp->towers[i].fg_dlists[j]))
- glDeleteLists(bp->towers[i].fg_dlists[j], 1);
- if (glIsList(bp->towers[i].bg_dlists[j]))
- glDeleteLists(bp->towers[i].bg_dlists[j], 1);
- }
- }
-}
-
-
-XSCREENSAVER_MODULE ("Gibson", gibson)
-/* Greets to Crash Override, The Phantom Freak, and also Joey */
-
-#endif /* USE_GL */