~elementary-os/elementaryos/os-patch-notify-osd-precise

« back to all changes in this revision

Viewing changes to egg/egg-alpha.c

  • Committer: Sergey "Shnatsel" Davidoff
  • Date: 2012-06-18 21:08:31 UTC
  • Revision ID: shnatsel@gmail.com-20120618210831-g6k5y7vecjdylgic
Initial import, version 0.9.34-0ubuntu2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Clutter.
 
3
 *
 
4
 * An OpenGL based 'interactive canvas' library.
 
5
 *
 
6
 * Authored By Matthew Allum  <mallum@openedhand.com>
 
7
 *             Jorn Baayen  <jorn@openedhand.com>
 
8
 *             Emmanuele Bassi  <ebassi@openedhand.com>
 
9
 *             Tomas Frydrych <tf@openedhand.com>
 
10
 *
 
11
 * Copyright (C) 2006, 2007 OpenedHand
 
12
 *
 
13
 * This library is free software; you can redistribute it and/or
 
14
 * modify it under the terms of the GNU Lesser General Public
 
15
 * License as published by the Free Software Foundation; either
 
16
 * version 2 of the License, or (at your option) any later version.
 
17
 *
 
18
 * This library is distributed in the hope that it will be useful,
 
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
21
 * Lesser General Public License for more details.
 
22
 *
 
23
 * You should have received a copy of the GNU Lesser General Public
 
24
 * License along with this library; if not, write to the
 
25
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
26
 * Boston, MA 02111-1307, USA.
 
27
 */
 
28
 
 
29
/**
 
30
 * SECTION:egg-alpha
 
31
 * @short_description: A class for calculating an alpha value as a function
 
32
 * of time.
 
33
 *
 
34
 * #EggAlpha is a class for calculating an integer value between
 
35
 * 0 and %EGG_ALPHA_MAX_ALPHA as a function of time.  You should
 
36
 * provide a #EggTimeline and bind it to the #EggAlpha object;
 
37
 * you should also provide a function returning the alpha value depending
 
38
 * on the position inside the timeline; this function will be executed
 
39
 * each time a new frame in the #EggTimeline is reached.  Since the
 
40
 * alpha function is controlled by the timeline instance, you can pause
 
41
 * or stop the #EggAlpha from calling the alpha function by controlling
 
42
 * the #EggTimeline object.
 
43
 *
 
44
 * #EggAlpha is used to "drive" a #EggBehaviour instance.
 
45
 *
 
46
 * <figure id="alpha-functions">
 
47
 *   <title>Graphic representation of some alpha functions</title>
 
48
 *   <graphic fileref="alpha-func.png" format="PNG"/>
 
49
 * </figure>
 
50
 *
 
51
 * Since: 0.2
 
52
 */
 
53
 
 
54
#ifdef HAVE_CONFIG_H
 
55
#include "config.h"
 
56
#endif
 
57
 
 
58
#include <math.h>
 
59
 
 
60
#include "egg-alpha.h"
 
61
#include "egg-hack.h"
 
62
// #include "egg-marshal.h"
 
63
// #include "egg-private.h"
 
64
#include "egg-debug.h"
 
65
 
 
66
G_DEFINE_TYPE (EggAlpha, egg_alpha, G_TYPE_INITIALLY_UNOWNED);
 
67
 
 
68
 
 
69
struct _EggAlphaPrivate
 
70
{
 
71
  EggTimeline *timeline;
 
72
  guint timeline_new_frame_id;
 
73
 
 
74
  guint32 alpha;
 
75
 
 
76
  GClosure *closure;
 
77
};
 
78
 
 
79
enum
 
80
{
 
81
  PROP_0,
 
82
  
 
83
  PROP_TIMELINE,
 
84
  PROP_ALPHA
 
85
};
 
86
 
 
87
static void
 
88
timeline_new_frame_cb (EggTimeline *timeline,
 
89
                       guint            current_frame_num,
 
90
                       EggAlpha    *alpha)
 
91
{
 
92
  EggAlphaPrivate *priv = alpha->priv;
 
93
 
 
94
  /* Update alpha value and notify */
 
95
  priv->alpha = egg_alpha_get_alpha (alpha);
 
96
  g_object_notify (G_OBJECT (alpha), "alpha");
 
97
}
 
98
 
 
99
static void 
 
100
egg_alpha_set_property (GObject      *object, 
 
101
                            guint         prop_id,
 
102
                            const GValue *value, 
 
103
                            GParamSpec   *pspec)
 
104
{
 
105
  EggAlpha *alpha;
 
106
 
 
107
  alpha = EGG_ALPHA (object);
 
108
 
 
109
  switch (prop_id) 
 
110
    {
 
111
    case PROP_TIMELINE:
 
112
      egg_alpha_set_timeline (alpha, g_value_get_object (value));
 
113
      break;
 
114
    default:
 
115
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
116
      break;
 
117
  }
 
118
}
 
