summaryrefslogtreecommitdiffstats
path: root/hacks/glx/crackberg.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/crackberg.c
parentDelete pre-6.00 files (diff)
downloadxscreensaver-master.tar.gz
xscreensaver-master.tar.xz
xscreensaver-master.zip
Diffstat (limited to 'hacks/glx/crackberg.c')
-rw-r--r--hacks/glx/crackberg.c1483
1 files changed, 0 insertions, 1483 deletions
diff --git a/hacks/glx/crackberg.c b/hacks/glx/crackberg.c
deleted file mode 100644
index 95b49e4..0000000
--- a/hacks/glx/crackberg.c
+++ /dev/null
@@ -1,1483 +0,0 @@
-/***************************
- ** crackberg; Matus Telgarsky [ catachresis@cmu.edu ] 2005
- ** */
-#ifndef HAVE_JWXYZ
-# define XK_MISCELLANY
-# include <X11/keysymdef.h>
-#endif
-
-#define DEFAULTS "*delay: 20000 \n" \
- "*showFPS: False \n" \
- "*wireframe: False \n" \
-
-# define release_crackberg 0
-
-#include "xlockmore.h"
-#ifdef USE_GL /* whole file */
-
-#define DEF_NSUBDIVS "4"
-#define DEF_BORING "False"
-#define DEF_CRACK "True"
-#define DEF_WATER "True"
-#define DEF_FLAT "True"
-#define DEF_COLOR "random"
-#define DEF_LIT "True"
-#define DEF_VISIBILITY "0.6"
-#define DEF_LETTERBOX "False"
-
-
-/***************************
- ** macros
- ** */
-
-#define M_RAD7_4 0.661437827766148
-#define M_SQRT3_2 0.866025403784439
-#define M_PI_180 0.0174532925199433
-#define M_180_PI 57.2957795130823
-#define MSPEED_SCALE 1.1
-#define AVE3(a,b,c) ( ((a) + (b) + (c)) / 3.0 )
-#define MAX_ZDELTA 0.35
-#define DISPLACE(h,d) (h+(random()/(double)RAND_MAX-0.5)*2*MAX_ZDELTA/(1<<d))
-#define MEAN(x,y) ( ((x) + (y)) / 2.0 )
-#define TCOORD(x,y) (cberg->heights[(cberg->epoints * (y) - ((y)-1)*(y)/2 + (x))])
-#define sNCOORD(x,y,p) (cberg->norms[3 * (cberg->epoints * (y) - ((y)-1)*(y)/2 + (x)) + (p)])
-#define SET_sNCOORD(x,y, down, a,b,c,d,e,f) \
- sNCOORD(x,y,0) = AVE3(a-d, 0.5 * (b-e), -0.5 * (c-f)); \
- sNCOORD(x,y,1) = ((down) ? -1 : +1) * AVE3(0.0, M_SQRT3_2 * (b-e), M_SQRT3_2 * (c-f)); \
- sNCOORD(x,y,2) = (2*dx)
-#define fNCOORD(x,y,w,p) \
- (cberg->norms[3 * (2*(y)*cberg->epoints-((y)+1)*((y)+1) + 1 + 2 * ((x)-1) + (w)) + (p)])
-#define SET_fNCOORDa(x,y, down, dz00,dz01) \
- fNCOORD(x,y,0,0) = (down) * (dy) * (dz01); \
- fNCOORD(x,y,0,1) = (down) * ((dz01) * (dx) / 2 - (dx) * (dz00)); \
- fNCOORD(x,y,0,2) = (down) * (dx) * (dy)
-#define SET_fNCOORDb(x,y, down, dz10,dz11) \
- fNCOORD(x,y,1,0) = (down) * (dy) * (dz10); \
- fNCOORD(x,y,1,1) = (down) * ((dz11) * (dx) - (dx) * (dz10) / 2); \
- fNCOORD(x,y,1,2) = (down) * (dx) * (dy)
-
-
-/***************************
- ** types
- ** */
-
-
-typedef struct _cberg_state cberg_state;
-typedef struct _Trile Trile;
-
-typedef struct {
- void (*init)(Trile *);
- void (*free)(Trile *);
- void (*draw)(Trile *);
- void (*init_iter)(Trile *, cberg_state *);
- void (*dying_iter)(Trile *, cberg_state *);
-} Morph;
-
-typedef struct {
- char *id;
- void (*land)(cberg_state *, double);
- void (*water)(cberg_state *, double);
- double bg[4];
-} Color;
-
-enum { TRILE_NEW, TRILE_INIT, TRILE_STABLE, TRILE_DYING, TRILE_DELETE };
-
-struct _Trile {
- int x,y; /*center coords; points up if (x+y)%2 == 0, else down*/
- short state;
- short visible;
- double *l,*r,*v; /*only edges need saving*/
- GLuint call_list;
-
- void *morph_data;
- const Morph *morph;
-
- struct _Trile *left, *right, *parent; /* for bst, NOT spatial */
- struct _Trile *next_free, *next0; /* for memory allocation */
-};
-
-enum { MOTION_AUTO = 0, MOTION_MANUAL = 1, MOTION_LROT= 2, MOTION_RROT = 4,
- MOTION_FORW = 8, MOTION_BACK = 16, MOTION_DEC = 32, MOTION_INC = 64,
- MOTION_LEFT = 128, MOTION_RIGHT = 256 };
-
-struct _cberg_state {
- GLXContext *glx_context;
- Trile *trile_head;
-
- double x,y,z, yaw,roll,pitch, dx,dy,dz, dyaw,droll,dpitch, elapsed;
- double prev_frame;
- int motion_state;
- double mspeed;
-
- double fovy, aspect, zNear, zFar;
-
- const Color *color;
-
- int count;
-
- unsigned int epoints, /*number of points to one edge*/
- tpoints, /*number points total*/
- ntris, /*number triangles per trile*/
- tnorms; /*number of normals*/
-
- double *heights, *norms;
- Trile *free_head; /* for trile_[alloc|free] */
- Trile *all_triles;
-
- double draw_elapsed;
-
- double dx0;
-
- double vs0r,vs0g,vs0b, vs1r, vs1g, vs1b,
- vf0r,vf0g,vf0b, vf1r, vf1g, vf1b;
-
- Bool button_down_p;
- int mouse_x, mouse_y;
- struct timeval paused;
-};
-
-
-
-/***************************
- ** globals
- ** */
-
-static unsigned int nsubdivs;
-static Bool crack, boring, do_water, flat, lit, letterbox;
-static float visibility;
-static char *color;
-
-static cberg_state *cbergs = NULL;
-
-static XrmOptionDescRec opts[] = {
- {"-nsubdivs", ".nsubdivs", XrmoptionSepArg, 0},
- {"-boring", ".boring", XrmoptionNoArg, "True"},
- {"-crack", ".crack", XrmoptionNoArg, "True"},
- {"-no-crack", ".crack", XrmoptionNoArg, "False"},
- {"-water", ".water", XrmoptionNoArg, "True"},
- {"-no-water", ".water", XrmoptionNoArg, "False"},
- {"-flat", ".flat", XrmoptionNoArg, "True"},
- {"-no-flat", ".flat", XrmoptionNoArg, "False"},
- {"-color", ".color", XrmoptionSepArg, 0},
- {"-lit", ".lit", XrmoptionNoArg, "True"},
- {"-no-lit", ".lit", XrmoptionNoArg, "False"},
- {"-visibility", ".visibility", XrmoptionSepArg, 0},
- {"-letterbox", ".letterbox", XrmoptionNoArg, "True"}
-};
-
-static argtype vars[] = {
- {&nsubdivs, "nsubdivs", "nsubdivs", DEF_NSUBDIVS, t_Int},
- {&boring, "boring", "boring", DEF_BORING, t_Bool},
- {&crack, "crack", "crack", DEF_CRACK, t_Bool},
- {&do_water, "water", "water", DEF_WATER, t_Bool},
- {&flat, "flat", "flat", DEF_FLAT, t_Bool},
- {&color, "color", "color", DEF_COLOR, t_String},
- {&lit, "lit", "lit", DEF_LIT, t_Bool},
- {&visibility, "visibility", "visibility", DEF_VISIBILITY, t_Float},
- {&letterbox, "letterbox", "letterbox", DEF_LETTERBOX, t_Bool}
-};
-
-ENTRYPOINT ModeSpecOpt crackberg_opts = {countof(opts), opts, countof(vars), vars, NULL};
-
-
-/***************************
- ** Trile functions.
- ** first come all are regular trile functions
- ** */
-
-
-/* forward decls for trile_new */
-static Trile *triles_find(Trile *tr, int x, int y);
-static Trile *trile_alloc(cberg_state *cberg);
-static const Morph *select_morph(void);
-static const Color *select_color(cberg_state *);
-
-static void trile_calc_sides(cberg_state *cberg,
- Trile *new, int x, int y, Trile *root)
-{
- unsigned int i,j,k;
- int dv = ( (x + y) % 2 ? +1 : -1); /* we are pointing down or up*/
- Trile *l, *r, *v; /* v_ertical */
-
-
- if (root) {
- l = triles_find(root, x-1, y);
- r = triles_find(root, x+1, y);
- v = triles_find(root, x,y+dv);
- } else
- l = r = v = NULL;
-
- if (v) {
- for (i = 0; i != cberg->epoints; ++i)
- new->v[i] = v->v[i];
- } else {
- if (l) new->v[0] = l->l[0];
- else if (!root) new->v[0] = DISPLACE(0,0);
- else {
- Trile *tr; /* all of these tests needed.. */
- if ( (tr = triles_find(root, x-1, y + dv)) )
- new->v[0] = tr->l[0];
- else if ( (tr = triles_find(root, x-2, y)) )
- new->v[0] = tr->r[0];
- else if ( (tr = triles_find(root, x-2, y + dv)) )
- new->v[0] = tr->r[0];
- else
- new->v[0] = DISPLACE(0,0);
- }
-
- if (r) new->v[cberg->epoints-1] = r->l[0];
- else if (!root) new->v[cberg->epoints-1] = DISPLACE(0,0);
- else {
- Trile *tr;
- if ( (tr = triles_find(root, x+1, y + dv)) )
- new->v[cberg->epoints-1] = tr->l[0];
- else if ( (tr = triles_find(root, x+2, y)) )
- new->v[cberg->epoints-1] = tr->v[0];
- else if ( (tr = triles_find(root, x+2, y + dv)) )
- new->v[cberg->epoints-1] = tr->v[0];
- else
- new->v[cberg->epoints-1] = DISPLACE(0,0);
- }
-
- for (i = ((1 << nsubdivs) >> 1), k =1; i; i >>= 1, ++k)
- for (j = i; j < cberg->epoints; j += i * 2)
- new->v[j] = DISPLACE(MEAN(new->v[j-i], new->v[j+i]), k);
- }
-
- if (l) {
- for (i = 0; i != cberg->epoints; ++i)
- new->l[i] = l->r[i];
- } else {
- if (r) new->l[0] = r->v[0];
- else if (!root) new->l[0] = DISPLACE(0,0);
- else {
- Trile *tr;
- if ( (tr = triles_find(root, x-1, y-dv)) )
- new->l[0] = tr->r[0];
- else if ( (tr = triles_find(root, x+1, y-dv)) )
- new->l[0] = tr->v[0];
- else if ( (tr = triles_find(root, x, y-dv)) )
- new->l[0] = tr->l[0];
- else
- new->l[0] = DISPLACE(0,0);
- }
-
- new->l[cberg->epoints - 1] = new->v[0];
-
- for (i = ((1 << nsubdivs) >> 1), k =1; i; i >>= 1, ++k)
- for (j = i; j < cberg->epoints; j += i * 2)
- new->l[j] = DISPLACE(MEAN(new->l[j-i], new->l[j+i]), k);
- }
-
- if (r) {
- for (i = 0; i != cberg->epoints; ++i)
- new->r[i] = r->l[i];
- } else {
- new->r[0] = new->v[cberg->epoints - 1];
- new->r[cberg->epoints - 1] = new->l[0];
-
- for (i = ((1 << nsubdivs) >> 1), k =1; i; i >>= 1, ++k)
- for (j = i; j < cberg->epoints; j += i * 2)
- new->r[j] = DISPLACE(MEAN(new->r[j-i], new->r[j+i]), k);
- }
-}
-
-static void trile_calc_heights(cberg_state *cberg, Trile *new)
-{
- unsigned int i, j, k, h;
-
- for (i = 0; i < cberg->epoints - 1; ++i) { /* copy in sides */
- TCOORD(i,0) = new->v[i];
- TCOORD(cberg->epoints - 1 - i, i) = new->r[i];
- TCOORD(0, cberg->epoints - 1 - i) = new->l[i];
- }
-
- for (i = ((1 << nsubdivs) >> 2), k =1; i; i >>= 1, ++k)
- for (j = 1; j < (1 << k); ++j)
- for (h = 1; h <= (1<<k) - j; ++h) {
- TCOORD( i*(2*h - 1), i*(2*j - 1) ) = /*rights*/
- DISPLACE(MEAN(TCOORD( i*(2*h - 2), i*(2*j + 0) ),
- TCOORD( i*(2*h + 0), i*(2*j - 2) )), k);
-
- TCOORD( i*(2*h + 0), i*(2*j - 1) ) = /*lefts*/
- DISPLACE(MEAN(TCOORD( i*(2*h + 0), i*(2*j - 2) ),
- TCOORD( i*(2*h + 0), i*(2*j + 0) )), k);
-
- TCOORD( i*(2*h - 1), i*(2*j + 0) ) = /*verts*/
- DISPLACE(MEAN(TCOORD( i*(2*h - 2), i*(2*j + 0) ),
- TCOORD( i*(2*h + 0), i*(2*j + 0) )), k);
- }
-}
-
-static void trile_calc_flat_norms(cberg_state *cberg, Trile *new)
-{
- unsigned int x, y;
- int down = (((new->x + new->y) % 2) ? -1 : +1);
- double dz00,dz01,dz10,dz11, a,b,c,d;
- double dy = down * M_SQRT3_2 / (1 << nsubdivs);
- double dx = cberg->dx0;
-
- for (y = 0; y < cberg->epoints - 1; ++y) {
- a = TCOORD(0,y);
- b = TCOORD(0,y+1);
- for (x = 1; x < cberg->epoints - 1 - y; ++x) {
- c = TCOORD(x,y);
- d = TCOORD(x,y+1);
-
- dz00 = b-c;
- dz01 = a-c;
- dz10 = b-d;
- dz11 = c-d;
-
- SET_fNCOORDa(x,y, down, dz00,dz01);
- SET_fNCOORDb(x,y, down, dz10,dz11);
-
- a = c;
- b = d;
- }
-
- c = TCOORD(x,y);
- dz00 = b-c;
- dz01 = a-c;
- SET_fNCOORDa(x,y, down, dz00, dz01);
- }
-}
-
-static void trile_calc_smooth_norms(cberg_state *cberg, Trile *new)
-{
- unsigned int i,j, down = (new->x + new->y) % 2;
- double prev, cur, next;
- double dx = cberg->dx0;
-
- /** corners -- assume level (bah) **/
- cur = TCOORD(0,0);
- SET_sNCOORD(0,0, down,
- cur,cur,TCOORD(0,1),TCOORD(1,0),cur,cur);
- cur = TCOORD(cberg->epoints-1,0);
- SET_sNCOORD(cberg->epoints-1,0, down,
- TCOORD(cberg->epoints-2,0),TCOORD(cberg->epoints-2,1),cur,cur,cur,cur);
- cur = TCOORD(0,cberg->epoints-1);
- SET_sNCOORD(0,cberg->epoints-1, down,
- cur,cur,cur,cur,TCOORD(1,cberg->epoints-2),TCOORD(0,cberg->epoints-2));
-
-
- /** sides **/
- /* vert */
- prev = TCOORD(0,0);
- cur = TCOORD(1,0);
- for (i = 1; i < cberg->epoints - 1; ++i) {
- next = TCOORD(i+1,0);
- SET_sNCOORD(i,0, down, prev,TCOORD(i-1,1),TCOORD(i,1), next,cur,cur);
- prev = cur;
- cur = next;
- }
-
- /* right */
- prev = TCOORD(cberg->epoints-1,0);
- cur = TCOORD(cberg->epoints-2,0);
- for (i = 1; i < cberg->epoints - 1; ++i) {
- next = TCOORD(cberg->epoints-i-2,i+1);
- SET_sNCOORD(cberg->epoints-i-1,i, down, TCOORD(cberg->epoints-i-2,i),next,cur,
- cur,prev,TCOORD(cberg->epoints-i-1,i-1));
- prev = cur;
- cur = next;
- }
-
- /* left */
- prev = TCOORD(0,0);
- cur = TCOORD(0,1);
- for (i = 1; i < cberg->epoints - 1; ++i) {
- next = TCOORD(0,i+1);
- SET_sNCOORD(0,i, down, cur,cur,next,TCOORD(1,i),TCOORD(1,i-1),prev);
- prev = cur;
- cur = next;
- }
-
-
- /** fill in **/
- for (i = 1; i < cberg->epoints - 2; ++i) {
- prev = TCOORD(0,i);
- cur = TCOORD(1,i);
- for (j = 1; j < cberg->epoints - i - 1; ++j) {
- next = TCOORD(j+1,i);
- SET_sNCOORD(j,i, down, prev,TCOORD(j-1,i+1),TCOORD(j,i+1),
- next,TCOORD(j+1,i-1),TCOORD(j,i-1));
- prev = cur;
- cur = next;
- }
- }
-}
-
-static inline void trile_light(cberg_state *cberg,
- unsigned int x, unsigned int y,
- unsigned int which)
-{
- if (flat) {
- if (x) {
- glNormal3d(fNCOORD(x,y,which,0),
- fNCOORD(x,y,which,1),
- fNCOORD(x,y,which,2));
- } else { /* I get mesa errors and bizarre glitches without this!! */
- glNormal3d(fNCOORD(1,y,0,0),
- fNCOORD(1,y,0,1),
- fNCOORD(1,y,0,2));
- }
- } else {
- glNormal3d(sNCOORD(x,y+which,0),
- sNCOORD(x,y+which,1),
- sNCOORD(x,y+which,2));
- }
-}
-
-static inline void trile_draw_vertex(cberg_state *cberg, unsigned int ix,
- unsigned int iy, unsigned int which, double x,double y,
- double zcur, double z1, double z2)
-{
- glColor3d(0.0, 0.0, 0.0); /* don't ask. my card breaks otherwise. */
-
- if (do_water && zcur <= 0.0) {
- cberg->color->water(cberg, zcur); /* XXX use average-of-3 for color when flat?*/
- if (lit) glNormal3d(0.0,0.0,1.0);
- glVertex3d(x, y, 0.0);
- } else {
- cberg->color->land(cberg, zcur);
- if (lit) trile_light(cberg,ix,iy,which);
- glVertex3d(x, y, zcur);
- }
-}
-
-static void trile_render(cberg_state *cberg, Trile *new)
-{
- double cornerx = 0.5 * new->x - 0.5, cornery;
- double dy = M_SQRT3_2 / (1 << nsubdivs);
- double z0,z1,z2;
- int x,y;
-
- new->call_list = glGenLists(1);
- glNewList(new->call_list, GL_COMPILE);
-
- if ((new->x + new->y) % 2) { /*point down*/
- cornery = (new->y + 0.5)*M_SQRT3_2;
- glFrontFace(GL_CW);
- dy = -dy;
- } else
- cornery = (new->y - 0.5) * M_SQRT3_2;
-
- for (y = 0; y < cberg->epoints - 1; ++y) {
- double dx = cberg->dx0;
- glBegin(GL_TRIANGLE_STRIP);
- /* first three points all part of the same triangle.. */
- z0 = TCOORD(0,y);
- z1 = TCOORD(0,y+1);
- z2 = TCOORD(1,y);
- trile_draw_vertex(cberg, 0,y,0,
- cornerx,cornery, z0, z1, z2);
- trile_draw_vertex(cberg, 0,y,1,
- cornerx+0.5*dx,cornery+dy, z1, z0, z2);
-
- for (x = 1; x < cberg->epoints - 1 - y; ++x) {
- trile_draw_vertex(cberg, x,y,0,
- cornerx+x*dx,cornery, z2, z1, z0);
-
- z0 = TCOORD(x, y+1);
-
- trile_draw_vertex(cberg, x,y,1,
- cornerx+(x+0.5)*dx,cornery+dy, z0, z2, z1);
-
- z1 = z0;
- z0 = z2;
- z2 = TCOORD(x+1,y);
- }
- trile_draw_vertex(cberg, x,y,0,
- cornerx + x*dx, cornery, z2, z1, z0);
- glEnd();
-
- cornerx += dx/2;
- cornery += dy;
- }
-
- if ((new->x + new->y) % 2) /*point down*/
- glFrontFace(GL_CCW);
- glEndList();
-}
-
-static Trile *trile_new(cberg_state *cberg, int x,int y,Trile *parent,Trile *root)
-{
- Trile *new;
-
- new = trile_alloc(cberg);
-
- new->x = x;
- new->y = y;
- new->state = TRILE_NEW;
- new->parent = parent;
- new->left = new->right = NULL;
- new->visible = 1;
-
- new->morph = select_morph();
- new->morph->init(new);
-
- trile_calc_sides(cberg, new, x, y, root);
- trile_calc_heights(cberg, new);
-
- if (lit) {
- if (flat) trile_calc_flat_norms(cberg, new);
- else trile_calc_smooth_norms(cberg, new);
- }
-
- trile_render(cberg, new);
- return new;
-}
-
-static Trile *trile_alloc(cberg_state *cberg)
-{
- Trile *new;
-
- if (cberg->free_head) {
- new = cberg->free_head;
- cberg->free_head = cberg->free_head->next_free;
- } else {
- ++cberg->count;
- if (!(new = calloc(1, sizeof(Trile)))
- || !(new->l = (double *) calloc(sizeof(double), cberg->epoints * 3))) {
- perror(progname);
- exit(1);
- }
- new->r = new->l + cberg->epoints;
- new->v = new->r + cberg->epoints;
- new->next0 = cberg->all_triles;
- cberg->all_triles = new;
-#ifdef DEBUG
- printf("needed to alloc; [%d]\n", cberg->count);
-#endif
- }
- return new;
-}
-
-static void trile_free(cberg_state *cberg, Trile *tr)
-{
- glDeleteLists(tr->call_list, 1);
- tr->morph->free(tr);
- tr->next_free = cberg->free_head;
- cberg->free_head = tr;
-}
-
-
-static void trile_draw_vanilla(Trile *tr)
-{ glCallList(tr->call_list); }
-
-static void trile_draw(Trile *tr, void *ignore)
-{
- if (tr->state == TRILE_STABLE)
- trile_draw_vanilla(tr);
- else
- tr->morph->draw(tr);
-}
-
-
-/***************************
- ** Trile morph functions.
- ** select function at bottom (forward decls sucls)
- ** */
-
-
-/*** first the basic growing morph */
-
-static void grow_init(Trile *tr)
-{
- if (!tr->morph_data)
- tr->morph_data = (void *) malloc(sizeof(double));
- *((double *)tr->morph_data) = 0.02; /* not 0; avoid normals crapping */
-}
-
-static void grow_free(Trile *tr)
-{
- if (tr->morph_data) free(tr->morph_data);
- tr->morph_data = 0;
-}
-
-static void grow_draw(Trile *tr)
-{
- glPushMatrix();
- glScaled(1.0,1.0, *((double *)tr->morph_data));
- trile_draw_vanilla(tr);
- glPopMatrix();
-}
-
-static void grow_init_iter(Trile *tr, cberg_state *cberg)
-{
- *((double *)(tr->morph_data)) = *((double *)tr->morph_data) + cberg->elapsed;
- if (*((double *)tr->morph_data) >= 1.0)
- tr->state = TRILE_STABLE;
-}
-
-static void grow_dying_iter(Trile *tr, cberg_state *cberg)
-{
- *((double *)tr->morph_data) = *((double *)tr->morph_data) - cberg->elapsed;
- if (*((double *)tr->morph_data) <= 0.02) /* XXX avoid fast del/cons? */
- tr->state = TRILE_DELETE;
-}
-
-/**** falling morph ****/
-
-static void fall_init(Trile *tr)
-{
- if (!tr->morph_data)
- tr->morph_data = (void *) malloc(sizeof(double));
- *((double *)tr->morph_data) = 0.0;
-}
-
-static void fall_free(Trile *tr)
-{
- if (tr->morph_data) free(tr->morph_data);
- tr->morph_data = 0;
-}
-
-static void fall_draw(Trile *tr)
-{
- glPushMatrix();
- glTranslated(0.0,0.0,(0.5 - *((double *)tr->morph_data)) * 8);
- trile_draw_vanilla(tr);
- glPopMatrix();
-}
-
-static void fall_init_iter(Trile *tr, cberg_state *cberg)
-{
- *((double *)(tr->morph_data)) = *((double *)tr->morph_data) + cberg->elapsed;
- if (*((double *)tr->morph_data) >= 0.5)
- tr->state = TRILE_STABLE;
-}
-
-static void fall_dying_iter(Trile *tr, cberg_state *cberg)
-{
- *((double *)tr->morph_data) = *((double *)tr->morph_data) - cberg->elapsed;
- if (*((double *)tr->morph_data) <= 0.0) /* XXX avoid fast del/cons? */
- tr->state = TRILE_DELETE;
-}
-
-/**** yeast morph ****/
-
-static void yeast_init(Trile *tr)
-{
- if (!tr->morph_data)
- tr->morph_data = (void *) malloc(sizeof(double));
- *((double *)tr->morph_data) = 0.02;
-}
-
-static void yeast_free(Trile *tr)
-{
- if (tr->morph_data) free(tr->morph_data);
- tr->morph_data = 0;
-}
-
-static void yeast_draw(Trile *tr)
-{
- double x = tr->x * 0.5,
- y = tr->y * M_SQRT3_2,
- z = *((double *)tr->morph_data);
-
- glPushMatrix();
- glTranslated(x, y, 0);
- glRotated(z*360, 0,0,1);
- glScaled(z,z,z);
- glTranslated(-x, -y, 0);
- trile_draw_vanilla(tr);
- glPopMatrix();
-}
-
-static void yeast_init_iter(Trile *tr, cberg_state *cberg)
-{
- *((double *)(tr->morph_data)) = *((double *)tr->morph_data) + cberg->elapsed;
- if (*((double *)tr->morph_data) >= 1.0)
- tr->state = TRILE_STABLE;
-}
-
-static void yeast_dying_iter(Trile *tr, cberg_state *cberg)
-{
- *((double *)tr->morph_data) = *((double *)tr->morph_data) - cberg->elapsed;
- if (*((double *)tr->morph_data) <= 0.02) /* XXX avoid fast del/cons? */
- tr->state = TRILE_DELETE;
-}
-
-/**** identity morph ****/
-
-static void identity_init(Trile *tr)
-{ tr->state = TRILE_STABLE; }
-
-static void identity_free(Trile *tr)
-{}
-
-static void identity_draw(Trile *tr)
-{ trile_draw_vanilla(tr); }
-
-static void identity_init_iter(Trile *tr, cberg_state *cberg)
-{}
-
-static void identity_dying_iter(Trile *tr, cberg_state *cberg)
-{ tr->state = TRILE_DELETE; }
-
-/** now to handle selection **/
-
-static const Morph morphs[] = {
- {grow_init, grow_free, grow_draw, grow_init_iter, grow_dying_iter},
- {fall_init, fall_free, fall_draw, fall_init_iter, fall_dying_iter},
- {yeast_init, yeast_free, yeast_draw, yeast_init_iter, yeast_dying_iter},
- {identity_init, /*always put identity last to skip it..*/
- identity_free, identity_draw, identity_init_iter, identity_dying_iter}
-};
-
-static const Morph *select_morph()
-{
- int nmorphs = countof(morphs);
- if (crack)
- return &morphs[random() % (nmorphs-1)];
- else if (boring)
- return &morphs[nmorphs-1];
- else
- return morphs;
-}
-
-
-/***************************
- ** Trile superstructure functions.
- ** */
-
-
-static void triles_set_visible(cberg_state *cberg, Trile **root, int x, int y)
-{
- Trile *parent = NULL,
- *iter = *root;
- int goleft=0;
-
- while (iter != NULL) {
- parent = iter;
- goleft = (iter->x > x || (iter->x == x && iter->y > y));
- if (goleft)
- iter = iter->left;
- else if (iter->x == x && iter->y == y) {
- iter->visible = 1;
- return;
- } else
- iter = iter->right;
- }
-
- if (parent == NULL)
- *root = trile_new(cberg, x,y, NULL, NULL);
- else if (goleft)
- parent->left = trile_new(cberg, x,y, parent, *root);
- else
- parent->right = trile_new(cberg, x,y, parent, *root);
-}
-
-static unsigned int triles_foreach(Trile *root, void (*f)(Trile *, void *),
- void *data)
-{
- if (root == NULL)
- return 0;
-
- f(root, data);
- return 1 + triles_foreach(root->left, f, data)
- + triles_foreach(root->right, f, data);
-}
-
-static void triles_update_state(Trile **root, cberg_state *cberg)
-{
- int process_current = 1;
- if (*root == NULL)
- return;
-
- while (process_current) {
- if ( (*root)->visible ) {
- if ( (*root)->state == TRILE_INIT )
- (*root)->morph->init_iter(*root, cberg);
- else if ( (*root)->state == TRILE_DYING ) {
- (*root)->state = TRILE_INIT;
- (*root)->morph->init_iter(*root, cberg);
- } else if ( (*root)->state == TRILE_NEW )
- (*root)->state = TRILE_INIT;
-
- (*root)->visible = 0;
- } else {
- if ( (*root)->state == TRILE_STABLE )
- (*root)->state = TRILE_DYING;
- else if ( (*root)->state == TRILE_INIT ) {
- (*root)->state = TRILE_DYING;
- (*root)->morph->dying_iter(*root, cberg);
- } else if ( (*root)->state == TRILE_DYING )
- (*root)->morph->dying_iter(*root, cberg);
- }
-
- if ( (*root)->state == TRILE_DELETE ) {
- Trile *splice_me;
- process_current = 1;
-
- if ((*root)->left == NULL) {
- splice_me = (*root)->right;
- if (splice_me)
- splice_me->parent = (*root)->parent;
- else
- process_current = 0;
- } else if ((*root)->right == NULL) {
- splice_me = (*root)->left;
- splice_me->parent = (*root)->parent;
- } else {
- Trile *tmp;
- for (splice_me = (*root)->right; splice_me->left != NULL; )
- splice_me = splice_me->left;
- tmp = splice_me->right;
-
- if (tmp) tmp->parent = splice_me->parent;
-
- if (splice_me == splice_me->parent->left)
- splice_me->parent->left = tmp;
- else
- splice_me->parent->right = tmp;
-
- splice_me->parent = (*root)->parent;
- splice_me->left = (*root)->left;
- (*root)->left->parent = splice_me;
- splice_me->right = (*root)->right;
- if ((*root)->right)
- (*root)->right->parent = splice_me;
- }
- trile_free(cberg, *root);
- *root = splice_me;
- } else
- process_current = 0;
- }
-
- if (*root) {
- triles_update_state(&((*root)->left), cberg);
- triles_update_state(&((*root)->right), cberg);
- }
-}
-
-static Trile *triles_find(Trile *tr, int x, int y)
-{
- while (tr && !(tr->x == x && tr->y == y))
- if (x < tr->x || (x == tr->x && y < tr->y))
- tr = tr->left;
- else
- tr = tr->right;
- return tr;
-}
-
-
-/***************************
- ** Trile superstructure visibility functions.
- ** strategy fine, implementation lazy&retarded =/
- ** */
-
-#ifdef DEBUG
-static double x_shit, y_shit;
-#endif
-
-static void calc_points(cberg_state *cberg, double *x1,double *y1,
- double *x2,double *y2, double *x3,double *y3, double *x4,double *y4)
-{
- double zNear, x_nearcenter, y_nearcenter, nhalfwidth, x_center, y_center;
-
-
- /* could cache these.. bahhhhhhhhhhhhhh */
- double halfheight = tan(cberg->fovy / 2 * M_PI_180) * cberg->zNear;
- double fovx_2 = atan(halfheight * cberg->aspect / cberg->zNear) * M_180_PI;
- double zFar = cberg->zFar + M_RAD7_4;
- double fhalfwidth = zFar * tan(fovx_2 * M_PI_180)
- + M_RAD7_4 / cos(fovx_2 * M_PI_180);
- double x_farcenter = cberg->x + zFar * cos(cberg->yaw * M_PI_180);
- double y_farcenter = cberg->y + zFar * sin(cberg->yaw * M_PI_180);
- *x1 = x_farcenter + fhalfwidth * cos((cberg->yaw - 90) * M_PI_180);
- *y1 = y_farcenter + fhalfwidth * sin((cberg->yaw - 90) * M_PI_180);
- *x2 = x_farcenter - fhalfwidth * cos((cberg->yaw - 90) * M_PI_180);
- *y2 = y_farcenter - fhalfwidth * sin((cberg->yaw - 90) * M_PI_180);
-
-#ifdef DEBUG
- printf("pos (%.3f,%.3f) @ %.3f || fovx: %f || fovy: %f\n",
- cberg->x, cberg->y, cberg->yaw, fovx_2 * 2, cberg->fovy);
- printf("\tfarcenter: (%.3f,%.3f) || fhalfwidth: %.3f \n"
- "\tp1: (%.3f,%.3f) || p2: (%.3f,%.3f)\n",
- x_farcenter, y_farcenter, fhalfwidth, *x1, *y1, *x2, *y2);
-#endif
-
- if (cberg->z - halfheight <= 0) /* near view plane hits xy */
- zNear = cberg->zNear - M_RAD7_4;
- else /* use bottom of frustum */
- zNear = cberg->z / tan(cberg->fovy / 2 * M_PI_180) - M_RAD7_4;
- nhalfwidth = zNear * tan(fovx_2 * M_PI_180)
- + M_RAD7_4 / cos(fovx_2 * M_PI_180);
- x_nearcenter = cberg->x + zNear * cos(cberg->yaw * M_PI_180);
- y_nearcenter = cberg->y + zNear * sin(cberg->yaw * M_PI_180);
- *x3 = x_nearcenter - nhalfwidth * cos((cberg->yaw - 90) * M_PI_180);
- *y3 = y_nearcenter - nhalfwidth * sin((cberg->yaw - 90) * M_PI_180);
- *x4 = x_nearcenter + nhalfwidth * cos((cberg->yaw - 90) * M_PI_180);
- *y4 = y_nearcenter + nhalfwidth * sin((cberg->yaw - 90) * M_PI_180);
-
-#ifdef DEBUG
- printf("\tnearcenter: (%.3f,%.3f) || nhalfwidth: %.3f\n"
- "\tp3: (%.3f,%.3f) || p4: (%.3f,%.3f)\n",
- x_nearcenter, y_nearcenter, nhalfwidth, *x3, *y3, *x4, *y4);
-#endif
-
-
- /* center can be average or the intersection of diagonals.. */
-#if 0
- {
- double c = nhalfwidth * (zFar -zNear) / (fhalfwidth + nhalfwidth);
- x_center = x_nearcenter + c * cos(cberg->yaw * M_PI_180);
- y_center = y_nearcenter + c * sin(cberg->yaw * M_PI_180);
- }
-#else
- x_center = (x_nearcenter + x_farcenter) / 2;
- y_center = (y_nearcenter + y_farcenter) / 2;
-#endif
-#ifdef DEBUG
- x_shit = x_center;
- y_shit = y_center;
-#endif
-
-#define VSCALE(p) *x##p = visibility * *x##p + (1-visibility) * x_center; \
- *y##p = visibility * *y##p + (1-visibility) * y_center
-
- VSCALE(1);
- VSCALE(2);
- VSCALE(3);
- VSCALE(4);
-#undef VSCALE
-}
-
-/* this is pretty stupid.. */
-static inline void minmax4(double a, double b, double c, double d,
- double *min, double *max)
-{
- *min = *max = a;
-
- if (b > *max) *max = b;
- else if (b < *min) *min = b;
- if (c > *max) *max = c;
- else if (c < *min) *min = c;
- if (d > *max) *max = d;
- else if (d < *min) *min = d;
-}
-
-typedef struct {
- double min, max, start, dx;
-} LS;
-
-#define check_line(a, b) \
- if (fabs(y##a-y##b) > 0.001) { \
- ls[count].dx = (x##b-x##a)/(y##b-y##a); \
- if (y##b > y##a) { \
- ls[count].start = x##a; \
- ls[count].min = y##a; \
- ls[count].max = y##b; \
- } else { \
- ls[count].start = x##b; \
- ls[count].min = y##b; \
- ls[count].max = y##a; \
- } \
- ++count; \
- }
-
-static unsigned int build_ls(cberg_state *cberg,
- double x1, double y1, double x2, double y2,
- double x3, double y3, double x4, double y4, LS *ls,
- double *trough, double *peak)
-{
- unsigned int count = 0;
-
- check_line(1, 2);
- check_line(2, 3);
- check_line(3, 4);
- check_line(4, 1);
-
- minmax4(y1, y2, y3, y4, trough, peak);
- return count;
-}
-
-#undef check_line
-
-/*needs bullshit to avoid double counts on corners.*/
-static void find_bounds(double y, double *left, double *right, LS *ls,
- unsigned int nls)
-{
- double x;
- unsigned int i, set = 0;
-
- for (i = 0; i != nls; ++i)
- if (ls[i].min <= y && ls[i].max >= y) {
- x = (y - ls[i].min) * ls[i].dx + ls[i].start;
- if (!set) {
- *left = x;
- ++set;
- } else if (fabs(x - *left) > 0.001) {
- if (*left < x)
- *right = x;
- else {
- *right = *left;
- *left = x;
- }
- return;
- }
- }
-
- /* just in case we somehow blew up */
- *left = 3.0;
- *right = -3.0;
-}
-
-static void mark_visible(cberg_state *cberg)
-{
- double trough, peak, yval, left=0, right=0;
- double x1,y1, x2,y2, x3,y3, x4,y4;
- int start, stop, x, y;
- LS ls[4];
- unsigned int nls;
-
- calc_points(cberg, &x1,&y1, &x2,&y2, &x3,&y3, &x4,&y4);
- nls = build_ls(cberg, x1,y1, x2,y2, x3,y3, x4,y4, ls, &trough, &peak);
-
- start = (int) ceil(trough / M_SQRT3_2);
- stop = (int) floor(peak / M_SQRT3_2);
-
- for (y = start; y <= stop; ++y) {
- yval = y * M_SQRT3_2;
- find_bounds(yval, &left, &right, ls, nls);
- for (x = (int) ceil(left*2-1); x <= (int) floor(right*2); ++x)
- triles_set_visible(cberg, &(cberg->trile_head), x, y);
- }
-}
-
-
-/***************************
- ** color schemes
- ** */
-
-static void plain_land(cberg_state *cberg, double z)
-{ glColor3f(pow((z/0.35),4), z/0.35, pow((z/0.35),4)); }
-static void plain_water(cberg_state *cberg, double z)
-{ glColor3f(0.0, (z+0.35)*1.6, 0.8); }
-
-static void ice_land(cberg_state *cberg, double z)
-{ glColor3f((0.35 - z)/0.35, (0.35 - z)/0.35, 1.0); }
-static void ice_water(cberg_state *cberg, double z)
-{ glColor3f(0.0, (z+0.35)*1.6, 0.8); }
-
-
-static void magma_land(cberg_state *cberg, double z)
-{ glColor3f(z/0.35, z/0.2,0); }
-static void magma_lava(cberg_state *cberg, double z)
-{ glColor3f((z+0.35)*1.6, (z+0.35), 0.0); }
-
-static void vomit_solid(cberg_state *cberg, double z)
-{
- double norm = fabs(z) / 0.35;
- glColor3f(
- (1-norm) * cberg->vs0r + norm * cberg->vs1r,
- (1-norm) * cberg->vs0g + norm * cberg->vs1g,
- (1-norm) * cberg->vs0b + norm * cberg->vs1b
- );
-}
-static void vomit_fluid(cberg_state *cberg, double z)
-{
- double norm = z / -0.35;
- glColor3f(
- (1-norm) * cberg->vf0r + norm * cberg->vf1r,
- (1-norm) * cberg->vf0g + norm * cberg->vf1g,
- (1-norm) * cberg->vf0b + norm * cberg->vf1b
- );
-}
-
-
-static const Color colors[] = {
- {"plain", plain_land, plain_water, {0.0, 0.0, 0.0, 1.0}},
- {"ice", ice_land, ice_water, {0.0, 0.0, 0.0, 1.0}},
- {"magma", magma_land, magma_lava, {0.3, 0.3, 0.0, 1.0}},
- {"vomit", vomit_solid, vomit_fluid, {0.3, 0.3, 0.0, 1.0}}, /* no error! */
-};
-
-static const Color *select_color(cberg_state *cberg)
-{
- unsigned int ncolors = countof(colors);
- int idx = -1;
- if ( ! strcmp(color, "random") )
- idx = random() % ncolors;
- else {
- unsigned int i;
- for (i = 0; i != ncolors; ++i)
- if ( ! strcmp(colors[i].id, color) ) {
- idx = i;
- break;
- }
-
- if (idx == -1) {
- printf("invalid color scheme selected; valid choices are:\n");
- for (i = 0; i != ncolors; ++i)
- printf("\t%s\n", colors[i].id);
- printf("\t%s\n", "random");
- idx = 0;
- }
- }
-
- if ( ! strcmp(colors[idx].id, "vomit") ) { /* need to create it (ghetto) */
- cberg->vs0r = random()/(double)RAND_MAX;
- cberg->vs0g = random()/(double)RAND_MAX;
- cberg->vs0b = random()/(double)RAND_MAX;
- cberg->vs1r = random()/(double)RAND_MAX;
- cberg->vs1g = random()/(double)RAND_MAX;
- cberg->vs1b = random()/(double)RAND_MAX;
- cberg->vf0r = random()/(double)RAND_MAX;
- cberg->vf0g = random()/(double)RAND_MAX;
- cberg->vf0b = random()/(double)RAND_MAX;
- cberg->vf1r = random()/(double)RAND_MAX;
- cberg->vf1g = random()/(double)RAND_MAX;
- cberg->vf1b = random()/(double)RAND_MAX;
-
- glClearColor(random()/(double)RAND_MAX,
- random()/(double)RAND_MAX,
- random()/(double)RAND_MAX,
- 1.0);
- } else {
- glClearColor(colors[idx].bg[0],
- colors[idx].bg[1],
- colors[idx].bg[2],
- colors[idx].bg[3]);
- }
- return colors + idx;
-}
-
-
-/***************************
- ** misc helper functions
- ** */
-
-
-/* simple one for now.. */
-static inline double drunken_rando(double cur_val, double max, double width)
-{
- double r = random() / (double) RAND_MAX * 2;
- if (cur_val > 0)
- if (r >= 1)
- return cur_val + (r-1) * width * (1-cur_val/max);
- else
- return cur_val - r * width;
- else
- if (r >= 1)
- return cur_val - (r-1) * width * (1+cur_val/max);
- else
- return cur_val + r * width;
-}
-
-
-/***************************
- ** core crackberg routines
- ** */
-
-ENTRYPOINT void reshape_crackberg (ModeInfo *mi, int w, int h);
-
-ENTRYPOINT void init_crackberg (ModeInfo *mi)
-{
- cberg_state *cberg;
-
- nsubdivs %= 16; /* just in case.. */
-
- MI_INIT(mi, cbergs);
-
- if (visibility > 1.0 || visibility < 0.2) {
- printf("visibility must be in range [0.2 .. 1.0]\n");
- visibility = 1.0;
- }
-
- cberg = &cbergs[MI_SCREEN(mi)];
-
- cberg->epoints = 1 + (1 << nsubdivs);
- cberg->tpoints = cberg->epoints * (cberg->epoints + 1) / 2;
- cberg->ntris = (1 << (nsubdivs << 1));
- cberg->tnorms = ( (flat) ? cberg->ntris : cberg->tpoints);
- cberg->dx0 = 1.0 / (1 << nsubdivs);
-
- cberg->heights = malloc(cberg->tpoints * sizeof(double));
- cberg->norms = malloc(3 * cberg->tnorms * sizeof(double));
-
- cberg->glx_context = init_GL(mi);
- cberg->motion_state = MOTION_AUTO;
- cberg->mspeed = 1.0;
- cberg->z = 0.5;
-
- cberg->fovy = 60.0;
- cberg->zNear = 0.5;
- cberg->zFar = 5.0;
-
- cberg->draw_elapsed = 1.0;
-
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glShadeModel((flat) ? GL_FLAT : GL_SMOOTH);
-# ifndef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */
- glPolygonMode(GL_FRONT_AND_BACK, (MI_IS_WIREFRAME(mi)) ? GL_LINE : GL_FILL);
-# endif
-
- if (lit) {
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glEnable(GL_COLOR_MATERIAL);
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
- glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
- glEnable(GL_NORMALIZE);
- glEnable(GL_RESCALE_NORMAL);
- }
-
- cberg->color = select_color(cberg);
-
- reshape_crackberg(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
-}
-
-ENTRYPOINT void reshape_crackberg (ModeInfo *mi, int w, int h)
-{
- int h2;
- cberg_state *cberg = &cbergs[MI_SCREEN(mi)];
-
- if (letterbox && (h2 = w * 9 / 16) < h) {
- glViewport(0, (h-h2)/2, w, h2);
- cberg->aspect = w/(double)h2;
- } else {
- glViewport (0, 0, w, h);
- cberg->aspect = w/(double)h;
- }
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(cberg->fovy, cberg->aspect, cberg->zNear, cberg->zFar);
- glMatrixMode(GL_MODELVIEW);
-}
-
-ENTRYPOINT Bool crackberg_handle_event (ModeInfo *mi, XEvent *ev)
-{
- cberg_state *cberg = &cbergs[MI_SCREEN(mi)];
- KeySym keysym = 0;
- char c = 0;
- if (ev->xany.type == KeyPress || ev->xany.type == KeyRelease)
- XLookupString (&ev->xkey, &c, 1, &keysym, 0);
-
- if (ev->xany.type == KeyPress) {
- switch (keysym) {
- case XK_Left: cberg->motion_state |= MOTION_LROT; break;
- case XK_Prior: cberg->motion_state |= MOTION_LROT; break;
- case XK_Right: cberg->motion_state |= MOTION_RROT; break;
- case XK_Next: cberg->motion_state |= MOTION_RROT; break;
- case XK_Down: cberg->motion_state |= MOTION_BACK; break;
- case XK_Up: cberg->motion_state |= MOTION_FORW; break;
- case '1': cberg->motion_state |= MOTION_DEC; break;
- case '2': cberg->motion_state |= MOTION_INC; break;
- case 'a': cberg->motion_state |= MOTION_LEFT; break;
- case 'd': cberg->motion_state |= MOTION_RIGHT; break;
- case 's': cberg->motion_state |= MOTION_BACK; break;
- case 'w': cberg->motion_state |= MOTION_FORW; break;
- default: return False;
- }
- cberg->motion_state |= MOTION_MANUAL;
- } else if (ev->xany.type == KeyRelease) {
-#if 0
- XEvent peek_ev;
- if (XPending(mi->dpy)) {
- XPeekEvent(mi->dpy, &peek_ev);
- if (peek_ev.type == KeyPress
- && peek_ev.xkey.keycode == ev->xkey.keycode
- && peek_ev.xkey.time - ev->xkey.time < 2) {
- XNextEvent(mi->dpy, &peek_ev); /* drop bullshit repeat events */
- return False;
- }
- }
-#endif
-
- switch (keysym) {
- case XK_Left: cberg->motion_state &= ~MOTION_LROT; break;
- case XK_Prior: cberg->motion_state &= ~MOTION_LROT; break;
- case XK_Right: cberg->motion_state &= ~MOTION_RROT; break;
- case XK_Next: cberg->motion_state &= ~MOTION_RROT; break;
- case XK_Down: cberg->motion_state &= ~MOTION_BACK; break;
- case XK_Up: cberg->motion_state &= ~MOTION_FORW; break;
- case '1': cberg->motion_state &= ~MOTION_DEC; break;
- case '2': cberg->motion_state &= ~MOTION_INC; break;
- case 'a': cberg->motion_state &= ~MOTION_LEFT; break;
- case 'd': cberg->motion_state &= ~MOTION_RIGHT; break;
- case 's': cberg->motion_state &= ~MOTION_BACK; break;
- case 'w': cberg->motion_state &= ~MOTION_FORW; break;
- case ' ':
- if (cberg->motion_state == MOTION_MANUAL)
- cberg->motion_state = MOTION_AUTO;
- break;
- default: return False;
- }
- } else if (ev->xany.type == ButtonPress &&
- ev->xbutton.button == Button1) {
- cberg->button_down_p = True;
- cberg->mouse_x = ev->xbutton.x;
- cberg->mouse_y = ev->xbutton.y;
- cberg->motion_state = MOTION_MANUAL;
- cberg->paused.tv_sec = 0;
- } else if (ev->xany.type == ButtonRelease &&
- ev->xbutton.button == Button1) {
- cberg->button_down_p = False;
- cberg->motion_state = MOTION_AUTO;
- /* After mouse-up, don't go back into auto-motion mode for a second, so
- that repeated click-and-drag gestures don't fight with auto-motion. */
- gettimeofday(&cberg->paused, NULL);
- } else if (ev->xany.type == MotionNotify &&
- cberg->button_down_p) {
- int dx = ev->xmotion.x - cberg->mouse_x;
- int dy = ev->xmotion.y - cberg->mouse_y;
- cberg->mouse_x = ev->xmotion.x;
- cberg->mouse_y = ev->xmotion.y;
- cberg->motion_state = MOTION_MANUAL;
-
- /* Take the larger dimension, since motion_state doesn't scale */
- if (dx > 0 && dx > dy) dy = 0;
- if (dx < 0 && dx < dy) dy = 0;
- if (dy > 0 && dy > dx) dx = 0;
- if (dy < 0 && dy < dx) dx = 0;
-
- {
- int rot = current_device_rotation();
- int swap;
- while (rot <= -180) rot += 360;
- while (rot > 180) rot -= 360;
- if (rot > 135 || rot < -135) /* 180 */
- dx = -dx, dy = -dy;
- else if (rot > 45) /* 90 */
- swap = dx, dx = -dy, dy = swap;
- else if (rot < -45) /* 270 */
- swap = dx, dx = dy, dy = -swap;
- }
-
- if (dx > 0) cberg->motion_state |= MOTION_LEFT;
- else if (dx < 0) cberg->motion_state |= MOTION_RIGHT;
- else if (dy > 0) cberg->motion_state |= MOTION_FORW;
- else if (dy < 0) cberg->motion_state |= MOTION_BACK;
- } else
- return False;
- return True;
-}
-
-ENTRYPOINT void draw_crackberg (ModeInfo *mi)
-{
- cberg_state *cberg = &cbergs[MI_SCREEN(mi)];
- struct timeval cur_frame_t;
- double cur_frame;
- static const float lpos[] = {2.0,0.0,-0.3,0.0};
-
- if (!cberg->glx_context) /*XXX does this get externally tweaked? it kinda*/
- return; /*XXX can't.. check it in crackberg_init*/
-
- glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *cberg->glx_context);
-
- gettimeofday(&cur_frame_t, NULL);
- cur_frame = cur_frame_t.tv_sec + cur_frame_t.tv_usec / 1.0E6;
- if ( cberg->prev_frame ) { /*not first run */
-
- cberg->elapsed = cur_frame - cberg->prev_frame;
-
- if (cberg->motion_state == MOTION_AUTO &&
- cberg->paused.tv_sec < cur_frame_t.tv_sec) {
- cberg->x += cberg->dx * cberg->elapsed;
- cberg->y += cberg->dy * cberg->elapsed;
- /* cberg->z */
- /* cberg->pitch */
- /* cberg->roll */
- cberg->yaw += cberg->dyaw * cberg->elapsed;
-
- cberg->draw_elapsed += cberg->elapsed;
- if (cberg->draw_elapsed >= 0.8) {
- cberg->draw_elapsed = 0.0;
- cberg->dx = drunken_rando(cberg->dx, 2.5, 0.8);
- cberg->dy = drunken_rando(cberg->dy, 2.5, 0.8);
- /* cberg->dz */
- /* cberg->dpitch */
- /* cberg->droll */
- cberg->dyaw = drunken_rando(cberg->dyaw, 40.0, 8.0);
- }
- } else {
- double scale = cberg->elapsed * cberg->mspeed;
- if (cberg->motion_state & MOTION_BACK) {
- cberg->x -= cos(cberg->yaw * M_PI_180) * scale;
- cberg->y -= sin(cberg->yaw * M_PI_180) * scale;
- }
- if (cberg->motion_state & MOTION_FORW) {
- cberg->x += cos(cberg->yaw * M_PI_180) * scale;
- cberg->y += sin(cberg->yaw * M_PI_180) * scale;
- }
-
- if (cberg->motion_state & MOTION_LEFT) {
- cberg->x -= sin(cberg->yaw * M_PI_180) * scale;
- cberg->y += cos(cberg->yaw * M_PI_180) * scale;
- }
- if (cberg->motion_state & MOTION_RIGHT) {
- cberg->x += sin(cberg->yaw * M_PI_180) * scale;
- cberg->y -= cos(cberg->yaw * M_PI_180) * scale;
- }
-
- if (cberg->motion_state & MOTION_LROT)
- cberg->yaw += 45 * scale;
- if (cberg->motion_state & MOTION_RROT)
- cberg->yaw -= 45 * scale;
-
- if (cberg->motion_state & MOTION_DEC)
- cberg->mspeed /= pow(MSPEED_SCALE, cberg->draw_elapsed);
- if (cberg->motion_state & MOTION_INC)
- cberg->mspeed *= pow(MSPEED_SCALE, cberg->draw_elapsed);
-
- }
- }
- cberg->prev_frame = cur_frame;
-
- mark_visible(cberg);
- triles_update_state(&(cberg->trile_head), cberg);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glLoadIdentity();
- glRotatef(current_device_rotation(), 0, 0, 1);
- gluLookAt(0,0,0, 1,0,0, 0,0,1);
- glLightfv(GL_LIGHT0, GL_POSITION, lpos);
- /*glRotated(cberg->roll, 1,0,0); / * XXX blah broken and unused for now..* /
- glRotated(cberg->pitch, 0,1,0); */
- glRotated(-cberg->yaw, 0,0,1); /* camera sees ->yaw over */
- glTranslated(-cberg->x, -cberg->y, -cberg->z);
-
- mi->polygon_count = cberg->ntris *
- triles_foreach(cberg->trile_head, trile_draw,(void *) cberg);
-
- if (mi->fps_p)
- do_fps(mi);
-
-#ifdef DEBUG
- glBegin(GL_LINES);
- glColor3f(1.0,0.0,0.0);
- glVertex3d(x_shit, y_shit, 0.0);
- glVertex3d(x_shit, y_shit, 1.0);
- glEnd();
-#endif
-
- glFinish();
- glXSwapBuffers(MI_DISPLAY(mi), MI_WINDOW(mi));
-}
-
-/* uh */
-ENTRYPOINT void free_crackberg (ModeInfo *mi)
-{
- cberg_state *cberg = &cbergs[MI_SCREEN(mi)];
- if (!cberg->glx_context) return;
- glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *cberg->glx_context);
- while (cberg->all_triles) {
- Trile *n = cberg->all_triles;
- cberg->all_triles = n->next0;
- free (n->l);
- if (n->morph_data) free (n->morph_data);
- free (n);
- }
- if (cberg->norms) free(cberg->norms);
- if (cberg->heights) free(cberg->heights);
-}
-
-XSCREENSAVER_MODULE ("Crackberg", crackberg)
-
-#endif /* USE_GL */