Simple Directmedia Layer
at main 11 kB view raw
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "SDL_internal.h" 22 23// This file contains portable stdlib functions for SDL 24 25#include "../libm/math_libm.h" 26 27double SDL_atan(double x) 28{ 29#ifdef HAVE_ATAN 30 return atan(x); 31#else 32 return SDL_uclibc_atan(x); 33#endif 34} 35 36float SDL_atanf(float x) 37{ 38#ifdef HAVE_ATANF 39 return atanf(x); 40#else 41 return (float)SDL_atan((double)x); 42#endif 43} 44 45double SDL_atan2(double y, double x) 46{ 47#ifdef HAVE_ATAN2 48 return atan2(y, x); 49#else 50 return SDL_uclibc_atan2(y, x); 51#endif 52} 53 54float SDL_atan2f(float y, float x) 55{ 56#ifdef HAVE_ATAN2F 57 return atan2f(y, x); 58#else 59 return (float)SDL_atan2((double)y, (double)x); 60#endif 61} 62 63double SDL_acos(double val) 64{ 65#ifdef HAVE_ACOS 66 return acos(val); 67#else 68 double result; 69 if (val == -1.0) { 70 result = SDL_PI_D; 71 } else { 72 result = SDL_atan(SDL_sqrt(1.0 - val * val) / val); 73 if (result < 0.0) { 74 result += SDL_PI_D; 75 } 76 } 77 return result; 78#endif 79} 80 81float SDL_acosf(float val) 82{ 83#ifdef HAVE_ACOSF 84 return acosf(val); 85#else 86 return (float)SDL_acos((double)val); 87#endif 88} 89 90double SDL_asin(double val) 91{ 92#ifdef HAVE_ASIN 93 return asin(val); 94#else 95 double result; 96 if (val == -1.0) { 97 result = -(SDL_PI_D / 2.0); 98 } else { 99 result = (SDL_PI_D / 2.0) - SDL_acos(val); 100 } 101 return result; 102#endif 103} 104 105float SDL_asinf(float val) 106{ 107#ifdef HAVE_ASINF 108 return asinf(val); 109#else 110 return (float)SDL_asin((double)val); 111#endif 112} 113 114double SDL_ceil(double x) 115{ 116#ifdef HAVE_CEIL 117 return ceil(x); 118#else 119 double integer = SDL_floor(x); 120 double fraction = x - integer; 121 if (fraction > 0.0) { 122 integer += 1.0; 123 } 124 return integer; 125#endif // HAVE_CEIL 126} 127 128float SDL_ceilf(float x) 129{ 130#ifdef HAVE_CEILF 131 return ceilf(x); 132#else 133 return (float)SDL_ceil((double)x); 134#endif 135} 136 137double SDL_copysign(double x, double y) 138{ 139#ifdef HAVE_COPYSIGN 140 return copysign(x, y); 141#elif defined(HAVE__COPYSIGN) 142 return _copysign(x, y); 143#elif defined(__WATCOMC__) && defined(__386__) 144 // this is nasty as hell, but it works.. 145 unsigned int *xi = (unsigned int *)&x, 146 *yi = (unsigned int *)&y; 147 xi[1] = (yi[1] & 0x80000000) | (xi[1] & 0x7fffffff); 148 return x; 149#else 150 return SDL_uclibc_copysign(x, y); 151#endif // HAVE_COPYSIGN 152} 153 154float SDL_copysignf(float x, float y) 155{ 156#ifdef HAVE_COPYSIGNF 157 return copysignf(x, y); 158#else 159 return (float)SDL_copysign((double)x, (double)y); 160#endif 161} 162 163double SDL_cos(double x) 164{ 165#ifdef HAVE_COS 166 return cos(x); 167#else 168 return SDL_uclibc_cos(x); 169#endif 170} 171 172float SDL_cosf(float x) 173{ 174#ifdef HAVE_COSF 175 return cosf(x); 176#else 177 return (float)SDL_cos((double)x); 178#endif 179} 180 181double SDL_exp(double x) 182{ 183#ifdef HAVE_EXP 184 return exp(x); 185#else 186 return SDL_uclibc_exp(x); 187#endif 188} 189 190float SDL_expf(float x) 191{ 192#ifdef HAVE_EXPF 193 return expf(x); 194#else 195 return (float)SDL_exp((double)x); 196#endif 197} 198 199double SDL_fabs(double x) 200{ 201#ifdef HAVE_FABS 202 return fabs(x); 203#else 204 return SDL_uclibc_fabs(x); 205#endif 206} 207 208float SDL_fabsf(float x) 209{ 210#ifdef HAVE_FABSF 211 return fabsf(x); 212#else 213 return (float)SDL_fabs((double)x); 214#endif 215} 216 217double SDL_floor(double x) 218{ 219#ifdef HAVE_FLOOR 220 return floor(x); 221#else 222 return SDL_uclibc_floor(x); 223#endif 224} 225 226float SDL_floorf(float x) 227{ 228#ifdef HAVE_FLOORF 229 return floorf(x); 230#else 231 return (float)SDL_floor((double)x); 232#endif 233} 234 235double SDL_trunc(double x) 236{ 237#ifdef HAVE_TRUNC 238 return trunc(x); 239#else 240 if (x >= 0.0f) { 241 return SDL_floor(x); 242 } else { 243 return SDL_ceil(x); 244 } 245#endif 246} 247 248float SDL_truncf(float x) 249{ 250#ifdef HAVE_TRUNCF 251 return truncf(x); 252#else 253 return (float)SDL_trunc((double)x); 254#endif 255} 256 257double SDL_fmod(double x, double y) 258{ 259#ifdef HAVE_FMOD 260 return fmod(x, y); 261#else 262 return SDL_uclibc_fmod(x, y); 263#endif 264} 265 266float SDL_fmodf(float x, float y) 267{ 268#ifdef HAVE_FMODF 269 return fmodf(x, y); 270#else 271 return (float)SDL_fmod((double)x, (double)y); 272#endif 273} 274 275int SDL_isinf(double x) 276{ 277#ifdef HAVE_ISINF 278 return isinf(x); 279#else 280 return SDL_uclibc_isinf(x); 281#endif 282} 283 284int SDL_isinff(float x) 285{ 286#ifdef HAVE_ISINF_FLOAT_MACRO 287 return isinf(x); 288#elif defined(HAVE_ISINFF) 289 return isinff(x); 290#else 291 return SDL_uclibc_isinff(x); 292#endif 293} 294 295int SDL_isnan(double x) 296{ 297#ifdef HAVE_ISNAN 298 return isnan(x); 299#else 300 return SDL_uclibc_isnan(x); 301#endif 302} 303 304int SDL_isnanf(float x) 305{ 306#ifdef HAVE_ISNAN_FLOAT_MACRO 307 return isnan(x); 308#elif defined(HAVE_ISNANF) 309 return isnanf(x); 310#else 311 return SDL_uclibc_isnanf(x); 312#endif 313} 314 315double SDL_log(double x) 316{ 317#ifdef HAVE_LOG 318 return log(x); 319#else 320 return SDL_uclibc_log(x); 321#endif 322} 323 324float SDL_logf(float x) 325{ 326#ifdef HAVE_LOGF 327 return logf(x); 328#else 329 return (float)SDL_log((double)x); 330#endif 331} 332 333double SDL_log10(double x) 334{ 335#ifdef HAVE_LOG10 336 return log10(x); 337#else 338 return SDL_uclibc_log10(x); 339#endif 340} 341 342float SDL_log10f(float x) 343{ 344#ifdef HAVE_LOG10F 345 return log10f(x); 346#else 347 return (float)SDL_log10((double)x); 348#endif 349} 350 351double SDL_modf(double x, double *y) 352{ 353#ifdef HAVE_MODF 354 return modf(x, y); 355#else 356 return SDL_uclibc_modf(x, y); 357#endif 358} 359 360float SDL_modff(float x, float *y) 361{ 362#ifdef HAVE_MODFF 363 return modff(x, y); 364#else 365 double double_result, double_y; 366 double_result = SDL_modf((double)x, &double_y); 367 *y = (float)double_y; 368 return (float)double_result; 369#endif 370} 371 372double SDL_pow(double x, double y) 373{ 374#ifdef HAVE_POW 375 return pow(x, y); 376#else 377 return SDL_uclibc_pow(x, y); 378#endif 379} 380 381float SDL_powf(float x, float y) 382{ 383#ifdef HAVE_POWF 384 return powf(x, y); 385#else 386 return (float)SDL_pow((double)x, (double)y); 387#endif 388} 389 390double SDL_round(double arg) 391{ 392#if defined HAVE_ROUND 393 return round(arg); 394#else 395 if (arg >= 0.0) { 396 return SDL_floor(arg + 0.5); 397 } else { 398 return SDL_ceil(arg - 0.5); 399 } 400#endif 401} 402 403float SDL_roundf(float arg) 404{ 405#if defined HAVE_ROUNDF 406 return roundf(arg); 407#else 408 return (float)SDL_round((double)arg); 409#endif 410} 411 412long SDL_lround(double arg) 413{ 414#if defined HAVE_LROUND 415 return lround(arg); 416#else 417 return (long)SDL_round(arg); 418#endif 419} 420 421long SDL_lroundf(float arg) 422{ 423#if defined HAVE_LROUNDF 424 return lroundf(arg); 425#else 426 return (long)SDL_round((double)arg); 427#endif 428} 429 430double SDL_scalbn(double x, int n) 431{ 432#ifdef HAVE_SCALBN 433 return scalbn(x, n); 434#elif defined(HAVE__SCALB) 435 return _scalb(x, n); 436#elif defined(HAVE_LIBC) && defined(HAVE_FLOAT_H) && (FLT_RADIX == 2) 437 /* from scalbn(3): If FLT_RADIX equals 2 (which is 438 * usual), then scalbn() is equivalent to ldexp(3). */ 439 return ldexp(x, n); 440#else 441 return SDL_uclibc_scalbn(x, n); 442#endif 443} 444 445float SDL_scalbnf(float x, int n) 446{ 447#ifdef HAVE_SCALBNF 448 return scalbnf(x, n); 449#else 450 return (float)SDL_scalbn((double)x, n); 451#endif 452} 453 454double SDL_sin(double x) 455{ 456#ifdef HAVE_SIN 457 return sin(x); 458#else 459 return SDL_uclibc_sin(x); 460#endif 461} 462 463float SDL_sinf(float x) 464{ 465#ifdef HAVE_SINF 466 return sinf(x); 467#else 468 return (float)SDL_sin((double)x); 469#endif 470} 471 472double SDL_sqrt(double x) 473{ 474#ifdef HAVE_SQRT 475 return sqrt(x); 476#else 477 return SDL_uclibc_sqrt(x); 478#endif 479} 480 481float SDL_sqrtf(float x) 482{ 483#ifdef HAVE_SQRTF 484 return sqrtf(x); 485#else 486 return (float)SDL_sqrt((double)x); 487#endif 488} 489 490double SDL_tan(double x) 491{ 492#ifdef HAVE_TAN 493 return tan(x); 494#else 495 return SDL_uclibc_tan(x); 496#endif 497} 498 499float SDL_tanf(float x) 500{ 501#ifdef HAVE_TANF 502 return tanf(x); 503#else 504 return (float)SDL_tan((double)x); 505#endif 506} 507 508int SDL_abs(int x) 509{ 510#ifdef HAVE_ABS 511 return abs(x); 512#else 513 return (x < 0) ? -x : x; 514#endif 515} 516 517int SDL_isalpha(int x) { return (SDL_isupper(x)) || (SDL_islower(x)); } 518int SDL_isalnum(int x) { return (SDL_isalpha(x)) || (SDL_isdigit(x)); } 519int SDL_isdigit(int x) { return ((x) >= '0') && ((x) <= '9'); } 520int SDL_isxdigit(int x) { return (((x) >= 'A') && ((x) <= 'F')) || (((x) >= 'a') && ((x) <= 'f')) || (SDL_isdigit(x)); } 521int SDL_ispunct(int x) { return (SDL_isgraph(x)) && (!SDL_isalnum(x)); } 522int SDL_isspace(int x) { return ((x) == ' ') || ((x) == '\t') || ((x) == '\r') || ((x) == '\n') || ((x) == '\f') || ((x) == '\v'); } 523int SDL_isupper(int x) { return ((x) >= 'A') && ((x) <= 'Z'); } 524int SDL_islower(int x) { return ((x) >= 'a') && ((x) <= 'z'); } 525int SDL_isprint(int x) { return ((x) >= ' ') && ((x) < '\x7f'); } 526int SDL_isgraph(int x) { return (SDL_isprint(x)) && ((x) != ' '); } 527int SDL_iscntrl(int x) { return (((x) >= '\0') && ((x) <= '\x1f')) || ((x) == '\x7f'); } 528int SDL_toupper(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A' + ((x) - 'a')) : (x); } 529int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a' + ((x) - 'A')) : (x); } 530int SDL_isblank(int x) { return ((x) == ' ') || ((x) == '\t'); } 531 532void *SDL_aligned_alloc(size_t alignment, size_t size) 533{ 534 size_t padding; 535 Uint8 *result = NULL; 536 537 if (alignment < sizeof(void*)) { 538 alignment = sizeof(void*); 539 } 540 padding = (alignment - (size % alignment)); 541 542 if (SDL_size_add_check_overflow(size, alignment, &size) && 543 SDL_size_add_check_overflow(size, sizeof(void *), &size) && 544 SDL_size_add_check_overflow(size, padding, &size)) { 545 void *original = SDL_malloc(size); 546 if (original) { 547 // Make sure we have enough space to store the original pointer 548 result = (Uint8 *)original + sizeof(original); 549 550 // Align the pointer we're going to return 551 result += alignment - (((size_t)result) % alignment); 552 553 // Store the original pointer right before the returned value 554 SDL_memcpy(result - sizeof(original), &original, sizeof(original)); 555 } 556 } 557 return result; 558} 559 560void SDL_aligned_free(void *mem) 561{ 562 if (mem) { 563 void *original; 564 SDL_memcpy(&original, ((Uint8 *)mem - sizeof(original)), sizeof(original)); 565 SDL_free(original); 566 } 567}