diff options
Diffstat (limited to 'hacks/hypercube.c')
-rw-r--r-- | hacks/hypercube.c | 575 |
1 files changed, 0 insertions, 575 deletions
diff --git a/hacks/hypercube.c b/hacks/hypercube.c deleted file mode 100644 index fe9e177..0000000 --- a/hacks/hypercube.c +++ /dev/null @@ -1,575 +0,0 @@ -/* xscreensaver, Copyright (c) 1992-2008 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. - * - * This code derived from TI Explorer Lisp code by Joe Keane, Fritz Mueller, - * and Jamie Zawinski. - */ - -#include <math.h> -#include "screenhack.h" - -#define POINT_COUNT 16 -#define LINE_COUNT 32 - -#define ANGLE_SCALE 0.001 - -struct line_info -{ - char li_ip; - char li_iq; - char li_color; - char li_pad; -}; - -struct point_state -{ - short old_x, old_y; - short new_x, new_y; -}; - -struct hyper_state -{ - 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; -}; - -static const struct line_info line_table[LINE_COUNT]; - -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", - "*color7: #00FFD0", - "*color5: #8080FF", - "*color6: #00D0FF", - - 0 -}; - -static XrmOptionDescRec hypercube_options [] = -{ - { "-color0", ".color0", XrmoptionSepArg, 0 }, - { "-color1", ".color1", XrmoptionSepArg, 0 }, - { "-color2", ".color2", XrmoptionSepArg, 0 }, - { "-color3", ".color3", XrmoptionSepArg, 0 }, - { "-color4", ".color4", XrmoptionSepArg, 0 }, - { "-color5", ".color5", XrmoptionSepArg, 0 }, - { "-color6", ".color6", XrmoptionSepArg, 0 }, - { "-color7", ".color7", XrmoptionSepArg, 0 }, - - { "-xw", ".xw", XrmoptionSepArg, 0 }, - { "-xy", ".xy", XrmoptionSepArg, 0 }, - { "-xz", ".xz", XrmoptionSepArg, 0 }, - { "-yw", ".yw", XrmoptionSepArg, 0 }, - { "-yz", ".yz", XrmoptionSepArg, 0 }, - { "-zw", ".zw", XrmoptionSepArg, 0 }, - - { "-observer-z", ".observer-z", XrmoptionSepArg, 0 }, - { "-delay", ".delay", XrmoptionSepArg, 0 }, - { 0, 0, 0, 0 } -}; - - -static void set_sizes (struct hyper_state *hs, int width, int height); - -static void * -hypercube_init (Display *dpy, Window win) -{ - XGCValues gcv; - Colormap cmap; - unsigned long bg_pixel; - int delay; - float observer_z; - - struct hyper_state *hs = (struct hyper_state *) calloc (1, sizeof(*hs)); - hs->hs_display = dpy; - hs->hs_window = win; - - 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; - - { - XWindowAttributes wa; - XGetWindowAttributes (dpy, win, &wa); - cmap = wa.colormap; - set_sizes (hs, wa.width, wa.height); - } - - delay = get_integer_resource (dpy, "delay", "Integer"); - hs->hs_delay = delay; - - 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_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 - { - 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; - - 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 <luik@isa.de> */ - -#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; */ - 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; -} - -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) -{ - struct hyper_state *hs = (struct hyper_state *) closure; - int i; - XFreeGC (dpy, hs->black_gc); - for (i = 0; i < 8; i++) - if (hs->hs_color_gcs[i]) XFreeGC (dpy, hs->hs_color_gcs[i]); - free (hs); -} - -XSCREENSAVER_MODULE ("HyperCube", hypercube) |