119
 
 
120
static void 
 
121
egg_alpha_get_property (GObject    *object, 
 
122
                            guint       prop_id,
 
123
                            GValue     *value, 
 
124
                            GParamSpec *pspec)
 
125
{
 
126
  EggAlpha        *alpha;
 
127
  EggAlphaPrivate *priv;
 
128
 
 
129
  alpha = EGG_ALPHA (object);
 
130
  priv = alpha->priv;
 
131
 
 
132
  switch (prop_id) 
 
133
    {
 
134
    case PROP_TIMELINE:
 
135
      g_value_set_object (value, priv->timeline);
 
136
      break;
 
137
    case PROP_ALPHA:
 
138
      g_value_set_uint (value, priv->alpha);
 
139
      break;
 
140
    default:
 
141
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
142
      break;
 
143
    }
 
144
}
 
145
 
 
146
static void 
 
147
egg_alpha_finalize (GObject *object)
 
148
{
 
149
  EggAlphaPrivate *priv = EGG_ALPHA (object)->priv;
 
150
 
 
151
  if (priv->closure)
 
152
    g_closure_unref (priv->closure);
 
153
 
 
154
  G_OBJECT_CLASS (egg_alpha_parent_class)->finalize (object);
 
155
}
 
156
 
 
157
static void 
 
158
egg_alpha_dispose (GObject *object)
 
159
{
 
160
  EggAlpha *self = EGG_ALPHA(object);
 
161
 
 
162
  egg_alpha_set_timeline (self, NULL);
 
163
 
 
164
  G_OBJECT_CLASS (egg_alpha_parent_class)->dispose (object);
 
165
}
 
166
 
 
167
 
 
168
static void
 
169
egg_alpha_class_init (EggAlphaClass *klass)
 
170
{
 
171
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
172
 
 
173
  object_class->set_property = egg_alpha_set_property;
 
174
  object_class->get_property = egg_alpha_get_property;
 
175
  object_class->finalize     = egg_alpha_finalize;
 
176
  object_class->dispose      = egg_alpha_dispose;
 
177
 
 
178
  g_type_class_add_private (klass, sizeof (EggAlphaPrivate));
 
179
 
 
180
  /**
 
181
   * EggAlpha:timeline:
 
182
   *
 
183
   * A #EggTimeline instance used to drive the alpha function.
 
184
   *
 
185
   * Since: 0.2
 
186
   */
 
187
  g_object_class_install_property (object_class,
 
188
                                   PROP_TIMELINE,
 
189
                                   g_param_spec_object ("timeline",
 
190
                                                        "Timeline",
 
191
                                                        "Timeline",
 
192
                                                        EGG_TYPE_TIMELINE,
 
193
                                                        EGG_PARAM_READWRITE));
 
194
  /**
 
195
   * EggAlpha:alpha:
 
196
   *
 
197
   * The alpha value as computed by the alpha function.
 
198
   *
 
199
   * Since: 0.2
 
200
   */
 
201
  g_object_class_install_property (object_class,
 
202
                                   PROP_ALPHA,
 
203
                                   g_param_spec_uint ("alpha",
 
204
                                                      "Alpha value",
 
205
                                                      "Alpha value",
 
206
                                                      0, 
 
207
                                                      EGG_ALPHA_MAX_ALPHA,
 
208
                                                      0,
 
209
                                                      EGG_PARAM_READABLE));
 
210
}
 
211
 
 
212
static void
 
213
egg_alpha_init (EggAlpha *self)
 
214
{
 
215
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
 
216
                                            EGG_TYPE_ALPHA,
 
217
                                            EggAlphaPrivate);
 
218
}
 
219
 
 
220
/**
 
221
 * egg_alpha_get_alpha:
 
222
 * @alpha: A #EggAlpha
 
223
 *
 
224
 * Query the current alpha value.
 
225
 *
 
226
 * Return Value: The current alpha value for the alpha
 
227
 *
 
228
 * Since: 0.2
 
229
 */
 
230
guint32
 
231
egg_alpha_get_alpha (EggAlpha *alpha)
 
232
{
 
233
  EggAlphaPrivate *priv;
 
234
  guint32 retval = 0;
 
235
 
 
236
  g_return_val_if_fail (EGG_IS_ALPHA (alpha), 0);
 
237
 
 
238
  priv = alpha->priv;
 
239
 
 
240
  if (G_LIKELY (priv->closure))
 
241
    {
 
242
      GValue params = { 0, };
 
243
      GValue result_value = { 0, };
 
244
 
 
245
      g_object_ref (alpha);
 
246
 
 
247
      g_value_init (&result_value, G_TYPE_UINT);
 
248
 
 
249
      g_value_init (&params, EGG_TYPE_ALPHA);
 
250
      g_value_set_object (&params, alpha);
 
251
                     
 
252
      g_closure_invoke (priv->closure,
 
253
                        &result_value,
 
254
                        1,
 
255
                        &params,
 
256
                        NULL);
 
257
 
 
258
      retval = g_value_get_uint (&result_value);
 
259
 
 
260
      g_value_unset (&result_value);
 
261
      g_value_unset (&params);
 
262
 
 
263
      g_object_unref (alpha);
 
264
    }
 
265
 
 
266
  return retval;
 
267
}
 
