1 /*
2  * Clutter.
3  *
4  * An OpenGL based 'interactive canvas' library.
5  *
6  * Authored By Matthew Allum  <mallum@openedhand.com>
7  *             Tomas Frydrych <tf@openedhand.com>
8  *
9  * Copyright (C) 2006 OpenedHand
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the
23  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24  * Boston, MA 02111-1307, USA.
25  */
26 
27 #ifndef _HAVE_EGG_FIXED_H
28 #define _HAVE_EGG_FIXED_H
29 
30 #include <glib-object.h>
31 
32 G_BEGIN_DECLS
33 
34 /**
35  * EggFixed:
36  *
37  * Fixed point number (16.16)
38  */
39 typedef gint32 EggFixed;
40 
41 /**
42  * EggAngle:
43  *
44  * Integer representation of an angle such that 1024 corresponds to
45  * full circle (i.e., 2*Pi).
46  */
47 typedef gint32 EggAngle;    /* angle such that 1024 == 2*PI */
48 
49 #define EGG_ANGLE_FROM_DEG(x)  (EGG_FLOAT_TO_INT (((x) * 1024.0) / 360.0))
50 #define EGG_ANGLE_FROM_DEGF(x) (EGG_FLOAT_TO_INT (((float)(x) * 1024.0f) / 360.0f))
51 #define EGG_ANGLE_FROM_DEGX(x) (CFX_INT((((x)/360)*1024) + CFX_HALF))
52 #define EGG_ANGLE_TO_DEG(x)    (((x) * 360.0)/ 1024.0)
53 #define EGG_ANGLE_TO_DEGF(x)   (((float)(x) * 360.0)/ 1024.0)
54 #define EGG_ANGLE_TO_DEGX(x)   (EGG_INT_TO_FIXED((x) * 45)/128)
55 
56 /*
57  * some commonly used constants
58  */
59 
60 /**
61  * CFX_Q:
62  *
63  * Size in bits of decimal part of floating point value.
64  */
65 #define CFX_Q      16		/* Decimal part size in bits */
66 
67 /**
68  * CFX_ONE:
69  *
70  * 1.0 represented as a fixed point value.
71  */
72 #define CFX_ONE    (1 << CFX_Q)	/* 1 */
73 
74 /**
75  * CFX_HALF:
76  *
77  * 0.5 represented as a fixed point value.
78  */
79 #define CFX_HALF   32768
80 
81 /**
82  * CFX_MAX:
83  *
84  * Maximum fixed point value.
85  */
86 #define CFX_MAX    0x7fffffff
87 
88 /**
89  * CFX_MIN:
90  *
91  * Minimum fixed point value.
92  */
93 #define CFX_MIN    0x80000000
94 
95 /**
96  * CFX_PI:
97  *
98  * Fixed point representation of Pi
99  */
100 #define CFX_PI     0x0003243f
101 /**
102  * CFX_2PI:
103  *
104  * Fixed point representation of Pi*2
105  */
106 #define CFX_2PI    0x0006487f
107 /**
108  * CFX_PI_2:
109  *
110  * Fixed point representation of Pi/2
111  */
112 #define CFX_PI_2   0x00019220   /* pi/2 */
113 /**
114  * CFX_PI_4:
115  *
116  * Fixed point representation of Pi/4
117  */
118 #define CFX_PI_4   0x0000c910   /* pi/4 */
119 /**
120  * CFX_360:
121  *
122  * Fixed point representation of the number 360
123  */
124 #define CFX_360 EGG_INT_TO_FIXED (360)
125 /**
126  * CFX_240:
127  *
128  * Fixed point representation of the number 240
129  */
130 #define CFX_240 EGG_INT_TO_FIXED (240)
131 /**
132  * CFX_180:
133  *
134  * Fixed point representation of the number 180
135  */
136 #define CFX_180 EGG_INT_TO_FIXED (180)
137 /**
138  * CFX_120:
139  *
140  * Fixed point representation of the number 120
141  */
142 #define CFX_120 EGG_INT_TO_FIXED (120)
143 /**
144  * CFX_60:
145  *
146  * Fixed point representation of the number 60
147  */
148 #define CFX_60  EGG_INT_TO_FIXED (60)
149 /**
150  * CFX_RADIANS_TO_DEGREES:
151  *
152  * Fixed point representation of the number 180 / pi
153  */
154 #define CFX_RADIANS_TO_DEGREES 0x394bb8
155 /**
156  * CFX_255:
157  *
158  * Fixed point representation of the number 255
159  */
160 #define CFX_255 EGG_INT_TO_FIXED (255)
161 
162 /**
163  * EGG_FIXED_TO_FLOAT:
164  * @x: a fixed point value
165  *
166  * Convert a fixed point value to float.
167  */
168 #define EGG_FIXED_TO_FLOAT(x)       ((float) ((int)(x) / 65536.0))
169 
170 /**
171  * EGG_FIXED_TO_DOUBLE:
172  * @x: a fixed point value
173  *
174  * Convert a fixed point value to double.
175  */
176 #define EGG_FIXED_TO_DOUBLE(x)      ((double) ((int)(x) / 65536.0))
177 
178 /**
179  * EGG_FLOAT_TO_FIXED:
180  * @x: a floating point value
181  *
182  * Convert a float value to fixed.
183  */
184 #define EGG_FLOAT_TO_FIXED(x)       (egg_double_to_fixed ((x)))
185 
186 /**
187  * EGG_FLOAT_TO_INT:
188  * @x: a floating point value
189  *
190  * Convert a float value to int.
191  */
192 #define EGG_FLOAT_TO_INT(x)         (egg_double_to_int ((x)))
193 
194 /**
195  * EGG_FLOAT_TO_UINT:
196  * @x: a floating point value
197  *
198  * Convert a float value to unsigned int.
199  */
200 #define EGG_FLOAT_TO_UINT(x)         (egg_double_to_uint ((x)))
201 
202 /**
203  * EGG_INT_TO_FIXED:
204  * @x: an integer value
205  *
206  * Convert an integer value to fixed point.
207  */
208 #define EGG_INT_TO_FIXED(x)         ((x) << CFX_Q)
209 
210 /**
211  * EGG_FIXED_TO_INT:
212  * @x: a fixed point value
213  *
214  * Converts a fixed point value to integer (removing the decimal part).
215  *
216  * Since: 0.6
217  */
218 #define EGG_FIXED_TO_INT(x)         ((x) >> CFX_Q)
219 
220 #ifndef EGG_DISABLE_DEPRECATED
221 
222 /**
223  * EGG_FIXED_INT:
224  * @x: a fixed point value
225  *
226  * Convert a fixed point value to integer (removing decimal part).
227  *
228  * Deprecated:0.6: Use %EGG_FIXED_TO_INT instead
229  */
230 #define EGG_FIXED_INT(x)            EGG_FIXED_TO_INT((x))
231 
232 #endif /* !EGG_DISABLE_DEPRECATED */
233 
234 /**
235  * EGG_FIXED_FRACTION:
236  * @x: a fixed point value
237  *
238  * Retrieves the fractionary part of a fixed point value
239  */
240 #define EGG_FIXED_FRACTION(x)       ((x) & ((1 << CFX_Q) - 1))
241 
242 /**
243  * EGG_FIXED_FLOOR:
244  * @x: a fixed point value
245  *
246  * Round down a fixed point value to an integer.
247  */
248 #define EGG_FIXED_FLOOR(x)          (((x) >= 0) ? ((x) >> CFX_Q) \
249                                                     : ~((~(x)) >> CFX_Q))
250 /**
251  * EGG_FIXED_CEIL:
252  * @x: a fixed point value
253  *
254  * Round up a fixed point value to an integer.
255  */
256 #define EGG_FIXED_CEIL(x)           (EGG_FIXED_FLOOR (x + 0xffff))
257 
258 /**
259  * EGG_FIXED_MUL:
260  * @x: a fixed point value
261  * @y: a fixed point value
262  *
263  * Multiply two fixed point values
264  */
265 #define EGG_FIXED_MUL(x,y) ((x) >> 8) * ((y) >> 8)
266 
267 /**
268  * EGG_FIXED_DIV:
269  * @x: a fixed point value
270  * @y: a fixed point value
271  *
272  * Divide two fixed point values
273  */
274 #define EGG_FIXED_DIV(x,y) ((((x) << 8)/(y)) << 8)
275 
276 /* Some handy fixed point short aliases to avoid exessively long lines */
277 /* FIXME: Remove from public API */
278 /*< private >*/
279 #define CFX_INT         EGG_FIXED_INT
280 #define CFX_MUL         EGG_FIXED_MUL
281 #define CFX_DIV         EGG_FIXED_DIV
282 #define CFX_QMUL(x,y)   egg_qmulx (x,y)
283 #define CFX_QDIV(x,y)   egg_qdivx (x,y)
284 
285 /*< public >*/
286 /* Fixed point math routines */
287 G_INLINE_FUNC
288 EggFixed egg_qmulx (EggFixed op1,
289 			    EggFixed op2);
290 #if defined (G_CAN_INLINE)
291 G_INLINE_FUNC
egg_qmulx(EggFixed op1,EggFixed op2)292 EggFixed egg_qmulx (EggFixed op1,
293 			    EggFixed op2)
294 {
295 #ifdef __arm__
296     int res_low, res_hi;
297 
298     __asm__ ("smull %0, %1, %2, %3     \n"
299 	     "mov   %0, %0,     lsr %4 \n"
300 	     "add   %1, %0, %1, lsl %5 \n"
301 	     : "=r"(res_hi), "=r"(res_low)\
302 	     : "r"(op1), "r"(op2), "i"(CFX_Q), "i"(32-CFX_Q));
303 
304     return (EggFixed) res_low;
305 #else
306     long long r = (long long) op1 * (long long) op2;
307 
308     return (unsigned int)(r >> CFX_Q);
309 #endif
310 }
311 #endif
312 
313 G_INLINE_FUNC
314 EggFixed egg_qdivx (EggFixed op1,
315 			    EggFixed op2);
316 #if defined (G_CAN_INLINE)
317 G_INLINE_FUNC
egg_qdivx(EggFixed op1,EggFixed op2)318 EggFixed egg_qdivx (EggFixed op1,
319 			    EggFixed op2)
320 {
321   return (EggFixed) ((((gint64) op1) << CFX_Q) / op2);
322 }
323 #endif
324 
325 EggFixed egg_sinx (EggFixed angle);
326 EggFixed egg_sini (EggAngle angle);
327 
328 EggFixed egg_tani (EggAngle angle);
329 
330 EggFixed egg_atani (EggFixed x);
331 EggFixed egg_atan2i (EggFixed y, EggFixed x);
332 
333 /* convenience macros for the cos functions */
334 
335 /**
336  * egg_cosx:
337  * @angle: a #EggFixed angle in radians
338  *
339  * Fixed point cosine function
340  *
341  * Return value: #EggFixed cosine value.
342  *
343  * Note: Implemneted as a macro.
344  *
345  * Since: 0.2
346  */
347 #define egg_cosx(angle) (egg_sinx((angle) + CFX_PI_2))
348 
349 /**
350  * egg_cosi:
351  * @angle: a #EggAngle angle
352  *
353  * Very fast fixed point implementation of cosine function.
354  *
355  * EggAngle is an integer such that 1024 represents
356  * full circle.
357  *
358  * Return value: #EggFixed cosine value.
359  *
360  * Note: Implemneted as a macro.
361  *
362  * Since: 0.2
363  */
364 #define egg_cosi(angle) (egg_sini ((angle) + 256))
365 
366 /**
367  * EGG_SQRTI_ARG_MAX
368  *
369  * Maximum argument that can be passed to #egg_sqrti function.
370  *
371  * Since: 0.6
372  */
373 #ifndef __SSE2__
374 #define EGG_SQRTI_ARG_MAX 0x3fffff
375 #else
376 #define EGG_SQRTI_ARG_MAX INT_MAX
377 #endif
378 
379 /**
380  * EGG_SQRTI_ARG_5_PERCENT
381  *
382  * Maximum argument that can be passed to #egg_sqrti for which the
383  * resulting error is < 5%
384  *
385  * Since: 0.6
386  */
387 #ifndef __SSE2__
388 #define EGG_SQRTI_ARG_5_PERCENT 210
389 #else
390 #define EGG_SQRTI_ARG_5_PERCENT INT_MAX
391 #endif
392 
393 /**
394  * EGG_SQRTI_ARG_10_PERCENT
395  *
396  * Maximum argument that can be passed to #egg_sqrti for which the
397  * resulting error is < 10%
398  *
399  * Since: 0.6
400  */
401 #ifndef __SSE2__
402 #define EGG_SQRTI_ARG_10_PERCENT 5590
403 #else
404 #define EGG_SQRTI_ARG_10_PERCENT INT_MAX
405 #endif
406 
407 EggFixed egg_sqrtx (EggFixed x);
408 gint         egg_sqrti (gint         x);
409 
410 EggFixed egg_log2x (guint x);
411 guint        egg_pow2x (EggFixed x);
412 guint        egg_powx  (guint x, EggFixed y);
413 
414 #define EGG_TYPE_FIXED                 (egg_fixed_get_type ())
415 #define EGG_TYPE_PARAM_FIXED           (egg_param_fixed_get_type ())
416 #define EGG_PARAM_SPEC_FIXED(pspec)    (G_TYPE_CHECK_INSTANCE_CAST ((pspec), EGG_TYPE_PARAM_FIXED, EggParamSpecFixed))
417 #define EGG_IS_PARAM_SPEC_FIXED(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), EGG_TYPE_PARAM_FIXED))
418 
419 /**
420  * EGG_VALUE_HOLDS_FIXED:
421  * @x: a #GValue
422  *
423  * Evaluates to %TRUE if @x holds a #EggFixed.
424  *
425  * Since: 0.8
426  */
427 #define EGG_VALUE_HOLDS_FIXED(x)    (G_VALUE_HOLDS ((x), EGG_TYPE_FIXED))
428 
429 typedef struct _EggParamSpecFixed   EggParamSpecFixed;
430 
431 /**
432  * EGG_MAXFIXED:
433  *
434  * Higher boundary for #EggFixed
435  *
436  * Since: 0.8
437  */
438 #define EGG_MAXFIXED        CFX_MAX
439 
440 /**
441  * EGG_MINFIXED:
442  *
443  * Lower boundary for #EggFixed
444  *
445  * Since: 0.8
446  */
447 #define EGG_MINFIXED        CFX_MIN
448 
449 /**
450  * EggParamSpecFixed
451  * @minimum: lower boundary
452  * @maximum: higher boundary
453  * @default_value: default value
454  *
455  * #GParamSpec subclass for fixed point based properties
456  *
457  * Since: 0.8
458  */
459 struct _EggParamSpecFixed
460 {
461   /*< private >*/
462   GParamSpec    parent_instance;
463 
464   /*< public >*/
465   EggFixed  minimum;
466   EggFixed  maximum;
467   EggFixed  default_value;
468 };
469 
470 GType        egg_fixed_get_type       (void) G_GNUC_CONST;
471 GType        egg_param_fixed_get_type (void) G_GNUC_CONST;
472 
473 void         egg_value_set_fixed      (GValue       *value,
474                                            EggFixed  fixed_);
475 EggFixed egg_value_get_fixed      (const GValue *value);
476 
477 GParamSpec * egg_param_spec_fixed     (const gchar  *name,
478                                            const gchar  *nick,
479                                            const gchar  *blurb,
480                                            EggFixed  minimum,
481                                            EggFixed  maximum,
482                                            EggFixed  default_value,
483                                            GParamFlags   flags);
484 
485 /* <private> */
486 extern EggFixed egg_double_to_fixed (double value);
487 extern gint         egg_double_to_int   (double value);
488 extern guint        egg_double_to_unit  (double value);
489 
490 G_END_DECLS
491 
492 #endif /* _HAVE_EGG_FIXED_H */
493