draw_fps_string (b_state *state)
{
XFillRectangle (state->dpy, state->b, state->erase_gc,
- 0, state->xgwa.height - state->font_height,
- state->xgwa.width, state->font_height);
+ 0, state->xgwa.height - state->font_height*3 - 20,
+ state->xgwa.width, state->font_height*3 + 20);
XDrawImageString (state->dpy, state->b, state->font_gc,
- 0, state->xgwa.height - state->font_baseline,
+ 10, state->xgwa.height - state->font_height*2 -
+ state->font_baseline - 10,
state->fps_str, strlen(state->fps_str));
}
state->xmin = wx;
state->ymin = wy;
state->xmax = state->xmin + state->xgwa.width;
- state->ymax = state->ymin + state->xgwa.height - state->font_height;
+ state->ymax = state->ymin + state->xgwa.height - (state->font_height*3) -
+ (state->font_height ? 22 : 0);
if (state->dbuf && (state->ba))
{
XClearWindow (state->dpy, state->window);
else if (state->fps_p && oymax != state->ymax)
XFillRectangle (state->dpy, state->b, state->erase_gc,
- 0, state->xgwa.height - state->font_height,
- state->xgwa.width, state->font_height);
+ 0, state->xgwa.height - state->font_height*3,
+ state->xgwa.width, state->font_height*3);
}
}
state->shake_p = get_boolean_resource (dpy, "shake", "Shake");
state->shake_threshold = get_float_resource (dpy, "shakeThreshold",
"ShakeThreshold");
+ state->time_tick = 999999;
+
+# ifdef USE_IPHONE /* Always obey real-world gravity */
+ state->shake_p = False;
+# endif
+
state->fps_p = get_boolean_resource (dpy, "doFPS", "DoFPS");
if (state->fps_p)
{
XFontStruct *font;
- char *fontname = get_string_resource (dpy, "font", "Font");
- const char *def_font = "fixed";
- if (!fontname || !*fontname) fontname = (char *)def_font;
+ char *fontname = get_string_resource (dpy, "fpsFont", "Font");
+ if (!fontname) fontname = "-*-courier-bold-r-normal-*-180-*";
font = XLoadQueryFont (dpy, fontname);
- if (!font) font = XLoadQueryFont (dpy, def_font);
+ if (!font) font = XLoadQueryFont (dpy, "fixed");
if (!font) exit(-1);
gcv.font = font->fid;
gcv.foreground = get_pixel_resource(state->dpy, state->xgwa.colormap,
state->time_since_shake += (now.tv_sec - state->last_time.tv_sec);
+# ifdef USE_IPHONE /* Always obey real-world gravity */
+ {
+ float a = fabs (fabs(state->accx) > fabs(state->accy)
+ ? state->accx : state->accy);
+ switch ((int) current_device_rotation ()) {
+ case 0: case 360: state->accx = 0; state->accy = a; break;
+ case -90: state->accx = -a; state->accy = 0; break;
+ case 90: state->accx = a; state->accy = 0; break;
+ case 180: case -180: state->accx = 0; state->accy = -a; break;
+ default: break;
+ }
+ }
+# endif /* USE_IPHONE */
+
if (state->fps_p)
{
float elapsed = ((now.tv_sec + (now.tv_usec / 1000000.0)) -
float fps = state->frame_count / elapsed;
float cps = state->collision_count / elapsed;
- sprintf (state->fps_str,
- " FPS: %.2f Collisions: %.3f/frame Max motion: %.3f",
- fps, cps/fps, max_d);
+ sprintf (state->fps_str, "Collisions: %.3f/frame Max motion: %.3f",
+ cps/fps, max_d);
draw_fps_string(state);
}
return True;
}
else
- for (i=1; i <= state->count; i++)
- {
- float d = ((state->px[i] - rx) * (state->px[i] - rx) +
- (state->py[i] - ry) * (state->py[i] - ry));
- float r = state->r[i];
- if (d < r*r)
+ {
+ /* When trying to pick up a ball, first look for a click directly
+ inside the ball; but if we don't find it, expand the radius
+ outward until we find something nearby.
+ */
+ float max = state->max_radius * 4;
+ float step = max / 10;
+ float r2;
+ for (r2 = step; r2 < max; r2 += step) {
+ for (i = 1; i <= state->count; i++)
{
- state->mouse_ball = i;
- return True;
+ float d = ((state->px[i] - rx) * (state->px[i] - rx) +
+ (state->py[i] - ry) * (state->py[i] - ry));
+ float r = state->r[i];
+ if (r2 > r) r = r2;
+ if (d < r*r)
+ {
+ state->mouse_ball = i;
+ return True;
+ }
}
}
+ }
return True;
}
else if (event->xany.type == ButtonRelease) /* drop the ball */
static const char *fluidballs_defaults [] = {
".background: black",
".foreground: yellow",
- ".textColor: yellow",
+ ".textColor: white",
"*mouseForeground: white",
- ".font: -*-helvetica-*-r-*-*-*-180-*-*-p-*-*-*",
"*delay: 10000",
"*count: 300",
"*size: 25",
"*wind: 0.00",
"*elasticity: 0.97",
"*timeScale: 1.0",
- "*doFPS: False",
"*shake: True",
"*shakeThreshold: 0.015",
"*doubleBuffer: True",
"*useDBE: True",
"*useDBEClear: True",
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
+#ifdef USE_IPHONE
+ "*ignoreRotation: True",
+#endif
0
};
{ "-gravity", ".gravity", XrmoptionSepArg, 0 },
{ "-wind", ".wind", XrmoptionSepArg, 0 },
{ "-elasticity", ".elasticity", XrmoptionSepArg, 0 },
- { "-fps", ".doFPS", XrmoptionNoArg, "True" },
- { "-no-fps", ".doFPS", XrmoptionNoArg, "False" },
{ "-shake", ".shake", XrmoptionNoArg, "True" },
{ "-no-shake", ".shake", XrmoptionNoArg, "False" },
{ "-random", ".random", XrmoptionNoArg, "True" },
};
-XSCREENSAVER_MODULE ("Fluidballs", fluidballs)
+XSCREENSAVER_MODULE ("FluidBalls", fluidballs)