268
 
 
269
/**
 
270
 * egg_alpha_set_closure:
 
271
 * @alpha: A #EggAlpha
 
272
 * @closure: A #GClosure
 
273
 *
 
274
 * Sets the #GClosure used to compute
 
275
 * the alpha value at each frame of the #EggTimeline
 
276
 * bound to @alpha.
 
277
 *
 
278
 * Since: 0.8
 
279
 */
 
280
void
 
281
egg_alpha_set_closure (EggAlpha *alpha,
 
282
                           GClosure     *closure)
 
283
{
 
284
  EggAlphaPrivate *priv;
 
285
 
 
286
  g_return_if_fail (EGG_IS_ALPHA (alpha));
 
287
  g_return_if_fail (closure != NULL);
 
288
 
 
289
  priv = alpha->priv;
 
290
 
 
291
  if (priv->closure)
 
292
    g_closure_unref (priv->closure);
 
293
 
 
294
  priv->closure = g_closure_ref (closure);
 
295
  g_closure_sink (closure);
 
296
 
 
297
  if (G_CLOSURE_NEEDS_MARSHAL (closure))
 
298
    {
 
299
      GClosureMarshal marshal = egg_marshal_UINT__VOID;
 
300
 
 
301
      g_closure_set_marshal (closure, marshal);
 
302
    }
 
303
}
 
304
 
 
305
/**
 
306
 * egg_alpha_set_func:
 
307
 * @alpha: A #EggAlpha
 
308
 * @func: A #EggAlphaAlphaFunc
 
309
 * @data: user data to be passed to the alpha function, or %NULL
 
310
 * @destroy: notify function used when disposing the alpha function
 
311
 *
 
312
 * Sets the #EggAlphaFunc function used to compute
 
313
 * the alpha value at each frame of the #EggTimeline
 
314
 * bound to @alpha.
 
315
 *
 
316
 * Since: 0.2
 
317
 */
 
318
void
 
319
egg_alpha_set_func (EggAlpha    *alpha,
 
320
                        EggAlphaFunc func,
 
321
                        gpointer         data,
 
322
                        GDestroyNotify   destroy)
 
323
{
 
324
  GClosure *closure;
 
325
 
 
326
  g_return_if_fail (EGG_IS_ALPHA (alpha));
 
327
  g_return_if_fail (func != NULL);
 
328
  
 
329
  closure = g_cclosure_new (G_CALLBACK (func), data, (GClosureNotify) destroy);
 
330
  egg_alpha_set_closure (alpha, closure);
 
331
}
 
332
 
 
333
/**
 
334
 * egg_alpha_set_timeline:
 
335
 * @alpha: A #EggAlpha
 
336
 * @timeline: A #EggTimeline
 
337
 *
 
338
 * Binds @alpha to @timeline.
 
339
 *
 
340
 * Since: 0.2
 
341
 */
 
342
void
 
343
egg_alpha_set_timeline (EggAlpha    *alpha,
 
344
                            EggTimeline *timeline)
 
345
{
 
346
  EggAlphaPrivate *priv;
 
347
 
 
348
  g_return_if_fail (EGG_IS_ALPHA (alpha));
 
349
  g_return_if_fail (timeline == NULL || EGG_IS_TIMELINE (timeline));
 
350
  
 
351
  priv = alpha->priv;
 
352
 
 
353
  if (priv->timeline)
 
354
    {
 
355
      g_signal_handlers_disconnect_by_func (priv->timeline,
 
356
                                            timeline_new_frame_cb,
 
357
                                            alpha);
 
358
 
 
359
      g_object_unref (priv->timeline);
 
360
      priv->timeline = NULL;
 
361
    }
 
362
 
 
363
  if (timeline)
 
364
    {
 
365
      priv->timeline = g_object_ref (timeline);
 
366
 
 
367
      g_signal_connect (priv->timeline, "new-frame",
 
368
                        G_CALLBACK (timeline_new_frame_cb),
 
369
                        alpha);
 
370
    }
 
371
}
 
372
 
 
373
/**
 
374
 * egg_alpha_get_timeline:
 
375
 * @alpha: A #EggAlpha
 
376
 *
 
377
 * Gets the #EggTimeline bound to @alpha.
 
378
 *
 
379
 * Return value: a #EggTimeline instance
 
380
 *
 
381
 * Since: 0.2
 
382
 */
 
383
EggTimeline *
 
384
egg_alpha_get_timeline (EggAlpha *alpha)
 
385
{
 
386
  g_return_val_if_fail (EGG_IS_ALPHA (alpha), NULL);
 
387
 
 
388
  return alpha->priv->timeline;
 
389
}
 
