X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fhypercube.c;h=4fb16c584c80fb417a574ba496b6cb73b25eec2d;hb=aa75c7476aeaa84cf3abc192b376a8b03c325213;hp=37ac07455746c27c3387bc670dc6036bcd60230b;hpb=258170f6204e23da06f272ffda1f4504b6ae2eaf;p=xscreensaver diff --git a/hacks/hypercube.c b/hacks/hypercube.c index 37ac0745..4fb16c58 100644 --- a/hacks/hypercube.c +++ b/hacks/hypercube.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1992 Jamie Zawinski +/* xscreensaver, Copyright (c) 1992-2008 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -12,239 +12,94 @@ * and Jamie Zawinski. */ -#include "screenhack.h" #include +#include "screenhack.h" -static Display *dpy; -static Window window; -static GC color0, color1, color2, color3, color4, color5, color6, color7; -static GC black; - -static int delay; +#define POINT_COUNT 16 +#define LINE_COUNT 32 -static int observer_z; -static int x_offset, y_offset; -static int unit_pixels; +#define ANGLE_SCALE 0.001 -struct point_state { - int old_x, old_y; - int new_x, new_y; - Bool same_p; +struct line_info +{ + char li_ip; + char li_iq; + char li_color; + char li_pad; }; -static void -move_line (state0, state1, gc) - struct point_state *state0, *state1; - GC gc; +struct point_state { - if (state0->same_p && state1->same_p) - return; - if (mono_p) - { - XDrawLine (dpy, window, black, - state0->old_x, state0->old_y, state1->old_x, state1->old_y); - XDrawLine (dpy, window, gc, - state0->new_x, state0->new_y, state1->new_x, state1->new_y); - } - else - { - XSegment segments [2]; - segments [0].x1 = state0->old_x; segments [0].y1 = state0->old_y; - segments [0].x2 = state1->old_x; segments [0].y2 = state1->old_y; - segments [1].x1 = state0->new_x; segments [1].y1 = state0->new_y; - segments [1].x2 = state1->new_x; segments [1].y2 = state1->new_y; - XDrawSegments (dpy, window, gc, segments, 2); - } -} + short old_x, old_y; + short new_x, new_y; +}; -static void -hyper (xy, xz, yz, xw, yw, zw) - double xy, xz, yz, xw, yw, zw; +struct hyper_state { - double cos_xy = cos (xy), sin_xy = sin (xy); - double cos_xz = cos (xz), sin_xz = sin (xz); - double cos_yz = cos (yz), sin_yz = sin (yz); - double cos_xw = cos (xw), sin_xw = sin (xw); - double cos_yw = cos (yw), sin_yw = sin (yw); - double cos_zw = cos (zw), sin_zw = sin (zw); - - double ax = 1.0, ay = 0.0, az = 0.0, aw = 0.0; - double bx = 0.0, by = 1.0, bz = 0.0, bw = 0.0; - double cx = 0.0, cy = 0.0, cz = 1.0, cw = 0.0; - double dx = 0.0, dy = 0.0, dz = 0.0, dw = 1.0; - - double _tmp0_, _tmp1_; - - struct point_state points [16]; - bzero (points, sizeof (points)); - -#define mmmm (&points[0]) -#define mmmp (&points[1]) -#define mmpm (&points[2]) -#define mmpp (&points[3]) -#define mpmm (&points[4]) -#define mpmp (&points[5]) -#define mppm (&points[6]) -#define mppp (&points[7]) -#define pmmm (&points[8]) -#define pmmp (&points[9]) -#define pmpm (&points[10]) -#define pmpp (&points[11]) -#define ppmm (&points[12]) -#define ppmp (&points[13]) -#define pppm (&points[14]) -#define pppp (&points[15]) - - while (1) - { - double temp_mult; - -#define compute(a,b,c,d,point_state) \ - temp_mult = (unit_pixels / (((a*az) + (b*bz) + (c*cz) + (d*dz) + \ - (a*aw) + (b*bw) + (c*cw) + (d*dw)) \ - - observer_z)); \ - point_state->old_x = point_state->new_x; \ - point_state->old_y = point_state->new_y; \ - point_state->new_x = ((((a*ax) + (b*bx) + (c*cx) + (d*dx)) * temp_mult) \ - + x_offset); \ - point_state->new_y = ((((a*ay) + (b*by) + (c*cy) + (d*dy)) * temp_mult) \ - + y_offset); \ - point_state->same_p = (point_state->old_x == point_state->new_x && \ - point_state->old_y == point_state->new_y); - - compute (-1, -1, -1, -1, mmmm); - compute (-1, -1, -1, 1, mmmp); - compute (-1, -1, 1, -1, mmpm); - compute (-1, -1, 1, 1, mmpp); - compute (-1, 1, -1, -1, mpmm); - compute (-1, 1, -1, 1, mpmp); - compute (-1, 1, 1, -1, mppm); - compute (-1, 1, 1, 1, mppp); - compute ( 1, -1, -1, -1, pmmm); - compute ( 1, -1, -1, 1, pmmp); - compute ( 1, -1, 1, -1, pmpm); - compute ( 1, -1, 1, 1, pmpp); - compute ( 1, 1, -1, -1, ppmm); - compute ( 1, 1, -1, 1, ppmp); - compute ( 1, 1, 1, -1, pppm); - compute ( 1, 1, 1, 1, pppp); - - move_line (mmmm, mmmp, color0); - move_line (mmmm, mmpm, color0); - move_line (mmpm, mmpp, color0); - move_line (mmmp, mmpp, color0); - - move_line (pmmm, pmmp, color1); - move_line (pmmm, pmpm, color1); - move_line (pmpm, pmpp, color1); - move_line (pmmp, pmpp, color1); - - move_line (mpmm, mpmp, color2); - move_line (mpmm, mppm, color2); - move_line (mppm, mppp, color2); - move_line (mpmp, mppp, color2); - - move_line (mmpp, mppp, color3); - move_line (mmpp, pmpp, color3); - move_line (pmpp, pppp, color3); - move_line (mppp, pppp, color3); - - move_line (mmmm, mpmm, color4); - move_line (mmmm, pmmm, color4); - move_line (mpmm, ppmm, color4); - move_line (pmmm, ppmm, color4); - - move_line (mmmp, mpmp, color5); - move_line (mmmp, pmmp, color5); - move_line (pmmp, ppmp, color5); - move_line (mpmp, ppmp, color5); - - move_line (mmpm, mppm, color6); - move_line (mmpm, pmpm, color6); - move_line (pmpm, pppm, color6); - move_line (mppm, pppm, color6); - - move_line (ppmm, ppmp, color7); - move_line (ppmm, pppm, color7); - move_line (pppm, pppp, color7); - move_line (ppmp, pppp, color7); - - /* If you get error messages about the following forms, and you think you're - using an ANSI C conforming compiler, then you're mistaken. Possibly you're - mixing an ANSI compiler with a non-ANSI preprocessor, or vice versa. - Regardless, your system is broken; it's not a bug in this program. - */ -#if __STDC__ || SVR4 -# define rotate(name,dim0,dim1,cos,sin) \ - _tmp0_ = ((name##dim0 * cos) + (name##dim1 * sin)); \ - _tmp1_ = ((name##dim1 * cos) - (name##dim0 * sin)); \ - name##dim0 = _tmp0_; \ - name##dim1 = _tmp1_; - -# define rotates(dim0,dim1) \ - if (sin_##dim0##dim1 != 0) { \ - rotate(a, dim0, dim1, cos_##dim0##dim1, sin_##dim0##dim1); \ - rotate(b, dim0, dim1, cos_##dim0##dim1, sin_##dim0##dim1); \ - rotate(c, dim0, dim1, cos_##dim0##dim1, sin_##dim0##dim1); \ - rotate(d, dim0, dim1, cos_##dim0##dim1, sin_##dim0##dim1); \ - } - -#else /* !__STDC__, courtesy of Andreas Luik */ -# define rotate(name,dim0,dim1,cos,sin) \ - _tmp0_ = ((name/**/dim0 * cos) + (name/**/dim1 * sin)); \ - _tmp1_ = ((name/**/dim1 * cos) - (name/**/dim0 * sin)); \ - name/**/dim0 = _tmp0_; \ - name/**/dim1 = _tmp1_; - -# define rotates(dim0,dim1) \ - if (sin_/**/dim0/**/dim1 != 0) { \ - rotate(a,dim0,dim1,cos_/**/dim0/**/dim1,sin_/**/dim0/**/dim1); \ - rotate(b,dim0,dim1,cos_/**/dim0/**/dim1,sin_/**/dim0/**/dim1); \ - rotate(c,dim0,dim1,cos_/**/dim0/**/dim1,sin_/**/dim0/**/dim1); \ - rotate(d,dim0,dim1,cos_/**/dim0/**/dim1,sin_/**/dim0/**/dim1); \ - } -#endif /* !__STDC__ */ - - rotates (x,y); - rotates (x,z); - rotates (y,z); - rotates (x,w); - rotates (y,w); - rotates (z,w); - - XSync (dpy, True); - if (delay) usleep (delay); - } -} + char hs_stop; + char hs_icon; + char hs_resize; + char hs_redraw; + Display *hs_display; + Window hs_window; + float hs_two_observer_z; + float hs_offset_x; + float hs_offset_y; + float hs_unit_scale; + int hs_delay; + GC hs_color_gcs[8]; + GC black_gc; +#if 0 + double hs_angle_xy; + double hs_angle_xz; + double hs_angle_yz; + double hs_angle_xw; + double hs_angle_yw; + double hs_angle_zw; +#endif + double hs_cos_xy, hs_sin_xy; + double hs_cos_xz, hs_sin_xz; + double hs_cos_yz, hs_sin_yz; + double hs_cos_xw, hs_sin_xw; + double hs_cos_yw, hs_sin_yw; + double hs_cos_zw, hs_sin_zw; + double hs_ref_ax, hs_ref_ay, hs_ref_az, hs_ref_aw; + double hs_ref_bx, hs_ref_by, hs_ref_bz, hs_ref_bw; + double hs_ref_cx, hs_ref_cy, hs_ref_cz, hs_ref_cw; + double hs_ref_dx, hs_ref_dy, hs_ref_dz, hs_ref_dw; + struct point_state hs_points[POINT_COUNT]; + int roted; +}; - -char *progclass = "Hypercube"; +static const struct line_info line_table[LINE_COUNT]; -char *defaults [] = { - "*background: black", - "*foreground: white", - "*color0: red", - "*color1: orange", - "*color2: yellow", - "*color3: white", +static const char *hypercube_defaults[] = +{ + "*observer-z: 3.0", + "*delay: 10000", + "*xy: 3", + "*xz: 5", + "*yw: 10", + "*yz: 0", + "*xw: 0", + "*zw: 0", + ".background: black", + ".foreground: white", + "*fpsSolid: true", + "*color0: magenta", + "*color3: #FF0093", + "*color1: yellow", + "*color2: #FF9300", "*color4: green", - "*color5: cyan", - "*color6: blue", - "*color7: magenta", - - "*xw: 0.000", - "*xy: 0.010", - "*xz: 0.005", - "*yw: 0.010", - "*yz: 0.000", - "*zw: 0.000", - - "*observer-z: 5", - "*delay: 100000", + "*color7: #00FFD0", + "*color5: #8080FF", + "*color6: #00D0FF", + 0 }; -XrmOptionDescRec options [] = { +static XrmOptionDescRec hypercube_options [] = +{ { "-color0", ".color0", XrmoptionSepArg, 0 }, { "-color1", ".color1", XrmoptionSepArg, 0 }, { "-color2", ".color2", XrmoptionSepArg, 0 }, @@ -262,73 +117,455 @@ XrmOptionDescRec options [] = { { "-zw", ".zw", XrmoptionSepArg, 0 }, { "-observer-z", ".observer-z", XrmoptionSepArg, 0 }, - { "-delay", ".delay", XrmoptionSepArg, 0 } + { "-delay", ".delay", XrmoptionSepArg, 0 }, + { 0, 0, 0, 0 } }; -int options_size = (sizeof (options) / sizeof (options[0])); +static void set_sizes (struct hyper_state *hs, int width, int height); -void -screenhack (d, w) - Display *d; - Window w; +static void * +hypercube_init (Display *dpy, Window win) { XGCValues gcv; - XWindowAttributes xgwa; Colormap cmap; - double xy, xz, yz, xw, yw, zw; - unsigned long bg, pixel; - - dpy = d; - window = w; - XGetWindowAttributes (dpy, window, &xgwa); - cmap = xgwa.colormap; + unsigned long bg_pixel; + int delay; + float observer_z; - x_offset = xgwa.width / 2; - y_offset = xgwa.height / 2; - unit_pixels = xgwa.width < xgwa.height ? xgwa.width : xgwa.height; + struct hyper_state *hs = (struct hyper_state *) calloc (1, sizeof(*hs)); + hs->hs_display = dpy; + hs->hs_window = win; - xy = get_float_resource ("xy", "Float"); - xz = get_float_resource ("xz", "Float"); - yz = get_float_resource ("yz", "Float"); - xw = get_float_resource ("xw", "Float"); - yw = get_float_resource ("yw", "Float"); - zw = get_float_resource ("zw", "Float"); + observer_z = get_float_resource (dpy, "observer-z", "Float"); + if (observer_z < 1.125) + observer_z = 1.125; + /* hs->hs_observer_z = observer_z; */ + hs->hs_two_observer_z = 2.0 * observer_z; - observer_z = get_integer_resource ("observer-z", "Integer"); + { + XWindowAttributes wa; + XGetWindowAttributes (dpy, win, &wa); + cmap = wa.colormap; + set_sizes (hs, wa.width, wa.height); + } - delay = get_integer_resource ("delay", "Integer"); + delay = get_integer_resource (dpy, "delay", "Integer"); + hs->hs_delay = delay; - bg = get_pixel_resource ("background", "Background", dpy, cmap); + bg_pixel = get_pixel_resource (dpy, cmap, "background", "Background"); if (mono_p) { + GC black_gc; + unsigned long fg_pixel; + GC white_gc; + gcv.function = GXcopy; - gcv.foreground = bg; - black = XCreateGC (dpy, window, GCForeground|GCFunction, &gcv); - gcv.foreground = get_pixel_resource ("foreground", "Foreground", - dpy, cmap); - color0 = color1 = color2 = color3 = color4 = color5 = color6 = color7 = - XCreateGC (dpy, window, GCForeground|GCFunction, &gcv); + gcv.foreground = bg_pixel; + black_gc = XCreateGC (dpy, win, GCForeground|GCFunction, &gcv); + fg_pixel = get_pixel_resource (dpy, cmap, "foreground", "Foreground"); + gcv.foreground = fg_pixel ^ bg_pixel; + white_gc = XCreateGC (dpy, win, GCForeground|GCFunction, &gcv); + hs->hs_color_gcs[0] = black_gc; + hs->hs_color_gcs[1] = white_gc; } else { - black = 0; - gcv.function = GXxor; -#define make_gc(color,name) \ - gcv.foreground = bg ^ get_pixel_resource ((name), "Foreground", \ - dpy, cmap); \ - color = XCreateGC (dpy, window, GCForeground|GCFunction, &gcv) - - make_gc (color0,"color0"); - make_gc (color1,"color1"); - make_gc (color2,"color2"); - make_gc (color3,"color3"); - make_gc (color4,"color4"); - make_gc (color5,"color5"); - make_gc (color6,"color6"); - make_gc (color7,"color7"); + int col; + + gcv.function = GXcopy; + + gcv.foreground = get_pixel_resource (dpy, cmap, + "background", "Background"); + hs->black_gc = XCreateGC (dpy, win, GCForeground|GCFunction, &gcv); + + for (col = 0; col < 8; col++) + { + char buffer[16]; + unsigned long fg_pixel; + GC color_gc; + + sprintf (buffer, "color%d", col); + fg_pixel = get_pixel_resource (dpy, cmap, buffer, "Foreground"); + gcv.foreground = fg_pixel; + color_gc = XCreateGC (dpy, win, GCForeground|GCFunction, &gcv); + hs->hs_color_gcs[col] = color_gc; + } + } + + hs->hs_ref_ax = 1.0, hs->hs_ref_ay = 0.0, hs->hs_ref_az = 0.0, hs->hs_ref_aw = 0.0; + hs->hs_ref_bx = 0.0, hs->hs_ref_by = 1.0, hs->hs_ref_bz = 0.0, hs->hs_ref_bw = 0.0; + hs->hs_ref_cx = 0.0, hs->hs_ref_cy = 0.0, hs->hs_ref_cz = 1.0, hs->hs_ref_cw = 0.0; + hs->hs_ref_dx = 0.0, hs->hs_ref_dy = 0.0, hs->hs_ref_dz = 0.0, hs->hs_ref_dw = 1.0; + + { + double xy; + double xz; + double yz; + double xw; + double yw; + double zw; + double cos_xy, sin_xy; + double cos_xz, sin_xz; + double cos_yz, sin_yz; + double cos_xw, sin_xw; + double cos_yw, sin_yw; + double cos_zw, sin_zw; + + xy = get_float_resource (dpy, "xy", "Float") * ANGLE_SCALE; + xz = get_float_resource (dpy, "xz", "Float") * ANGLE_SCALE; + yz = get_float_resource (dpy, "yz", "Float") * ANGLE_SCALE; + xw = get_float_resource (dpy, "xw", "Float") * ANGLE_SCALE; + yw = get_float_resource (dpy, "yw", "Float") * ANGLE_SCALE; + zw = get_float_resource (dpy, "zw", "Float") * ANGLE_SCALE; + + cos_xy = cos (xy), sin_xy = sin (xy); + hs->hs_cos_xy = cos_xy, hs->hs_sin_xy = sin_xy; + cos_xz = cos (xz), sin_xz = sin (xz); + hs->hs_cos_xz = cos_xz, hs->hs_sin_xz = sin_xz; + cos_yz = cos (yz), sin_yz = sin (yz); + hs->hs_cos_yz = cos_yz, hs->hs_sin_yz = sin_yz; + cos_xw = cos (xw), sin_xw = sin (xw); + hs->hs_cos_xw = cos_xw, hs->hs_sin_xw = sin_xw; + cos_yw = cos (yw), sin_yw = sin (yw); + hs->hs_cos_yw = cos_yw, hs->hs_sin_yw = sin_yw; + cos_zw = cos (zw), sin_zw = sin (zw); + hs->hs_cos_zw = cos_zw, hs->hs_sin_zw = sin_zw; + } + + return hs; +} + + +static unsigned long +hypercube_draw (Display *dpy, Window window, void *closure) +{ + struct hyper_state *hs = (struct hyper_state *) closure; + int this_delay = hs->hs_delay; + +#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */ + XClearWindow (dpy, window); +#endif + + { + int icon; + int resize; + char moved[POINT_COUNT]; + int redraw; + int stop; + int delay; + + icon = hs->hs_icon; + resize = hs->hs_resize; + if (icon || !(hs->roted | resize)) + goto skip1; + + { + float observer_z; + float unit_scale; + float offset_x; + float offset_y; + double az, bz, cz, dz; + double sum_z; + double ax, bx, cx, dx; + double sum_x; + double ay, by, cy, dy; + double sum_y; + struct point_state *ps; + int old_x; + int old_y; + double mul; + double xf; + double yf; + int new_x; + int new_y; + int mov; + + +#define compute(as,bs,cs,ds,i) \ + az = hs->hs_ref_az; bz = hs->hs_ref_bz; cz = hs->hs_ref_cz; dz = hs->hs_ref_dz; \ + ax = hs->hs_ref_ax; bx = hs->hs_ref_bx; cx = hs->hs_ref_cx; dx = hs->hs_ref_dx; \ + ay = hs->hs_ref_ay; by = hs->hs_ref_by; cy = hs->hs_ref_cy; dy = hs->hs_ref_dy; \ + sum_z = as az bs bz cs cz ds dz; \ + observer_z = hs->hs_two_observer_z; \ + unit_scale = hs->hs_unit_scale; \ + sum_x = as ax bs bx cs cx ds dx; \ + sum_y = as ay bs by cs cy ds dy; \ + ps = &hs->hs_points[i]; \ + mul = unit_scale / (observer_z - sum_z); \ + offset_x = hs->hs_offset_x; \ + offset_y = hs->hs_offset_y; \ + old_x = ps->new_x; \ + old_y = ps->new_y; \ + xf = sum_x * mul + offset_x; \ + yf = sum_y * mul + offset_y; \ + new_x = (int)rint(xf); \ + new_y = (int)rint(yf); \ + ps->old_x = old_x; \ + ps->old_y = old_y; \ + ps->new_x = new_x; \ + ps->new_y = new_y; \ + mov = old_x != new_x || old_y != new_y; \ + moved[i] = mov; + + compute (-, -, -, -, 0); + compute (-, -, -, +, 1); + compute (-, -, +, -, 2); + compute (-, -, +, +, 3); + compute (-, +, -, -, 4); + compute (-, +, -, +, 5); + compute (-, +, +, -, 6); + compute (-, +, +, +, 7); + compute (+, -, -, -, 8); + compute (+, -, -, +, 9); + compute (+, -, +, -, 10); + compute (+, -, +, +, 11); + compute (+, +, -, -, 12); + compute (+, +, -, +, 13); + compute (+, +, +, -, 14); + compute (+, +, +, +, 15); + } + + skip1: + icon = hs->hs_icon; + redraw = hs->hs_redraw; + if (icon || !(hs->roted | redraw)) + goto skip2; + + { + int lc; + const struct line_info *lip; + int mono; + Window win; + + lc = LINE_COUNT; + lip = &line_table[0]; + mono = mono_p; + win = hs->hs_window; + + while (--lc >= 0) + { + int ip; + int iq; + int col; + struct point_state *sp; + struct point_state *sq; + int mov_p; + int mov_q; + GC erase_gc; + GC draw_gc; + int p_x; + int p_y; + int q_x; + int q_y; + + ip = lip->li_ip; + iq = lip->li_iq; + col = lip->li_color; + lip++; + mov_p = moved[ip]; + mov_q = moved[iq]; + if (!(redraw | mov_p | mov_q)) + continue; + + sp = &hs->hs_points[ip]; + sq = &hs->hs_points[iq]; + + if (mono) + { + erase_gc = hs->hs_color_gcs[0]; + draw_gc = hs->hs_color_gcs[1]; + } + else + { + erase_gc = hs->black_gc; + draw_gc = hs->hs_color_gcs[col]; + } + + if (!redraw) + { + p_x = sp->old_x; + p_y = sp->old_y; + q_x = sq->old_x; + q_y = sq->old_y; + XDrawLine (dpy, win, erase_gc, p_x, p_y, q_x, q_y); + } + + p_x = sp->new_x; + p_y = sp->new_y; + q_x = sq->new_x; + q_y = sq->new_y; + XDrawLine (dpy, win, draw_gc, p_x, p_y, q_x, q_y); + } + } + + skip2: + stop = hs->hs_stop; + hs->roted = 0; + if (stop) + goto skip3; + + hs->roted = 1; + + { + double cos_a; + double sin_a; + double old_u; + double old_v; + double new_u; + double new_v; + + /* If you get error messages about the following forms, and you think you're + using an ANSI C conforming compiler, then you're mistaken. Possibly you're + mixing an ANSI compiler with a non-ANSI preprocessor, or vice versa. + Regardless, your system is broken; it's not a bug in this program. + */ +#if defined(__STDC__) || defined(__ANSI_CPP__) + +#define rotate(name,dim0,dim1) \ + old_u = hs->hs_ref_##name##dim0; \ + old_v = hs->hs_ref_##name##dim1; \ + new_u = old_u * cos_a + old_v * sin_a; \ + new_v = old_v * cos_a - old_u * sin_a; \ + hs->hs_ref_##name##dim0 = new_u; \ + hs->hs_ref_##name##dim1 = new_v; + +#define rotates(dim0,dim1) \ + if (hs->hs_sin_##dim0##dim1 != 0) { \ + cos_a = hs->hs_cos_##dim0##dim1; \ + sin_a = hs->hs_sin_##dim0##dim1; \ + rotate(a,dim0,dim1); \ + rotate(b,dim0,dim1); \ + rotate(c,dim0,dim1); \ + rotate(d,dim0,dim1); \ + } + +#else /* !__STDC__, courtesy of Andreas Luik */ + +#define rotate(name,dim0,dim1) \ + old_u = hs->hs_ref_/**/name/**/dim0; \ + old_v = hs->hs_ref_/**/name/**/dim1; \ + new_u = old_u * cos_a + old_v * sin_a; \ + new_v = old_v * cos_a - old_u * sin_a; \ + hs->hs_ref_/**/name/**/dim0 = new_u; \ + hs->hs_ref_/**/name/**/dim1 = new_v; + +#define rotates(dim0,dim1) \ + if (hs->hs_sin_/**/dim0/**/dim1 != 0) { \ + cos_a = hs->hs_cos_/**/dim0/**/dim1; \ + sin_a = hs->hs_sin_/**/dim0/**/dim1; \ + rotate(a,dim0,dim1); \ + rotate(b,dim0,dim1); \ + rotate(c,dim0,dim1); \ + rotate(d,dim0,dim1); \ + } + +#endif /* !__STDC__ */ + + rotates (x,y); + rotates (x,z); + rotates (y,z); + rotates (x,w); + rotates (y,w); + rotates (z,w); + } + + skip3: + /* stop = hs->hs_stop; */ + delay = hs->hs_delay; + if (stop && this_delay < 10000) + this_delay = 10000; + } + return this_delay; +} + + +static Bool +hypercube_event (Display *dpy, Window window, void *closure, XEvent *e) +{ + struct hyper_state *hs = (struct hyper_state *) closure; + if (e->type == ButtonPress && e->xbutton.button == 2) + { + hs->hs_stop = !hs->hs_stop; + return True; } + return False; +} - hyper (xy, xz, yz, xw, yw, zw); +static void +hypercube_reshape (Display *dpy, Window window, void *closure, + unsigned int w, unsigned int h) +{ + struct hyper_state *hs = (struct hyper_state *) closure; + set_sizes (hs, w, h); + XClearWindow (dpy, window); } + + +static void +set_sizes (struct hyper_state *hs, int width, int height) +{ + double observer_z; + int min_dim; + double var; + double offset_x; + double offset_y; + double unit_scale; + + observer_z = 0.5 * hs->hs_two_observer_z; + min_dim = width < height ? width : height; + var = sqrt(observer_z * observer_z - 1.0); + offset_x = 0.5 * (double)(width - 1); + offset_y = 0.5 * (double)(height - 1); + unit_scale = 0.4 * min_dim * var; + hs->hs_offset_x = (float)offset_x; + hs->hs_offset_y = (float)offset_y; + hs->hs_unit_scale = (float)unit_scale; +} + + +/* data */ + +static const struct line_info line_table[LINE_COUNT] = +{ + { 0, 1, 0, }, + { 0, 2, 0, }, + { 1, 3, 0, }, + { 2, 3, 0, }, + { 4, 5, 1, }, + { 4, 6, 1, }, + { 5, 7, 1, }, + { 6, 7, 1, }, + { 0, 4, 4, }, + { 0, 8, 4, }, + { 4, 12, 4, }, + { 8, 12, 4, }, + { 1, 5, 5, }, + { 1, 9, 5, }, + { 5, 13, 5, }, + { 9, 13, 5, }, + { 2, 6, 6, }, + { 2, 10, 6, }, + { 6, 14, 6, }, + { 10, 14, 6, }, + { 3, 7, 7, }, + { 3, 11, 7, }, + { 7, 15, 7, }, + { 11, 15, 7, }, + { 8, 9, 2, }, + { 8, 10, 2, }, + { 9, 11, 2, }, + { 10, 11, 2, }, + { 12, 13, 3, }, + { 12, 14, 3, }, + { 13, 15, 3, }, + { 14, 15, 3, }, +}; + +static void +hypercube_free (Display *dpy, Window window, void *closure) +{ +} + +XSCREENSAVER_MODULE ("HyperCube", hypercube)