X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fattraction.c;fp=hacks%2Fattraction.c;h=8e3f188f3584f8ac9b9e982c2c8d715a97a67f05;hb=ccbc9f87eb59497b23bd0424ee1ed20ad7c7db54;hp=7844154a8f32c7dbd0c9836e74b546fb4e04a15d;hpb=6edc84f12f15860a71430c45e8392a5e4ef8203c;p=xscreensaver diff --git a/hacks/attraction.c b/hacks/attraction.c index 7844154a..8e3f188f 100644 --- a/hacks/attraction.c +++ b/hacks/attraction.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1992 Jamie Zawinski +/* xscreensaver, Copyright (c) 1992, 1995 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 @@ -11,7 +11,8 @@ /* Simulation of a pair of quasi-gravitational fields, maybe sorta kinda a little like the strong and weak electromagnetic forces. Derived from - a Lispm screensaver by John Pezaris . + a Lispm screensaver by John Pezaris . Mouse control and + viscosity added by "Philip Edward Cutone, III" . John sez: @@ -32,15 +33,20 @@ The 1/r^2, -1/r^2, -10/r^2 thresholds proved not only robust but also interesting -- the orbs never collided and the threshold viscosity fixed the non-conservational problem. + + Philip sez: + > An even normal viscosity (rather than the thresholded version to + > bleed excess energy) is also not interesting. + + unless you make about 200 points.... set the viscosity to about .8 + and drag the mouse through it. it makes a nice wave which travels + through the field. */ -#include "screenhack.h" -#include "spline.h" #include #include -#if __STDC__ -#include /* for M_PI */ -#endif +#include "screenhack.h" +#include "spline.h" struct ball { float x, y; @@ -66,6 +72,11 @@ static int point_stack_size, point_stack_fp, pixel_stack_fp, pixel_stack_size; static unsigned long *pixel_stack; static unsigned int color_shift; +/*flip mods for mouse interaction*/ +static Bool mouse_p; +int mouse_x, mouse_y, mouse_mass, root_x, root_y; +static float viscosity; + static enum object_mode { ball_mode, line_mode, polygon_mode, spline_mode, spline_filled_mode, tail_mode @@ -122,6 +133,13 @@ init_balls (dpy, window) color_shift = get_integer_resource ("colorShift", "Integer"); if (color_shift >= 360) color_shift = 5; + /*flip mods for mouse interaction*/ + mouse_p = get_boolean_resource ("mouse", "Boolean"); + mouse_mass = get_integer_resource ("mouseSize", "Integer"); + mouse_mass = mouse_mass * mouse_mass *10; + + viscosity = get_float_resource ("viscosity", "Float"); + mode_str = get_string_resource ("mode", "Mode"); if (! mode_str) mode = ball_mode; else if (!strcmp (mode_str, "balls")) mode = ball_mode; @@ -272,6 +290,7 @@ compute_force (i, dx_ret, dy_ret) float *dx_ret, *dy_ret; { int j; + float x_dist, y_dist, dist, dist2; *dx_ret = 0; *dy_ret = 0; for (j = 0; j < npoints; j++) @@ -298,6 +317,28 @@ compute_force (i, dx_ret, dy_ret) *dy_ret += (frand (10.0) - 5.0); } } + + if (mouse_p) + { + x_dist = mouse_x - balls [i].x; + y_dist = mouse_y - balls [i].y; + dist2 = (x_dist * x_dist) + (y_dist * y_dist); + dist = sqrt (dist2); + + if (dist > 0.1) /* the balls are not overlapping */ + { + float new_acc = ((mouse_mass / dist2) * + ((dist < threshold) ? -1.0 : 1.0)); + float new_acc_dist = new_acc / dist; + *dx_ret += new_acc_dist * x_dist; + *dy_ret += new_acc_dist * y_dist; + } + else + { /* the balls are overlapping; move randomly */ + *dx_ret += (frand (10.0) - 5.0); + *dy_ret += (frand (10.0) - 5.0); + } + } } static void @@ -310,6 +351,15 @@ run_balls (dpy, window) static Colormap cmap; int i; + /*flip mods for mouse interaction*/ + Window root1, child1; + int mask; + if (mouse_p) + { + XQueryPointer(dpy, window, &root1, &child1, + &root_x, &root_y, &mouse_x, &mouse_y, &mask); + } + if (tick++ == 500) { XWindowAttributes xgwa; @@ -341,11 +391,20 @@ run_balls (dpy, window) balls[i].vx *= 0.9; balls[i].dx = 0; } + else if (viscosity != 1) + { + balls[i].vx *= viscosity; + } + if (balls[i].vy > 10) { balls[i].vy *= 0.9; balls[i].dy = 0; } + else if (viscosity != 1) + { + balls[i].vy *= viscosity; + } balls[i].x += balls[i].vx; balls[i].y += balls[i].vy; @@ -435,7 +494,7 @@ run_balls (dpy, window) abort (); if (!mono_p) { - XColor color2; + XColor color2, desired; color2 = balls [0].color; switch (cmode) { @@ -451,7 +510,18 @@ run_balls (dpy, window) abort (); } - if (!XAllocColor (dpy, cmap, &color2)) + desired = color2; + if (XAllocColor (dpy, cmap, &color2)) + { + /* XAllocColor returns the actual RGB that the hardware let us + allocate. Restore the requested values into the XColor struct + so that limited-resolution hardware doesn't cause cycle_hue to + get "stuck". */ + color2.red = desired.red; + color2.green = desired.green; + color2.blue = desired.blue; + } + else { color2 = balls [0].color; if (!XAllocColor (dpy, cmap, &balls [0].color)) @@ -569,6 +639,9 @@ char *defaults [] = { "*threshold: 100", "*delay: 10000", "*glow: false", + "*mouseSize: 10", + "*mouse: false", + "*viscosity: 1", "*orbit: false", "*colorShift: 3", "*segments: 100", @@ -588,6 +661,10 @@ XrmOptionDescRec options [] = { { "-vx", ".vx", XrmoptionSepArg, 0 }, { "-vy", ".vy", XrmoptionSepArg, 0 }, { "-vmult", ".vMult", XrmoptionSepArg, 0 }, + { "-mouse-size", ".mouseSize", XrmoptionSepArg, 0 }, + { "-mouse", ".mouse", XrmoptionNoArg, "true" }, + { "-nomouse", ".mouse", XrmoptionNoArg, "false" }, + { "-viscosity", ".viscosity", XrmoptionSepArg, 0 }, { "-glow", ".glow", XrmoptionNoArg, "true" }, { "-noglow", ".glow", XrmoptionNoArg, "false" }, { "-orbit", ".orbit", XrmoptionNoArg, "true" }