390
 
 
391
/**
 
392
 * egg_alpha_new:
 
393
 * 
 
394
 * Creates a new #EggAlpha instance.  You must set a function
 
395
 * to compute the alpha value using egg_alpha_set_func() and
 
396
 * bind a #EggTimeline object to the #EggAlpha instance
 
397
 * using egg_alpha_set_timeline().
 
398
 *
 
399
 * You should use the newly created #EggAlpha instance inside
 
400
 * a #EggBehaviour object.
 
401
 *
 
402
 * Return value: the newly created empty #EggAlpha instance.
 
403
 *
 
404
 * Since: 0.2
 
405
 */
 
406
EggAlpha *
 
407
egg_alpha_new (void)
 
408
{
 
409
  return g_object_new (EGG_TYPE_ALPHA, NULL);
 
410
}
 
411
 
 
412
/**
 
413
 * egg_alpha_new_full:
 
414
 * @timeline: #EggTimeline timeline
 
415
 * @func: #EggAlphaFunc alpha function
 
416
 * @data: data to be passed to the alpha function
 
417
 * @destroy: notify to be called when removing the alpha function
 
418
 *
 
419
 * Creates a new #EggAlpha instance and sets the timeline
 
420
 * and alpha function.
 
421
 *
 
422
 * Return Value: the newly created #EggAlpha
 
423
 *
 
424
 * Since: 0.2
 
425
 */
 
426
EggAlpha *
 
427
egg_alpha_new_full (EggTimeline  *timeline,
 
428
                        EggAlphaFunc  func,
 
429
                        gpointer          data,
 
430
                        GDestroyNotify    destroy)
 
431
{
 
432
  EggAlpha *retval;
 
433
 
 
434
  g_return_val_if_fail (EGG_IS_TIMELINE (timeline), NULL);
 
435
  g_return_val_if_fail (func != NULL, NULL);
 
436
 
 
437
  retval = egg_alpha_new ();
 
438
 
 
439
  egg_alpha_set_timeline (retval, timeline);
 
440
  egg_alpha_set_func (retval, func, data, destroy);
 
441
 
 
442
  return retval;
 
443
}
 
444
 
 
445
/**
 
446
 * EGG_ALPHA_RAMP_INC:
 
447
 *
 
448
 * Convenience symbol for egg_ramp_inc_func().
 
449
 *
 
450
 * Since: 0.2
 
451
 */
 
452
 
 
453
/**
 
454
 * egg_ramp_inc_func:
 
455
 * @alpha: a #EggAlpha
 
456
 * @dummy: unused argument
 
457
 *
 
458
 * Convenience alpha function for a monotonic increasing ramp. You
 
459
 * can use this function as the alpha function for egg_alpha_set_func().
 
460
 *
 
461
 * Return value: an alpha value.
 
462
 *
 
463
 * Since: 0.2
 
464
 */
 
465
guint32
 
466
egg_ramp_inc_func (EggAlpha *alpha,
 
467
                       gpointer      dummy)
 
468
{
 
469
  EggTimeline *timeline;
 
470
  gint current_frame_num, n_frames;
 
471
 
 
472
  timeline = egg_alpha_get_timeline (alpha);
 
473
 
 
474
  current_frame_num = egg_timeline_get_current_frame (timeline);
 
475
  n_frames = egg_timeline_get_n_frames (timeline);
 
476
 
 
477
  return (current_frame_num * EGG_ALPHA_MAX_ALPHA) / n_frames;
 
478
}
 
479
 
 
480
/**
 
481
 * EGG_ALPHA_RAMP_DEC:
 
482
 *
 
483
 * Convenience symbol for egg_ramp_dec_func().
 
484
 *
 
485
 * Since: 0.2
 
486
 */
 
487
 
 
488
/**
 
489
 * egg_ramp_dec_func:
 
490
 * @alpha: a #EggAlpha
 
491
 * @dummy: unused argument
 
492
 *
 
493
 * Convenience alpha function for a monotonic decreasing ramp. You
 
494
 * can use this function as the alpha function for egg_alpha_set_func().
 
495
 *
 
496
 * Return value: an alpha value.
 
497
 *
 
498
 * Since: 0.2
 
499
 */
 
500
guint32
 
501
egg_ramp_dec_func (EggAlpha *alpha,
 
502
                       gpointer      dummy)
 
503
{
 
504
  EggTimeline *timeline;
 
505
  gint current_frame_num, n_frames;
 
506
 
 
507
  timeline = egg_alpha_get_timeline (alpha);
 
508
 
 
509
  current_frame_num = egg_timeline_get_current_frame (timeline);
 
510
  n_frames = egg_timeline_get_n_frames (timeline);
 
511
 
 
512
  return (n_frames - current_frame_num)
 
513
         * EGG_ALPHA_MAX_ALPHA
 
514
         / n_frames;
 
515
}
 
