SDL_stdlib.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2026 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. #else
  128. return SDL_uclibc_copysign(x, y);
  129. #endif // HAVE_COPYSIGN
  130. }
  131. float SDL_copysignf(float x, float y)
  132. {
  133. #ifdef HAVE_COPYSIGNF
  134. return copysignf(x, y);
  135. #else
  136. return (float)SDL_copysign((double)x, (double)y);
  137. #endif
  138. }
  139. double SDL_cos(double x)
  140. {
  141. #ifdef HAVE_COS
  142. return cos(x);
  143. #else
  144. return SDL_uclibc_cos(x);
  145. #endif
  146. }
  147. float SDL_cosf(float x)
  148. {
  149. #ifdef HAVE_COSF
  150. return cosf(x);
  151. #else
  152. return (float)SDL_cos((double)x);
  153. #endif
  154. }
  155. double SDL_exp(double x)
  156. {
  157. #ifdef HAVE_EXP
  158. return exp(x);
  159. #else
  160. return SDL_uclibc_exp(x);
  161. #endif
  162. }
  163. float SDL_expf(float x)
  164. {
  165. #ifdef HAVE_EXPF
  166. return expf(x);
  167. #else
  168. return (float)SDL_exp((double)x);
  169. #endif
  170. }
  171. double SDL_fabs(double x)
  172. {
  173. #ifdef HAVE_FABS
  174. return fabs(x);
  175. #else
  176. return SDL_uclibc_fabs(x);
  177. #endif
  178. }
  179. float SDL_fabsf(float x)
  180. {
  181. #ifdef HAVE_FABSF
  182. return fabsf(x);
  183. #else
  184. return (float)SDL_fabs((double)x);
  185. #endif
  186. }
  187. double SDL_floor(double x)
  188. {
  189. #ifdef HAVE_FLOOR
  190. return floor(x);
  191. #else
  192. return SDL_uclibc_floor(x);
  193. #endif
  194. }
  195. float SDL_floorf(float x)
  196. {
  197. #ifdef HAVE_FLOORF
  198. return floorf(x);
  199. #else
  200. return (float)SDL_floor((double)x);
  201. #endif
  202. }
  203. double SDL_trunc(double x)
  204. {
  205. #ifdef HAVE_TRUNC
  206. return trunc(x);
  207. #else
  208. if (x >= 0.0f) {
  209. return SDL_floor(x);
  210. } else {
  211. return SDL_ceil(x);
  212. }
  213. #endif
  214. }
  215. float SDL_truncf(float x)
  216. {
  217. #ifdef HAVE_TRUNCF
  218. return truncf(x);
  219. #else
  220. return (float)SDL_trunc((double)x);
  221. #endif
  222. }
  223. double SDL_fmod(double x, double y)
  224. {
  225. #ifdef HAVE_FMOD
  226. return fmod(x, y);
  227. #else
  228. return SDL_uclibc_fmod(x, y);
  229. #endif
  230. }
  231. float SDL_fmodf(float x, float y)
  232. {
  233. #ifdef HAVE_FMODF
  234. return fmodf(x, y);
  235. #else
  236. return (float)SDL_fmod((double)x, (double)y);
  237. #endif
  238. }
  239. int SDL_isinf(double x)
  240. {
  241. #ifdef HAVE_ISINF
  242. return isinf(x);
  243. #else
  244. return SDL_uclibc_isinf(x);
  245. #endif
  246. }
  247. int SDL_isinff(float x)
  248. {
  249. #ifdef HAVE_ISINF_FLOAT_MACRO
  250. return isinf(x);
  251. #elif defined(HAVE_ISINFF)
  252. return isinff(x);
  253. #else
  254. return SDL_uclibc_isinff(x);
  255. #endif
  256. }
  257. int SDL_isnan(double x)
  258. {
  259. #ifdef HAVE_ISNAN
  260. return isnan(x);
  261. #else
  262. return SDL_uclibc_isnan(x);
  263. #endif
  264. }
  265. int SDL_isnanf(float x)
  266. {
  267. #ifdef HAVE_ISNAN_FLOAT_MACRO
  268. return isnan(x);
  269. #elif defined(HAVE_ISNANF)
  270. return isnanf(x);
  271. #else
  272. return SDL_uclibc_isnanf(x);
  273. #endif
  274. }
  275. double SDL_log(double x)
  276. {
  277. #ifdef HAVE_LOG
  278. return log(x);
  279. #else
  280. return SDL_uclibc_log(x);
  281. #endif
  282. }
  283. float SDL_logf(float x)
  284. {
  285. #ifdef HAVE_LOGF
  286. return logf(x);
  287. #else
  288. return (float)SDL_log((double)x);
  289. #endif
  290. }
  291. double SDL_log10(double x)
  292. {
  293. #ifdef HAVE_LOG10
  294. return log10(x);
  295. #else
  296. return SDL_uclibc_log10(x);
  297. #endif
  298. }
  299. float SDL_log10f(float x)
  300. {
  301. #ifdef HAVE_LOG10F
  302. return log10f(x);
  303. #else
  304. return (float)SDL_log10((double)x);
  305. #endif
  306. }
  307. double SDL_modf(double x, double *y)
  308. {
  309. #ifdef HAVE_MODF
  310. return modf(x, y);
  311. #else
  312. return SDL_uclibc_modf(x, y);
  313. #endif
  314. }
  315. float SDL_modff(float x, float *y)
  316. {
  317. #ifdef HAVE_MODFF
  318. return modff(x, y);
  319. #else
  320. double double_result, double_y;
  321. double_result = SDL_modf((double)x, &double_y);
  322. *y = (float)double_y;
  323. return (float)double_result;
  324. #endif
  325. }
  326. double SDL_pow(double x, double y)
  327. {
  328. #ifdef HAVE_POW
  329. return pow(x, y);
  330. #else
  331. return SDL_uclibc_pow(x, y);
  332. #endif
  333. }
  334. float SDL_powf(float x, float y)
  335. {
  336. #ifdef HAVE_POWF
  337. return powf(x, y);
  338. #else
  339. return (float)SDL_pow((double)x, (double)y);
  340. #endif
  341. }
  342. double SDL_round(double arg)
  343. {
  344. #if defined HAVE_ROUND
  345. return round(arg);
  346. #else
  347. if (arg >= 0.0) {
  348. return SDL_floor(arg + 0.5);
  349. } else {
  350. return SDL_ceil(arg - 0.5);
  351. }
  352. #endif
  353. }
  354. float SDL_roundf(float arg)
  355. {
  356. #if defined HAVE_ROUNDF
  357. return roundf(arg);
  358. #else
  359. return (float)SDL_round((double)arg);
  360. #endif
  361. }
  362. long SDL_lround(double arg)
  363. {
  364. #if defined HAVE_LROUND
  365. return lround(arg);
  366. #else
  367. return (long)SDL_round(arg);
  368. #endif
  369. }
  370. long SDL_lroundf(float arg)
  371. {
  372. #if defined HAVE_LROUNDF
  373. return lroundf(arg);
  374. #else
  375. return (long)SDL_round((double)arg);
  376. #endif
  377. }
  378. double SDL_scalbn(double x, int n)
  379. {
  380. #ifdef HAVE_SCALBN
  381. return scalbn(x, n);
  382. #elif defined(HAVE__SCALB)
  383. return _scalb(x, n);
  384. #elif defined(HAVE_LIBC) && defined(HAVE_FLOAT_H) && (FLT_RADIX == 2)
  385. /* from scalbn(3): If FLT_RADIX equals 2 (which is
  386. * usual), then scalbn() is equivalent to ldexp(3). */
  387. return ldexp(x, n);
  388. #else
  389. return SDL_uclibc_scalbn(x, n);
  390. #endif
  391. }
  392. float SDL_scalbnf(float x, int n)
  393. {
  394. #ifdef HAVE_SCALBNF
  395. return scalbnf(x, n);
  396. #else
  397. return (float)SDL_scalbn((double)x, n);
  398. #endif
  399. }
  400. double SDL_sin(double x)
  401. {
  402. #ifdef HAVE_SIN
  403. return sin(x);
  404. #else
  405. return SDL_uclibc_sin(x);
  406. #endif
  407. }
  408. float SDL_sinf(float x)
  409. {
  410. #ifdef HAVE_SINF
  411. return sinf(x);
  412. #else
  413. return (float)SDL_sin((double)x);
  414. #endif
  415. }
  416. double SDL_sqrt(double x)
  417. {
  418. #ifdef HAVE_SQRT
  419. return sqrt(x);
  420. #else
  421. return SDL_uclibc_sqrt(x);
  422. #endif
  423. }
  424. float SDL_sqrtf(float x)
  425. {
  426. #ifdef HAVE_SQRTF
  427. return sqrtf(x);
  428. #else
  429. return (float)SDL_sqrt((double)x);
  430. #endif
  431. }
  432. double SDL_tan(double x)
  433. {
  434. #ifdef HAVE_TAN
  435. return tan(x);
  436. #else
  437. return SDL_uclibc_tan(x);
  438. #endif
  439. }
  440. float SDL_tanf(float x)
  441. {
  442. #ifdef HAVE_TANF
  443. return tanf(x);
  444. #else
  445. return (float)SDL_tan((double)x);
  446. #endif
  447. }
  448. int SDL_abs(int x)
  449. {
  450. #ifdef HAVE_ABS
  451. return abs(x);
  452. #else
  453. return (x < 0) ? -x : x;
  454. #endif
  455. }
  456. int SDL_isalpha(int x) { return (SDL_isupper(x)) || (SDL_islower(x)); }
  457. int SDL_isalnum(int x) { return (SDL_isalpha(x)) || (SDL_isdigit(x)); }
  458. int SDL_isdigit(int x) { return ((x) >= '0') && ((x) <= '9'); }
  459. int SDL_isxdigit(int x) { return (((x) >= 'A') && ((x) <= 'F')) || (((x) >= 'a') && ((x) <= 'f')) || (SDL_isdigit(x)); }
  460. int SDL_ispunct(int x) { return (SDL_isgraph(x)) && (!SDL_isalnum(x)); }
  461. int SDL_isspace(int x) { return ((x) == ' ') || ((x) == '\t') || ((x) == '\r') || ((x) == '\n') || ((x) == '\f') || ((x) == '\v'); }
  462. int SDL_isupper(int x) { return ((x) >= 'A') && ((x) <= 'Z'); }
  463. int SDL_islower(int x) { return ((x) >= 'a') && ((x) <= 'z'); }
  464. int SDL_isprint(int x) { return ((x) >= ' ') && ((x) < '\x7f'); }
  465. int SDL_isgraph(int x) { return (SDL_isprint(x)) && ((x) != ' '); }
  466. int SDL_iscntrl(int x) { return (((x) >= '\0') && ((x) <= '\x1f')) || ((x) == '\x7f'); }
  467. int SDL_toupper(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A' + ((x) - 'a')) : (x); }
  468. int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a' + ((x) - 'A')) : (x); }
  469. int SDL_isblank(int x) { return ((x) == ' ') || ((x) == '\t'); }
  470. void *SDL_aligned_alloc(size_t alignment, size_t size)
  471. {
  472. size_t padding;
  473. Uint8 *result = NULL;
  474. size_t requested_size = size;
  475. if (alignment < sizeof(void *)) {
  476. alignment = sizeof(void *);
  477. }
  478. padding = (alignment - (size % alignment));
  479. if (SDL_size_add_check_overflow(size, alignment, &size) &&
  480. SDL_size_add_check_overflow(size, sizeof(void *), &size) &&
  481. SDL_size_add_check_overflow(size, padding, &size)) {
  482. void *original = SDL_malloc(size);
  483. if (original) {
  484. // Make sure we have enough space to store the original pointer
  485. result = (Uint8 *)original + sizeof(original);
  486. // Align the pointer we're going to return
  487. result += alignment - (((size_t)result) % alignment);
  488. // Store the original pointer right before the returned value
  489. SDL_memcpy(result - sizeof(original), &original, sizeof(original));
  490. // Initialize the padding to zero
  491. if (padding > 0) {
  492. SDL_memset(result + requested_size, 0, padding);
  493. }
  494. }
  495. }
  496. return result;
  497. }
  498. void SDL_aligned_free(void *mem)
  499. {
  500. if (mem) {
  501. void *original;
  502. SDL_memcpy(&original, ((Uint8 *)mem - sizeof(original)), sizeof(original));
  503. SDL_free(original);
  504. }
  505. }