Index: apps/plugins/pdbox/pdbox-func.c =================================================================== --- apps/plugins/pdbox/pdbox-func.c (revision 0) +++ apps/plugins/pdbox/pdbox-func.c (revision 0) @@ -0,0 +1,284 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 Wincent Balin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "plugin.h" +#include "pdbox.h" + +#include "ctype.h" + + +/* This implementation of strncat is taken from lua plug-in. */ + +/* gcc is broken and has a non-SUSv2 compliant internal prototype. + * This causes it to warn about a type mismatch here. Ignore it. */ +char *rb_strncat(char *s, const char *t, size_t n) +{ + char *dest = s; + register char *max; + s += rb->strlen(s); + + if((max = s + n) == s) + goto strncat_fini; + + while(true) + { + if(!(*s = *t)) + break; + if(++s == max) + break; + ++t; + +#ifndef WANT_SMALL_STRING_ROUTINES + if(!(*s = *t)) + break; + if(++s == max) + break; + ++t; + if(!(*s = *t)) + break; + if(++s == max) + break; + ++t; + if(!(*s = *t)) + break; + if(++s == max) + break; + ++t; +#endif + } + + *s = 0; + +strncat_fini: + return dest; +} + + +/* Implementation of floor, original. */ + +float rb_floor(float value) +{ + /* If value is negative, decrement value to match function's definition. */ + if(value < 0.0) + { + value -= 1.0; + } + + /* Truncate fractional part (convert to integer) + and afterwards convert back to double. */ + return (float) ((int) value); +} + + +/* Implementation of strtod() and atof(), + taken from SanOS (http://www.jbox.dk/sanos/). */ + +double rb_strtod(const char *str, char **endptr) +{ + double number; + int exponent; + int negative; + char *p = (char *) str; + double p10; + int n; + int num_digits; + int num_decimals; + + // Skip leading whitespace + while (isspace(*p)) p++; + + // Handle optional sign + negative = 0; + switch (*p) + { + case '-': negative = 1; // Fall through to increment position + case '+': p++; + } + + number = 0.; + exponent = 0; + num_digits = 0; + num_decimals = 0; + + // Process string of digits + while (isdigit(*p)) + { + number = number * 10. + (*p - '0'); + p++; + num_digits++; + } + + // Process decimal part + if (*p == '.') + { + p++; + + while (isdigit(*p)) + { + number = number * 10. + (*p - '0'); + p++; + num_digits++; + num_decimals++; + } + + exponent -= num_decimals; + } + + if (num_digits == 0) + { +#ifndef ROCKBOX + errno = ERANGE; +#endif + return 0.0; + } + + // Correct for sign + if (negative) number = -number; + + // Process an exponent string + if (*p == 'e' || *p == 'E') + { + // Handle optional sign + negative = 0; + switch(*++p) + { + case '-': negative = 1; // Fall through to increment pos + case '+': p++; + } + + // Process string of digits + n = 0; + while (isdigit(*p)) + { + n = n * 10 + (*p - '0'); + p++; + } + + if (negative) + exponent -= n; + else + exponent += n; + } + +#ifndef ROCKBOX + if (exponent < DBL_MIN_EXP || exponent > DBL_MAX_EXP) + { + errno = ERANGE; + return HUGE_VAL; + } +#endif + + // Scale the result + p10 = 10.; + n = exponent; + if (n < 0) n = -n; + while (n) + { + if (n & 1) + { + if (exponent < 0) + number /= p10; + else + number *= p10; + } + n >>= 1; + p10 *= p10; + } + +#ifndef ROCKBOX + if (number == HUGE_VAL) errno = ERANGE; +#endif + if (endptr) *endptr = p; + + return number; +} + +double rb_atof(const char *str) +{ + return rb_strtod(str, NULL); +} + + + +/* Implementation of atol(), adapted from + the atoi() implementation in Rockbox. */ +long rb_atol(const char* str) +{ + long value = 0; + long sign = 1; + + while (isspace(*str)) + { + str++; + } + + if ('-' == *str) + { + sign = -1; + str++; + } + else if ('+' == *str) + { + str++; + } + + while ('0' == *str) + { + str++; + } + + while (isdigit(*str)) + { + value = (value * 10L) + (*str - '0'); + str++; + } + + return value * sign; +} + + +/* Implementation of sin() and cos(), + adapted from http://lab.polygonal.de/2007/07/18/fast-and-accurate-sinecosine-approximation/ +*/ + +float rb_sin(float rad) +{ + /* Trim input value to -PI..PI interval. */ + if(rad < -3.14159265) + rad += 6.28318531; + else if(rad > 3.14159265) + rad -= 6.28318531; + + if(rad < 0) + return (1.27323954 * rad + 0.405284735 * rad * rad); + else + return (1.27323954 * rad - 0.405284735 * rad * rad); +} + +float rb_cos(float rad) +{ + /* Compute cosine: sin(x + PI/2) = cos(x) */ + rad += 1.57079632; + if(rad > 3.14159265) + rad -= 6.28318531; + + return rb_sin(rad); +}