516
 
 
517
/**
 
518
 * EGG_ALPHA_RAMP:
 
519
 *
 
520
 * Convenience symbol for egg_ramp_func().
 
521
 *
 
522
 * Since: 0.2
 
523
 */
 
524
 
 
525
/**
 
526
 * egg_ramp_func:
 
527
 * @alpha: a #EggAlpha
 
528
 * @dummy: unused argument
 
529
 *
 
530
 * Convenience alpha function for a full ramp function (increase for
 
531
 * half the time, decrease for the remaining half). You can use this
 
532
 * function as the alpha function for egg_alpha_set_func().
 
533
 *
 
534
 * Return value: an alpha value.
 
535
 *
 
536
 * Since: 0.2
 
537
 */
 
538
guint32
 
539
egg_ramp_func (EggAlpha *alpha,
 
540
                   gpointer      dummy)
 
541
{
 
542
  EggTimeline *timeline;
 
543
  gint current_frame_num, n_frames;
 
544
 
 
545
  timeline = egg_alpha_get_timeline (alpha);
 
546
 
 
547
  current_frame_num = egg_timeline_get_current_frame (timeline);
 
548
  n_frames = egg_timeline_get_n_frames (timeline);
 
549
 
 
550
  if (current_frame_num > (n_frames / 2))
 
551
    {
 
552
      return (n_frames - current_frame_num)
 
553
             * EGG_ALPHA_MAX_ALPHA
 
554
             / (n_frames / 2);
 
555
    }
 
556
  else
 
557
    {
 
558
      return current_frame_num
 
559
             * EGG_ALPHA_MAX_ALPHA
 
560
             / (n_frames / 2);
 
561
    }
 
562
}
 
563
 
 
564
static guint32
 
565
sincx1024_func (EggAlpha *alpha, 
 
566
                EggAngle  angle,
 
567
                EggFixed  offset)
 
568
{
 
569
  EggTimeline *timeline;
 
570
  gint current_frame_num, n_frames;
 
571
  EggAngle x;
 
572
  unsigned int sine;
 
573
  
 
574
  timeline = egg_alpha_get_timeline (alpha);
 
575
 
 
576
  current_frame_num = egg_timeline_get_current_frame (timeline);
 
577
  n_frames = egg_timeline_get_n_frames (timeline);
 
578
 
 
579
  x = angle * current_frame_num / n_frames;
 
580
 
 
581
  x -= (512 * 512 / angle);
 
582
  
 
583
  sine = ((egg_sini (x) + offset)/2) * EGG_ALPHA_MAX_ALPHA;
 
584
 
 
585
  sine = sine >> CFX_Q;
 
586
  
 
587
  return sine;
 
588
}
 
589
#if 0
 
590
/*
 
591
 * The following two functions are left in place for reference
 
592
 * purposes.
 
593
 */
 
594
static guint32
 
595
sincx_func (EggAlpha *alpha, 
 
596
            EggFixed  angle,
 
597
            EggFixed  offset)
 
598
{
 
599
  EggTimeline *timeline;
 
600
  gint current_frame_num, n_frames;
 
601
  EggFixed x, sine;
 
602
  
 
603
  timeline = egg_alpha_get_timeline (alpha);
 
604
 
 
605
  current_frame_num = egg_timeline_get_current_frame (timeline);
 
606
  n_frames = egg_timeline_get_n_frames (timeline);
 
607
 
 
608
  x = angle * current_frame_num / n_frames;
 
609
  x = EGG_FIXED_MUL (x, CFX_PI) - EGG_FIXED_DIV (CFX_PI, angle);
 
610
 
 
611
  sine = (egg_fixed_sin (x) + offset)/2;
 
612
 
 
613
  EGG_NOTE (ALPHA, "sine: %2f\n", EGG_FIXED_TO_DOUBLE (sine));
 
614
 
 
615
  return EGG_FIXED_TO_INT (sine * EGG_ALPHA_MAX_ALPHA);
 
616
}
 
617
 
 
618
/* NB: angle is not in radians but in muliples of PI, i.e., 2.0
 
619
 * represents full circle.
 
620
 */
 
621
static guint32
 
622
sinc_func (EggAlpha *alpha, 
 
623
           float         angle,
 
624
           float         offset)
 
625
{
 
626
  EggTimeline *timeline;
 
627
  gint current_frame_num, n_frames;
 
628
  gdouble x, sine;
 
629
  
 
630
  timeline = egg_alpha_get_timeline (alpha);
 
631
 
 
632
  current_frame_num = egg_timeline_get_current_frame (timeline);
 
633
  n_frames = egg_timeline_get_n_frames (timeline);
 
634
 
 
635
  /* FIXME: fixed point, and fixed point sine() */
 
636
 
 
637
  x = (gdouble) (current_frame_num * angle * G_PI) / n_frames ;
 
638
  sine = (sin (x - (G_PI / angle)) + offset) * 0.5f;
 
639
 
 
640
  EGG_NOTE (ALPHA, "sine: %2f\n",sine);
 
641
 
 
642
  return EGG_FLOAT_TO_INT ((sine * (gdouble) EGG_ALPHA_MAX_ALPHA));
 
643
}
 
