[ClutterBehaviourRotate] Fix up some breakage from the cogl-float branch merge
authorNeil Roberts <neil@linux.intel.com>
Wed, 18 Feb 2009 17:57:17 +0000 (17:57 +0000)
committerNeil Roberts <neil@linux.intel.com>
Wed, 18 Feb 2009 18:30:58 +0000 (18:30 +0000)
The rotation angle calculated in clutter_behaviour_rotate_alpha_notify
gets applied to each actor using clutter_behaviour_actors_foreach. The
angle is a ClutterFixed value. Before the cogl float branch merge it
was stuffed into a gpointer using GPOINTER_TO_UINT. The pointer was
then converted back to a uint and cast to a ClutterFixed which worked
out fine even for negative numbers.

After the cogl-float merge the angle is effectively a gfloat. This
gets cast to a uint and stored in a pointer and converted back to a
float via a uint at the other end. However this fails for negative
numbers because a uint -> float conversion can't take advantage of
overflow to preserve the sign so you end up with a large number.

It also had the side effect that it only rotated in whole degrees.

This commit fixes the problem by just passing the ClutterFixed value
inside a closure struct instead of trying to stuff it into a pointer.

clutter/clutter-behaviour-rotate.c

index 8fbd2c6..a840ae4 100644 (file)
@@ -83,12 +83,16 @@ enum
   PROP_CENTER_Z
 };
 
+typedef struct {
+  ClutterFixed angle;
+} RotateFrameClosure;
+
 static void
 alpha_notify_foreach (ClutterBehaviour *behaviour,
                      ClutterActor     *actor,
                      gpointer          data)
 {
-  ClutterFixed angle = GPOINTER_TO_UINT (data);
+  RotateFrameClosure *closure = data;
   ClutterBehaviourRotate *rotate_behaviour;
   ClutterBehaviourRotatePrivate *priv;
 
@@ -96,7 +100,7 @@ alpha_notify_foreach (ClutterBehaviour *behaviour,
   priv = rotate_behaviour->priv;
 
   clutter_actor_set_rotation (actor, priv->axis,
-                              CLUTTER_FIXED_TO_DOUBLE (angle),
+                              CLUTTER_FIXED_TO_DOUBLE (closure->angle),
                               priv->center_x,
                               priv->center_y,
                               priv->center_z);
@@ -119,17 +123,18 @@ static void
 clutter_behaviour_rotate_alpha_notify (ClutterBehaviour *behaviour,
                                        gdouble           alpha_value)
 {
-  ClutterFixed factor, angle, start, end;
+  ClutterFixed factor, start, end;
   ClutterBehaviourRotate *rotate_behaviour;
   ClutterBehaviourRotatePrivate *priv;
+  RotateFrameClosure closure;
 
   rotate_behaviour = CLUTTER_BEHAVIOUR_ROTATE (behaviour);
   priv = rotate_behaviour->priv;
 
-  factor = CLUTTER_FLOAT_TO_FIXED (alpha_value);
-  angle  = 0;
-  start  = priv->angle_start;
-  end    = priv->angle_end;
+  factor        = CLUTTER_FLOAT_TO_FIXED (alpha_value);
+  closure.angle = 0;
+  start         = priv->angle_start;
+  end           = priv->angle_end;
 
   if (priv->direction == CLUTTER_ROTATE_CW && start >= end)
     {
@@ -140,12 +145,11 @@ clutter_behaviour_rotate_alpha_notify (ClutterBehaviour *behaviour,
       end -= 360.0;
     }
 
-  angle = CLUTTER_FIXED_MUL ((end - start), alpha_value)
-        + start;
+  closure.angle = CLUTTER_FIXED_MUL (end - start, alpha_value) + start;
 
   clutter_behaviour_actors_foreach (behaviour,
                                    alpha_notify_foreach,
-                                   GUINT_TO_POINTER ((guint)angle));
+                                   &closure);
 }
 
 static void