SDL_stdlib.c 11 KB

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