644
#endif
 
645
 
 
646
/**
 
647
 * EGG_ALPHA_SINE:
 
648
 *
 
649
 * Convenience symbol for egg_sine_func().
 
650
 *
 
651
 * Since: 0.2
 
652
 */
 
653
 
 
654
/**
 
655
 * egg_sine_func:
 
656
 * @alpha: a #EggAlpha
 
657
 * @dummy: unused argument
 
658
 *
 
659
 * Convenience alpha function for a sine wave. You can use this
 
660
 * function as the alpha function for egg_alpha_set_func().
 
661
 *
 
662
 * Return value: an alpha value.
 
663
 *
 
664
 * Since: 0.2
 
665
 */
 
666
guint32 
 
667
egg_sine_func (EggAlpha *alpha,
 
668
                   gpointer      dummy)
 
669
{
 
670
#if 0
 
671
    return sinc_func (alpha, 2.0, 1.0);
 
672
#else
 
673
    /* 2.0 above represents full circle */
 
674
    return sincx1024_func (alpha, 1024, CFX_ONE);
 
675
#endif
 
676
}
 
677
 
 
678
/**
 
679
 * EGG_ALPHA_SINE_INC:
 
680
 *
 
681
 * Convenience symbol for egg_sine_inc_func().
 
682
 *
 
683
 * Since: 0.2
 
684
 */
 
685
 
 
686
/**
 
687
 * egg_sine_inc_func:
 
688
 * @alpha: a #EggAlpha
 
689
 * @dummy: unused argument
 
690
 *
 
691
 * Convenience alpha function for a sine wave over interval [0, pi / 2].
 
692
 * You can use this function as the alpha function for
 
693
 * egg_alpha_set_func().
 
694
 *
 
695
 * Return value: an alpha value.
 
696
 *
 
697
 * Since: 0.2
 
698
 */
 
699
guint32 
 
700
egg_sine_inc_func (EggAlpha *alpha,
 
701
                       gpointer      dummy)
 
702
{
 
703
  EggTimeline * timeline;
 
704
  gint              frame;
 
705
  gint              n_frames;
 
706
  EggAngle      x;
 
707
  EggFixed      sine;
 
708
  
 
709
  timeline = egg_alpha_get_timeline (alpha);
 
710
  frame    = egg_timeline_get_current_frame (timeline);
 
711
  n_frames = egg_timeline_get_n_frames (timeline);
 
712
 
 
713
  x = 256 * frame / n_frames;
 
714
 
 
715
  sine = egg_sini (x) * EGG_ALPHA_MAX_ALPHA;
 
716
 
 
717
  return ((guint32)sine) >> CFX_Q;
 
718
}
 
719
 
 
720
/**
 
721
 * EGG_ALPHA_SINE_DEC:
 
722
 *
 
723
 * Convenience symbol for egg_sine_dec_func().
 
724
 *
 
725
 * Since: 0.2
 
726
 */
 
727
 
 
728
/**
 
729
 * egg_sine_dec_func:
 
730
 * @alpha: a #EggAlpha
 
731
 * @dummy: unused argument
 
732
 *
 
733
 * Convenience alpha function for a sine wave over interval [pi / 2, pi].
 
734
 * You can use this function as the alpha function for
 
735
 * egg_alpha_set_func().
 
736
 *
 
737
 * Return value: an alpha value.
 
738
 *
 
739
 * Since: 0.4
 
740
 */
 
741
guint32 
 
742
egg_sine_dec_func (EggAlpha *alpha,
 
743
                       gpointer      dummy)
 
744
{
 
745
  EggTimeline * timeline;
 
746
  gint              frame;
 
747
  gint              n_frames;
 
748
  EggAngle      x;
 
749
  EggFixed      sine;
 
750
  
 
751
  timeline = egg_alpha_get_timeline (alpha);
 
752
  frame    = egg_timeline_get_current_frame (timeline);
 
753
  n_frames = egg_timeline_get_n_frames (timeline);
 
754
 
 
755
  x = 256 * frame / n_frames + 256;
 
756
 
 
757
  sine = egg_sini (x) * EGG_ALPHA_MAX_ALPHA;
 
758
 
 
759
  return ((guint32)sine) >> CFX_Q;
 
760
}
 
761
 
 
762
/**
 
763
 * EGG_ALPHA_SINE_HALF:
 
764
 *
 
765
 * Convenience symbol for egg_sine_half_func().
 
766
 *
 
767
 * Since: 0.4
 
768
 */
 
