diff options
author | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
commit | dd7595a3475407a7fa96a97393bae8c5220e8762 (patch) | |
tree | e341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/embryo/src/lib/embryo_float.c | |
parent | Add the skeleton. (diff) | |
download | SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2 SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz |
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/embryo/src/lib/embryo_float.c')
-rw-r--r-- | libraries/embryo/src/lib/embryo_float.c | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/libraries/embryo/src/lib/embryo_float.c b/libraries/embryo/src/lib/embryo_float.c new file mode 100644 index 0000000..608be9d --- /dev/null +++ b/libraries/embryo/src/lib/embryo_float.c | |||
@@ -0,0 +1,331 @@ | |||
1 | /* Float arithmetic for the Small AMX engine | ||
2 | * | ||
3 | * Copyright (c) Artran, Inc. 1999 | ||
4 | * Written by Greg Garner (gmg@artran.com) | ||
5 | * Portions Copyright (c) Carsten Haitzler, 2004 <raster@rasterman.com> | ||
6 | * | ||
7 | * This software is provided "as-is", without any express or implied warranty. | ||
8 | * In no event will the authors be held liable for any damages arising from | ||
9 | * the use of this software. | ||
10 | * | ||
11 | * Permission is granted to anyone to use this software for any purpose, | ||
12 | * including commercial applications, and to alter it and redistribute it | ||
13 | * freely, subject to the following restrictions: | ||
14 | * | ||
15 | * 1. The origin of this software must not be misrepresented; you must not | ||
16 | * claim that you wrote the original software. If you use this software in | ||
17 | * a product, an acknowledgment in the product documentation would be | ||
18 | * appreciated but is not required. | ||
19 | * 2. Altered source versions must be plainly marked as such, and must not be | ||
20 | * misrepresented as being the original software. | ||
21 | * 3. This notice may not be removed or altered from any source distribution. | ||
22 | */ | ||
23 | |||
24 | /* CHANGES - | ||
25 | * 2002-08-27: Basic conversion of source from C++ to C by Adam D. Moss | ||
26 | * <adam@gimp.org> <aspirin@icculus.org> | ||
27 | * 2003-08-29: Removal of the dynamic memory allocation and replacing two | ||
28 | * type conversion functions by macros, by Thiadmer Riemersma | ||
29 | * 2003-09-22: Moved the type conversion macros to AMX.H, and simplifications | ||
30 | * of some routines, by Thiadmer Riemersma | ||
31 | * 2003-11-24: A few more native functions (geometry), plus minor modifications, | ||
32 | * mostly to be compatible with dynamically loadable extension | ||
33 | * modules, by Thiadmer Riemersma | ||
34 | * 2004-03-20: Cleaned up and reduced size for Embryo, Modified to conform to | ||
35 | * E coding style. Added extra parameter checks. | ||
36 | * Carsten Haitzler, <raster@rasterman.com> | ||
37 | */ | ||
38 | |||
39 | |||
40 | #ifdef HAVE_CONFIG_H | ||
41 | # include "config.h" | ||
42 | #endif | ||
43 | |||
44 | #include <stdlib.h> | ||
45 | #include <math.h> | ||
46 | |||
47 | #include "Embryo.h" | ||
48 | #include "embryo_private.h" | ||
49 | |||
50 | #define PI 3.1415926535897932384626433832795f | ||
51 | |||
52 | /* internally useful calls */ | ||
53 | |||
54 | static float | ||
55 | _embryo_fp_degrees_to_radians(float angle, int radix) | ||
56 | { | ||
57 | switch (radix) | ||
58 | { | ||
59 | case 1: /* degrees, sexagesimal system (technically: degrees/minutes/seconds) */ | ||
60 | return (angle * PI / 180.0f); | ||
61 | case 2: /* grades, centesimal system */ | ||
62 | return (angle * PI / 200.0f); | ||
63 | default: /* assume already radian */ | ||
64 | break; | ||
65 | } | ||
66 | return angle; | ||
67 | } | ||
68 | |||
69 | /* exported float api */ | ||
70 | |||
71 | static Embryo_Cell | ||
72 | _embryo_fp(Embryo_Program *ep __UNUSED__, Embryo_Cell *params) | ||
73 | { | ||
74 | /* params[1] = long value to convert to a float */ | ||
75 | float f; | ||
76 | |||
77 | if (params[0] != (1 * sizeof(Embryo_Cell))) return 0; | ||
78 | f = (float)params[1]; | ||
79 | return EMBRYO_FLOAT_TO_CELL(f); | ||
80 | } | ||
81 | |||
82 | static Embryo_Cell | ||
83 | _embryo_fp_str(Embryo_Program *ep, Embryo_Cell *params) | ||
84 | { | ||
85 | /* params[1] = virtual string address to convert to a float */ | ||
86 | char buf[64]; | ||
87 | Embryo_Cell *str; | ||
88 | float f; | ||
89 | int len; | ||
90 | |||
91 | if (params[0] != (1 * sizeof(Embryo_Cell))) return 0; | ||
92 | str = embryo_data_address_get(ep, params[1]); | ||
93 | len = embryo_data_string_length_get(ep, str); | ||
94 | if ((len == 0) || (len >= (int)sizeof(buf))) return 0; | ||
95 | embryo_data_string_get(ep, str, buf); | ||
96 | f = (float)atof(buf); | ||
97 | return EMBRYO_FLOAT_TO_CELL(f); | ||
98 | } | ||
99 | |||
100 | static Embryo_Cell | ||
101 | _embryo_fp_mul(Embryo_Program *ep __UNUSED__, Embryo_Cell *params) | ||
102 | { | ||
103 | /* params[1] = float operand 1 */ | ||
104 | /* params[2] = float operand 2 */ | ||
105 | float f; | ||
106 | |||
107 | if (params[0] != (2 * sizeof(Embryo_Cell))) return 0; | ||
108 | f = EMBRYO_CELL_TO_FLOAT(params[1]) * EMBRYO_CELL_TO_FLOAT(params[2]); | ||
109 | return EMBRYO_FLOAT_TO_CELL(f); | ||
110 | } | ||
111 | |||
112 | static Embryo_Cell | ||
113 | _embryo_fp_div(Embryo_Program *ep __UNUSED__, Embryo_Cell *params) | ||
114 | { | ||
115 | /* params[1] = float dividend (top) */ | ||
116 | /* params[2] = float divisor (bottom) */ | ||
117 | float f; | ||
118 | |||
119 | if (params[0] != (2 * sizeof(Embryo_Cell))) return 0; | ||
120 | f = EMBRYO_CELL_TO_FLOAT(params[1]) / EMBRYO_CELL_TO_FLOAT(params[2]); | ||
121 | return EMBRYO_FLOAT_TO_CELL(f); | ||
122 | } | ||
123 | |||
124 | static Embryo_Cell | ||
125 | _embryo_fp_add(Embryo_Program *ep __UNUSED__, Embryo_Cell *params) | ||
126 | { | ||
127 | /* params[1] = float operand 1 */ | ||
128 | /* params[2] = float operand 2 */ | ||
129 | float f; | ||
130 | |||
131 | if (params[0] != (2 * sizeof(Embryo_Cell))) return 0; | ||
132 | f = EMBRYO_CELL_TO_FLOAT(params[1]) + EMBRYO_CELL_TO_FLOAT(params[2]); | ||
133 | return EMBRYO_FLOAT_TO_CELL(f); | ||
134 | } | ||
135 | |||
136 | static Embryo_Cell | ||
137 | _embryo_fp_sub(Embryo_Program *ep __UNUSED__, Embryo_Cell *params) | ||
138 | { | ||
139 | /* params[1] = float operand 1 */ | ||
140 | /* params[2] = float operand 2 */ | ||
141 | float f; | ||
142 | |||
143 | if (params[0] != (2 * sizeof(Embryo_Cell))) return 0; | ||
144 | f = EMBRYO_CELL_TO_FLOAT(params[1]) - EMBRYO_CELL_TO_FLOAT(params[2]); | ||
145 | return EMBRYO_FLOAT_TO_CELL(f); | ||
146 | } | ||
147 | |||
148 | /* Return fractional part of float */ | ||
149 | static Embryo_Cell | ||
150 | _embryo_fp_fract(Embryo_Program *ep __UNUSED__, Embryo_Cell *params) | ||
151 | { | ||
152 | /* params[1] = float operand */ | ||
153 | float f; | ||
154 | |||
155 | if (params[0] != (1 * sizeof(Embryo_Cell))) return 0; | ||
156 | f = EMBRYO_CELL_TO_FLOAT(params[1]); | ||
157 | f -= (floorf(f)); | ||
158 | return EMBRYO_FLOAT_TO_CELL(f); | ||
159 | } | ||
160 | |||
161 | /* Return integer part of float, rounded */ | ||
162 | static Embryo_Cell | ||
163 | _embryo_fp_round(Embryo_Program *ep __UNUSED__, Embryo_Cell *params) | ||
164 | { | ||
165 | /* params[1] = float operand */ | ||
166 | /* params[2] = Type of rounding (cell) */ | ||
167 | float f; | ||
168 | |||
169 | if (params[0] != (2 * sizeof(Embryo_Cell))) return 0; | ||
170 | f = EMBRYO_CELL_TO_FLOAT(params[1]); | ||
171 | switch (params[2]) | ||
172 | { | ||
173 | case 1: /* round downwards (truncate) */ | ||
174 | f = (floorf(f)); | ||
175 | break; | ||
176 | case 2: /* round upwards */ | ||
177 | f = (ceilf(f)); | ||
178 | break; | ||
179 | case 3: /* round towards zero */ | ||
180 | if (f >= 0.0) f = (floorf(f)); | ||
181 | else f = (ceilf(f)); | ||
182 | break; | ||
183 | default: /* standard, round to nearest */ | ||
184 | f = (floorf(f + 0.5)); | ||
185 | break; | ||
186 | } | ||
187 | return (Embryo_Cell)f; | ||
188 | } | ||
189 | |||
190 | static Embryo_Cell | ||
191 | _embryo_fp_cmp(Embryo_Program *ep __UNUSED__, Embryo_Cell *params) | ||
192 | { | ||
193 | /* params[1] = float operand 1 */ | ||
194 | /* params[2] = float operand 2 */ | ||
195 | float f, ff; | ||
196 | |||
197 | if (params[0] != (2 * sizeof(Embryo_Cell))) return 0; | ||
198 | f = EMBRYO_CELL_TO_FLOAT(params[1]); | ||
199 | ff = EMBRYO_CELL_TO_FLOAT(params[2]); | ||
200 | if (f == ff) return 0; | ||
201 | else if (f > ff) return 1; | ||
202 | return -1; | ||
203 | } | ||
204 | |||
205 | static Embryo_Cell | ||
206 | _embryo_fp_sqroot(Embryo_Program *ep, Embryo_Cell *params) | ||
207 | { | ||
208 | /* params[1] = float operand */ | ||
209 | float f; | ||
210 | |||
211 | if (params[0] != (1 * sizeof(Embryo_Cell))) return 0; | ||
212 | f = EMBRYO_CELL_TO_FLOAT(params[1]); | ||
213 | f = sqrtf(f); | ||
214 | if (f < 0) | ||
215 | { | ||
216 | embryo_program_error_set(ep, EMBRYO_ERROR_DOMAIN); | ||
217 | return 0; | ||
218 | } | ||
219 | return EMBRYO_FLOAT_TO_CELL(f); | ||
220 | } | ||
221 | |||
222 | static Embryo_Cell | ||
223 | _embryo_fp_power(Embryo_Program *ep __UNUSED__, Embryo_Cell *params) | ||
224 | { | ||
225 | /* params[1] = float operand 1 */ | ||
226 | /* params[2] = float operand 2 */ | ||
227 | float f, ff; | ||
228 | |||
229 | if (params[0] != (2 * sizeof(Embryo_Cell))) return 0; | ||
230 | f = EMBRYO_CELL_TO_FLOAT(params[1]); | ||
231 | ff = EMBRYO_CELL_TO_FLOAT(params[2]); | ||
232 | f = powf(f, ff); | ||
233 | return EMBRYO_FLOAT_TO_CELL(f); | ||
234 | } | ||
235 | |||
236 | static Embryo_Cell | ||
237 | _embryo_fp_log(Embryo_Program *ep, Embryo_Cell *params) | ||
238 | { | ||
239 | /* params[1] = float operand 1 (value) */ | ||
240 | /* params[2] = float operand 2 (base) */ | ||
241 | float f, ff; | ||
242 | |||
243 | if (params[0] != (2 * sizeof(Embryo_Cell))) return 0; | ||
244 | f = EMBRYO_CELL_TO_FLOAT(params[1]); | ||
245 | ff = EMBRYO_CELL_TO_FLOAT(params[2]); | ||
246 | if ((f <= 0.0) || (ff <= 0.0)) | ||
247 | { | ||
248 | embryo_program_error_set(ep, EMBRYO_ERROR_DOMAIN); | ||
249 | return 0; | ||
250 | } | ||
251 | if (ff == 10.0) f = log10f(f); | ||
252 | else f = (logf(f) / logf(ff)); | ||
253 | return EMBRYO_FLOAT_TO_CELL(f); | ||
254 | } | ||
255 | |||
256 | static Embryo_Cell | ||
257 | _embryo_fp_sin(Embryo_Program *ep __UNUSED__, Embryo_Cell *params) | ||
258 | { | ||
259 | /* params[1] = float operand 1 (angle) */ | ||
260 | /* params[2] = float operand 2 (radix) */ | ||
261 | float f; | ||
262 | |||
263 | if (params[0] != (2 * sizeof(Embryo_Cell))) return 0; | ||
264 | f = EMBRYO_CELL_TO_FLOAT(params[1]); | ||
265 | f = _embryo_fp_degrees_to_radians(f, params[2]); | ||
266 | f = sinf(f); | ||
267 | return EMBRYO_FLOAT_TO_CELL(f); | ||
268 | } | ||
269 | |||
270 | static Embryo_Cell | ||
271 | _embryo_fp_cos(Embryo_Program *ep __UNUSED__, Embryo_Cell *params) | ||
272 | { | ||
273 | /* params[1] = float operand 1 (angle) */ | ||
274 | /* params[2] = float operand 2 (radix) */ | ||
275 | float f; | ||
276 | |||
277 | if (params[0] != (2 * sizeof(Embryo_Cell))) return 0; | ||
278 | f = EMBRYO_CELL_TO_FLOAT(params[1]); | ||
279 | f = _embryo_fp_degrees_to_radians(f, params[2]); | ||
280 | f = cosf(f); | ||
281 | return EMBRYO_FLOAT_TO_CELL(f); | ||
282 | } | ||
283 | |||
284 | static Embryo_Cell | ||
285 | _embryo_fp_tan(Embryo_Program *ep __UNUSED__, Embryo_Cell *params) | ||
286 | { | ||
287 | /* params[1] = float operand 1 (angle) */ | ||
288 | /* params[2] = float operand 2 (radix) */ | ||
289 | float f; | ||
290 | |||
291 | if (params[0] != (2 * sizeof(Embryo_Cell))) return 0; | ||
292 | f = EMBRYO_CELL_TO_FLOAT(params[1]); | ||
293 | f = _embryo_fp_degrees_to_radians(f, params[2]); | ||
294 | f = tanf(f); | ||
295 | return EMBRYO_FLOAT_TO_CELL(f); | ||
296 | } | ||
297 | |||
298 | static Embryo_Cell | ||
299 | _embryo_fp_abs(Embryo_Program *ep __UNUSED__, Embryo_Cell *params) | ||
300 | { | ||
301 | /* params[1] = float operand */ | ||
302 | float f; | ||
303 | |||
304 | if (params[0] != (1 * sizeof(Embryo_Cell))) return 0; | ||
305 | f = EMBRYO_CELL_TO_FLOAT(params[1]); | ||
306 | f = (f >= 0) ? f : -f; | ||
307 | return EMBRYO_FLOAT_TO_CELL(f); | ||
308 | } | ||
309 | |||
310 | /* functions used by the rest of embryo */ | ||
311 | |||
312 | void | ||
313 | _embryo_fp_init(Embryo_Program *ep) | ||
314 | { | ||
315 | embryo_program_native_call_add(ep, "float", _embryo_fp); | ||
316 | embryo_program_native_call_add(ep, "atof", _embryo_fp_str); | ||
317 | embryo_program_native_call_add(ep, "float_mul", _embryo_fp_mul); | ||
318 | embryo_program_native_call_add(ep, "float_div", _embryo_fp_div); | ||
319 | embryo_program_native_call_add(ep, "float_add", _embryo_fp_add); | ||
320 | embryo_program_native_call_add(ep, "float_sub", _embryo_fp_sub); | ||
321 | embryo_program_native_call_add(ep, "fract", _embryo_fp_fract); | ||
322 | embryo_program_native_call_add(ep, "round", _embryo_fp_round); | ||
323 | embryo_program_native_call_add(ep, "float_cmp", _embryo_fp_cmp); | ||
324 | embryo_program_native_call_add(ep, "sqrt", _embryo_fp_sqroot); | ||
325 | embryo_program_native_call_add(ep, "pow", _embryo_fp_power); | ||
326 | embryo_program_native_call_add(ep, "log", _embryo_fp_log); | ||
327 | embryo_program_native_call_add(ep, "sin", _embryo_fp_sin); | ||
328 | embryo_program_native_call_add(ep, "cos", _embryo_fp_cos); | ||
329 | embryo_program_native_call_add(ep, "tan", _embryo_fp_tan); | ||
330 | embryo_program_native_call_add(ep, "abs", _embryo_fp_abs); | ||
331 | } | ||