769
 
 
770
/**
 
771
 * egg_sine_half_func:
 
772
 * @alpha: a #EggAlpha
 
773
 * @dummy: unused argument
 
774
 *
 
775
 * Convenience alpha function for a sine wave over interval [0, pi].
 
776
 * You can use this function as the alpha function for
 
777
 * egg_alpha_set_func().
 
778
 *
 
779
 * Return value: an alpha value.
 
780
 *
 
781
 * Since: 0.4
 
782
 */
 
783
guint32 
 
784
egg_sine_half_func (EggAlpha *alpha,
 
785
                        gpointer      dummy)
 
786
{
 
787
  EggTimeline * timeline;
 
788
  gint              frame;
 
789
  gint              n_frames;
 
790
  EggAngle      x;
 
791
  EggFixed      sine;
 
792
  
 
793
  timeline = egg_alpha_get_timeline (alpha);
 
794
  frame    = egg_timeline_get_current_frame (timeline);
 
795
  n_frames = egg_timeline_get_n_frames (timeline);
 
796
 
 
797
  x = 512 * frame / n_frames;
 
798
 
 
799
  sine = egg_sini (x) * EGG_ALPHA_MAX_ALPHA;
 
800
 
 
801
  return ((guint32)sine) >> CFX_Q;
 
802
}
 
803
 
 
804
/**
 
805
 * EGG_ALPHA_SQUARE:
 
806
 *
 
807
 * Convenience symbol for egg_square_func().
 
808
 *
 
809
 * Since: 0.4
 
810
 */
 
811
 
 
812
/**
 
813
 * egg_square_func:
 
814
 * @alpha: a #EggAlpha
 
815
 * @dummy: unused argument
 
816
 *
 
817
 * Convenience alpha function for a square wave. You can use this
 
818
 * function as the alpha function for egg_alpha_set_func().
 
819
 *
 
820
 * Return value: an alpha value
 
821
 *
 
822
 * Since: 0.4
 
823
 */
 
824
guint32
 
825
egg_square_func (EggAlpha *alpha,
 
826
                     gpointer      dummy)
 
827
{
 
828
  EggTimeline *timeline;
 
829
  gint current_frame_num, n_frames;
 
830
 
 
831
  timeline = egg_alpha_get_timeline (alpha);
 
832
 
 
833
  current_frame_num = egg_timeline_get_current_frame (timeline);
 
834
  n_frames = egg_timeline_get_n_frames (timeline);
 
835
 
 
836
  return (current_frame_num > (n_frames / 2)) ? EGG_ALPHA_MAX_ALPHA
 
837
                                              : 0;
 
838
}
 
839
 
 
840
/**
 
841
 * EGG_ALPHA_SMOOTHSTEP_INC:
 
842
 *
 
843
 * Convenience symbol for egg_smoothstep_inc_func().
 
844
 *
 
845
 * Since: 0.4
 
846
 */
 
847
 
 
848
/**
 
849
 * egg_smoothstep_inc_func:
 
850
 * @alpha: a #EggAlpha
 
851
 * @dummy: unused
 
852
 *
 
853
 * Convenience alpha function for a smoothstep curve. You can use this
 
854
 * function as the alpha function for egg_alpha_set_func().
 
855
 *
 
856
 * Return value: an alpha value
 
857
 *
 
858
 * Since: 0.4
 
859
 */
 
860
guint32
 
861
egg_smoothstep_inc_func (EggAlpha  *alpha,
 
862
                             gpointer       dummy)
 
863
{
 
864
  EggTimeline    *timeline;
 
865
  gint                frame;
 
866
  gint                n_frames;
 
867
  guint32             r; 
 
868
  guint32             x; 
 
869
 
 
870
  /*
 
871
   * The smoothstep function uses f(x) = -2x^3 + 3x^2 where x is from <0,1>,
 
872
   * and precission is critical -- we use 8.24 fixed format for this operation.
 
873
   * The earlier operations involve division, which we cannot do in 8.24 for
 
874
   * numbers in <0,1> we use EggFixed.
 
875
   */
 
876
  timeline = egg_alpha_get_timeline (alpha);
 
877
  frame    = egg_timeline_get_current_frame (timeline);
 
878
  n_frames = egg_timeline_get_n_frames (timeline);
 
879
 
 
880
  /*
 
881
   * Convert x to 8.24 for next step.
 
882
   */
 
883
  x = CFX_DIV (frame, n_frames) << 8;
 
884
 
 
885
  /*
 
886
   * f(x) = -2x^3 + 3x^2
 
887
   * 
 
888
   * Convert result to EggFixed to avoid overflow in next step.
 
889
   */
 
890
  r = ((x >> 12) * (x >> 12) * 3 - (x >> 15) * (x >> 16) * (x >> 16)) >> 8;
 
891
 
 
892
  return CFX_INT (r * EGG_ALPHA_MAX_ALPHA);
 
893
}
 
894
 
 
895
/**
 
896
 * EGG_ALPHA_SMOOTHSTEP_DEC:
 
897
 *
 
898
 * Convenience symbol for egg_smoothstep_dec_func().
 
899
 *
 
900
 * Since: 0.4
 
901
 */
 
902
 
 
903
/**
 
904
 * egg_smoothstep_dec_func:
 
905
 * @alpha: a #EggAlpha
 
906
 * @dummy: unused
 
907
 *
 
908
 * Convenience alpha function for a downward smoothstep curve. You can use
 
909
 * this function as the alpha function for egg_alpha_set_func().
 
910
 *
 
911
 * Return value: an alpha value
 
912
 *
 
913
 * Since: 0.4
 
914
 */
 
915
guint32
 
916
egg_smoothstep_dec_func (EggAlpha  *alpha,
 
917
                             gpointer       dummy)
 
918
{
 
919
  return EGG_ALPHA_MAX_ALPHA - egg_smoothstep_inc_func (alpha, dummy);
 
920
}
 
921
 
 
922
/**
 
923
 * EGG_ALPHA_EXP_INC:
 
924
 *
 
925
 * Convenience symbol for egg_exp_inc_func()
 
926
 *
 
927
 * Since: 0.4
 
928
 */
 
929
 
 
930
/**
 
931
 * egg_exp_inc_func:
 
932
 * @alpha: a #EggAlpha
 
933
 * @dummy: unused argument
 
934
 *
 
935
 * Convenience alpha function for a 2^x curve. You can use this function as the
 
936
 * alpha function for egg_alpha_set_func().
 
937
 *
 
938
 * Return value: an alpha value.
 
939
 *
 
940
 * Since: 0.4
 
941
 */
 
942
guint32 
 
943
egg_exp_inc_func (EggAlpha *alpha,
 
944
                      gpointer      dummy)
 
945
{
 
946
  EggTimeline * timeline;
 
947
  gint              frame;
 
948
  gint              n_frames;
 
949
  EggFixed      x;
 
950
  EggFixed      x_alpha_max = 0x100000;
 
951
  guint32           result;
 
952
  
 
953
  /*
 
954
   * Choose x_alpha_max such that
 
955
   * 
 
956
   *   (2^x_alpha_max) - 1 == EGG_ALPHA_MAX_ALPHA
 
957
   */
 
958
#if EGG_ALPHA_MAX_ALPHA != 0xffff
 
959
#error Adjust x_alpha_max to match EGG_ALPHA_MAX_ALPHA
 
960
#endif
 
961
  
 
962
  timeline = egg_alpha_get_timeline (alpha);
 
963
  frame    = egg_timeline_get_current_frame (timeline);
 
964
  n_frames = egg_timeline_get_n_frames (timeline);
 
965
 
 
966
  x =  x_alpha_max * frame / n_frames;
 
967
 
 
968
  result = CLAMP (egg_pow2x (x) - 1, 0, EGG_ALPHA_MAX_ALPHA);
 
969
 
 
970
  return result;
 
971
}
 
972
 
 
973
/**
 
974
 * EGG_ALPHA_EXP_DEC:
 
975
 *
 
976
 * Convenience symbold for egg_exp_dec_func().
 
977
 *
 
978
 * Since: 0.4
 
979
 */
 
980
 
 
981
/**
 
982
 * egg_exp_dec_func:
 
983
 * @alpha: a #EggAlpha
 
984
 * @dummy: unused argument
 
985
 *
 
986
 * Convenience alpha function for a decreasing 2^x curve. You can use this
 
987
 * function as the alpha function for egg_alpha_set_func().
 
988
 *
 
989
 * Return value: an alpha value.
 
990
 *
 
991
 * Since: 0.4
 
992
 */
 
993
guint32 
 
994
egg_exp_dec_func (EggAlpha *alpha,
 
995
                      gpointer      dummy)
 
996
{
 
997
  EggTimeline * timeline;
 
998
  gint              frame;
 
999
  gint              n_frames;
 
1000
  EggFixed      x;
 
1001
  EggFixed      x_alpha_max = 0x100000;
 
1002
  guint32           result;
 
1003
  
 
1004
  /*
 
1005
   * Choose x_alpha_max such that
 
1006
   * 
 
1007
   *   (2^x_alpha_max) - 1 == EGG_ALPHA_MAX_ALPHA
 
1008
   */
 
1009
#if EGG_ALPHA_MAX_ALPHA != 0xffff
 
1010
#error Adjust x_alpha_max to match EGG_ALPHA_MAX_ALPHA
 
1011
#endif
 
1012
  
 
1013
  timeline = egg_alpha_get_timeline (alpha);
 
1014
  frame    = egg_timeline_get_current_frame (timeline);
 
1015
  n_frames = egg_timeline_get_n_frames (timeline);
 
1016
 
 
1017
  x =  (x_alpha_max * (n_frames - frame)) / n_frames;
 
1018
 
 
1019
  result = CLAMP (egg_pow2x (x) - 1, 0, EGG_ALPHA_MAX_ALPHA);
 
1020
 
 
1021
  return result;
 
1022
}