SDL_stdlib.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2022 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. #if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS)
  19. #define SDL_DISABLE_ANALYZE_MACROS 1
  20. #endif
  21. #include "../SDL_internal.h"
  22. /* This file contains portable stdlib functions for SDL */
  23. #include "SDL_stdinc.h"
  24. #include "../libm/math_libm.h"
  25. double
  26. SDL_atan(double x)
  27. {
  28. #if defined(HAVE_ATAN)
  29. return atan(x);
  30. #else
  31. return SDL_uclibc_atan(x);
  32. #endif
  33. }
  34. float
  35. SDL_atanf(float x)
  36. {
  37. #if defined(HAVE_ATANF)
  38. return atanf(x);
  39. #else
  40. return (float)SDL_atan((double)x);
  41. #endif
  42. }
  43. double
  44. SDL_atan2(double y, double x)
  45. {
  46. #if defined(HAVE_ATAN2)
  47. return atan2(y, x);
  48. #else
  49. return SDL_uclibc_atan2(y, x);
  50. #endif
  51. }
  52. float
  53. SDL_atan2f(float y, float x)
  54. {
  55. #if defined(HAVE_ATAN2F)
  56. return atan2f(y, x);
  57. #else
  58. return (float)SDL_atan2((double)y, (double)x);
  59. #endif
  60. }
  61. double
  62. SDL_acos(double val)
  63. {
  64. #if defined(HAVE_ACOS)
  65. return acos(val);
  66. #else
  67. double result;
  68. if (val == -1.0) {
  69. result = M_PI;
  70. } else {
  71. result = SDL_atan(SDL_sqrt(1.0 - val * val) / val);
  72. if (result < 0.0)
  73. {
  74. result += M_PI;
  75. }
  76. }
  77. return result;
  78. #endif
  79. }
  80. float
  81. SDL_acosf(float val)
  82. {
  83. #if defined(HAVE_ACOSF)
  84. return acosf(val);
  85. #else
  86. return (float)SDL_acos((double)val);
  87. #endif
  88. }
  89. double
  90. SDL_asin(double val)
  91. {
  92. #if defined(HAVE_ASIN)
  93. return asin(val);
  94. #else
  95. double result;
  96. if (val == -1.0) {
  97. result = -(M_PI / 2.0);
  98. } else {
  99. result = (M_PI / 2.0) - SDL_acos(val);
  100. }
  101. return result;
  102. #endif
  103. }
  104. float
  105. SDL_asinf(float val)
  106. {
  107. #if defined(HAVE_ASINF)
  108. return asinf(val);
  109. #else
  110. return (float)SDL_asin((double)val);
  111. #endif
  112. }
  113. double
  114. SDL_ceil(double x)
  115. {
  116. #if defined(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. float
  128. SDL_ceilf(float x)
  129. {
  130. #if defined(HAVE_CEILF)
  131. return ceilf(x);
  132. #else
  133. return (float)SDL_ceil((double)x);
  134. #endif
  135. }
  136. double
  137. SDL_copysign(double x, double y)
  138. {
  139. #if defined(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. float
  154. SDL_copysignf(float x, float y)
  155. {
  156. #if defined(HAVE_COPYSIGNF)
  157. return copysignf(x, y);
  158. #else
  159. return (float)SDL_copysign((double)x, (double)y);
  160. #endif
  161. }
  162. double
  163. SDL_cos(double x)
  164. {
  165. #if defined(HAVE_COS)
  166. return cos(x);
  167. #else
  168. return SDL_uclibc_cos(x);
  169. #endif
  170. }
  171. float
  172. SDL_cosf(float x)
  173. {
  174. #if defined(HAVE_COSF)
  175. return cosf(x);
  176. #else
  177. return (float)SDL_cos((double)x);
  178. #endif
  179. }
  180. double
  181. SDL_exp(double x)
  182. {
  183. #if defined(HAVE_EXP)
  184. return exp(x);
  185. #else
  186. return SDL_uclibc_exp(x);
  187. #endif
  188. }
  189. float
  190. SDL_expf(float x)
  191. {
  192. #if defined(HAVE_EXPF)
  193. return expf(x);
  194. #else
  195. return (float)SDL_exp((double)x);
  196. #endif
  197. }
  198. double
  199. SDL_fabs(double x)
  200. {
  201. #if defined(HAVE_FABS)
  202. return fabs(x);
  203. #else
  204. return SDL_uclibc_fabs(x);
  205. #endif
  206. }
  207. float
  208. SDL_fabsf(float x)
  209. {
  210. #if defined(HAVE_FABSF)
  211. return fabsf(x);
  212. #else
  213. return (float)SDL_fabs((double)x);
  214. #endif
  215. }
  216. double
  217. SDL_floor(double x)
  218. {
  219. #if defined(HAVE_FLOOR)
  220. return floor(x);
  221. #else
  222. return SDL_uclibc_floor(x);
  223. #endif
  224. }
  225. float
  226. SDL_floorf(float x)
  227. {
  228. #if defined(HAVE_FLOORF)
  229. return floorf(x);
  230. #else
  231. return (float)SDL_floor((double)x);
  232. #endif
  233. }
  234. double
  235. SDL_trunc(double x)
  236. {
  237. #if defined(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. float
  248. SDL_truncf(float x)
  249. {
  250. #if defined(HAVE_TRUNCF)
  251. return truncf(x);
  252. #else
  253. return (float)SDL_trunc((double)x);
  254. #endif
  255. }
  256. double
  257. SDL_fmod(double x, double y)
  258. {
  259. #if defined(HAVE_FMOD)
  260. return fmod(x, y);
  261. #else
  262. return SDL_uclibc_fmod(x, y);
  263. #endif
  264. }
  265. float
  266. SDL_fmodf(float x, float y)
  267. {
  268. #if defined(HAVE_FMODF)
  269. return fmodf(x, y);
  270. #else
  271. return (float)SDL_fmod((double)x, (double)y);
  272. #endif
  273. }
  274. double
  275. SDL_log(double x)
  276. {
  277. #if defined(HAVE_LOG)
  278. return log(x);
  279. #else
  280. return SDL_uclibc_log(x);
  281. #endif
  282. }
  283. float
  284. SDL_logf(float x)
  285. {
  286. #if defined(HAVE_LOGF)
  287. return logf(x);
  288. #else
  289. return (float)SDL_log((double)x);
  290. #endif
  291. }
  292. double
  293. SDL_log10(double x)
  294. {
  295. #if defined(HAVE_LOG10)
  296. return log10(x);
  297. #else
  298. return SDL_uclibc_log10(x);
  299. #endif
  300. }
  301. float
  302. SDL_log10f(float x)
  303. {
  304. #if defined(HAVE_LOG10F)
  305. return log10f(x);
  306. #else
  307. return (float)SDL_log10((double)x);
  308. #endif
  309. }
  310. double
  311. SDL_pow(double x, double y)
  312. {
  313. #if defined(HAVE_POW)
  314. return pow(x, y);
  315. #else
  316. return SDL_uclibc_pow(x, y);
  317. #endif
  318. }
  319. float
  320. SDL_powf(float x, float y)
  321. {
  322. #if defined(HAVE_POWF)
  323. return powf(x, y);
  324. #else
  325. return (float)SDL_pow((double)x, (double)y);
  326. #endif
  327. }
  328. double
  329. SDL_round(double arg)
  330. {
  331. #if defined HAVE_ROUND
  332. return round(arg);
  333. #else
  334. if (arg >= 0.0) {
  335. return SDL_floor(arg + 0.5);
  336. } else {
  337. return SDL_ceil(arg - 0.5);
  338. }
  339. #endif
  340. }
  341. float
  342. SDL_roundf(float arg)
  343. {
  344. #if defined HAVE_ROUNDF
  345. return roundf(arg);
  346. #else
  347. return (float)SDL_round((double)arg);
  348. #endif
  349. }
  350. long
  351. SDL_lround(double arg)
  352. {
  353. #if defined HAVE_LROUND
  354. return lround(arg);
  355. #else
  356. return (long)SDL_round(arg);
  357. #endif
  358. }
  359. long
  360. SDL_lroundf(float arg)
  361. {
  362. #if defined HAVE_LROUNDF
  363. return lroundf(arg);
  364. #else
  365. return (long)SDL_round((double)arg);
  366. #endif
  367. }
  368. double
  369. SDL_scalbn(double x, int n)
  370. {
  371. #if defined(HAVE_SCALBN)
  372. return scalbn(x, n);
  373. #elif defined(HAVE__SCALB)
  374. return _scalb(x, n);
  375. #elif defined(HAVE_LIBC) && defined(HAVE_FLOAT_H) && (FLT_RADIX == 2)
  376. /* from scalbn(3): If FLT_RADIX equals 2 (which is
  377. * usual), then scalbn() is equivalent to ldexp(3). */
  378. return ldexp(x, n);
  379. #else
  380. return SDL_uclibc_scalbn(x, n);
  381. #endif
  382. }
  383. float
  384. SDL_scalbnf(float x, int n)
  385. {
  386. #if defined(HAVE_SCALBNF)
  387. return scalbnf(x, n);
  388. #else
  389. return (float)SDL_scalbn((double)x, n);
  390. #endif
  391. }
  392. double
  393. SDL_sin(double x)
  394. {
  395. #if defined(HAVE_SIN)
  396. return sin(x);
  397. #else
  398. return SDL_uclibc_sin(x);
  399. #endif
  400. }
  401. float
  402. SDL_sinf(float x)
  403. {
  404. #if defined(HAVE_SINF)
  405. return sinf(x);
  406. #else
  407. return (float)SDL_sin((double)x);
  408. #endif
  409. }
  410. double
  411. SDL_sqrt(double x)
  412. {
  413. #if defined(HAVE_SQRT)
  414. return sqrt(x);
  415. #else
  416. return SDL_uclibc_sqrt(x);
  417. #endif
  418. }
  419. float
  420. SDL_sqrtf(float x)
  421. {
  422. #if defined(HAVE_SQRTF)
  423. return sqrtf(x);
  424. #else
  425. return (float)SDL_sqrt((double)x);
  426. #endif
  427. }
  428. double
  429. SDL_tan(double x)
  430. {
  431. #if defined(HAVE_TAN)
  432. return tan(x);
  433. #else
  434. return SDL_uclibc_tan(x);
  435. #endif
  436. }
  437. float
  438. SDL_tanf(float x)
  439. {
  440. #if defined(HAVE_TANF)
  441. return tanf(x);
  442. #else
  443. return (float)SDL_tan((double)x);
  444. #endif
  445. }
  446. int SDL_abs(int x)
  447. {
  448. #if defined(HAVE_ABS)
  449. return abs(x);
  450. #else
  451. return (x < 0) ? -x : x;
  452. #endif
  453. }
  454. #if defined(HAVE_CTYPE_H)
  455. int SDL_isalpha(int x) { return isalpha(x); }
  456. int SDL_isalnum(int x) { return isalnum(x); }
  457. int SDL_isdigit(int x) { return isdigit(x); }
  458. int SDL_isxdigit(int x) { return isxdigit(x); }
  459. int SDL_ispunct(int x) { return ispunct(x); }
  460. int SDL_isspace(int x) { return isspace(x); }
  461. int SDL_isupper(int x) { return isupper(x); }
  462. int SDL_islower(int x) { return islower(x); }
  463. int SDL_isprint(int x) { return isprint(x); }
  464. int SDL_isgraph(int x) { return isgraph(x); }
  465. int SDL_iscntrl(int x) { return iscntrl(x); }
  466. int SDL_toupper(int x) { return toupper(x); }
  467. int SDL_tolower(int x) { return tolower(x); }
  468. #else
  469. int SDL_isalpha(int x) { return (SDL_isupper(x)) || (SDL_islower(x)); }
  470. int SDL_isalnum(int x) { return (SDL_isalpha(x)) || (SDL_isdigit(x)); }
  471. int SDL_isdigit(int x) { return ((x) >= '0') && ((x) <= '9'); }
  472. int SDL_isxdigit(int x) { return (((x) >= 'A') && ((x) <= 'F')) || (((x) >= 'a') && ((x) <= 'f')) || (SDL_isdigit(x)); }
  473. int SDL_ispunct(int x) { return (SDL_isgraph(x)) && (!SDL_isalnum(x)); }
  474. int SDL_isspace(int x) { return ((x) == ' ') || ((x) == '\t') || ((x) == '\r') || ((x) == '\n') || ((x) == '\f') || ((x) == '\v'); }
  475. int SDL_isupper(int x) { return ((x) >= 'A') && ((x) <= 'Z'); }
  476. int SDL_islower(int x) { return ((x) >= 'a') && ((x) <= 'z'); }
  477. int SDL_isprint(int x) { return ((x) >= ' ') && ((x) < '\x7f'); }
  478. int SDL_isgraph(int x) { return (SDL_isprint(x)) && ((x) != ' '); }
  479. int SDL_iscntrl(int x) { return (((x) >= '\0') && ((x) <= '\x1f')) || ((x) == '\x7f'); }
  480. int SDL_toupper(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A'+((x)-'a')) : (x); }
  481. int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a'+((x)-'A')) : (x); }
  482. #endif
  483. /* This file contains a portable memcpy manipulation function for SDL */
  484. void *
  485. SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len)
  486. {
  487. #ifdef __GNUC__
  488. /* Presumably this is well tuned for speed.
  489. On my machine this is twice as fast as the C code below.
  490. */
  491. return __builtin_memcpy(dst, src, len);
  492. #elif defined(HAVE_MEMCPY)
  493. return memcpy(dst, src, len);
  494. #elif defined(HAVE_BCOPY)
  495. bcopy(src, dst, len);
  496. return dst;
  497. #else
  498. /* GCC 4.9.0 with -O3 will generate movaps instructions with the loop
  499. using Uint32* pointers, so we need to make sure the pointers are
  500. aligned before we loop using them.
  501. */
  502. if (((uintptr_t)src & 0x3) || ((uintptr_t)dst & 0x3)) {
  503. /* Do an unaligned byte copy */
  504. Uint8 *srcp1 = (Uint8 *)src;
  505. Uint8 *dstp1 = (Uint8 *)dst;
  506. while (len--) {
  507. *dstp1++ = *srcp1++;
  508. }
  509. } else {
  510. size_t left = (len % 4);
  511. Uint32 *srcp4, *dstp4;
  512. Uint8 *srcp1, *dstp1;
  513. srcp4 = (Uint32 *) src;
  514. dstp4 = (Uint32 *) dst;
  515. len /= 4;
  516. while (len--) {
  517. *dstp4++ = *srcp4++;
  518. }
  519. srcp1 = (Uint8 *) srcp4;
  520. dstp1 = (Uint8 *) dstp4;
  521. switch (left) {
  522. case 3:
  523. *dstp1++ = *srcp1++;
  524. case 2:
  525. *dstp1++ = *srcp1++;
  526. case 1:
  527. *dstp1++ = *srcp1++;
  528. }
  529. }
  530. return dst;
  531. #endif /* __GNUC__ */
  532. }
  533. void *
  534. SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len)
  535. {
  536. #if defined(HAVE_MEMSET)
  537. return memset(dst, c, len);
  538. #else
  539. size_t left;
  540. Uint32 *dstp4;
  541. Uint8 *dstp1 = (Uint8 *) dst;
  542. Uint8 value1;
  543. Uint32 value4;
  544. /* The value used in memset() is a byte, passed as an int */
  545. c &= 0xff;
  546. /* The destination pointer needs to be aligned on a 4-byte boundary to
  547. * execute a 32-bit set. Set first bytes manually if needed until it is
  548. * aligned. */
  549. value1 = (Uint8)c;
  550. while ((uintptr_t)dstp1 & 0x3) {
  551. if (len--) {
  552. *dstp1++ = value1;
  553. } else {
  554. return dst;
  555. }
  556. }
  557. value4 = ((Uint32)c | ((Uint32)c << 8) | ((Uint32)c << 16) | ((Uint32)c << 24));
  558. dstp4 = (Uint32 *) dstp1;
  559. left = (len % 4);
  560. len /= 4;
  561. while (len--) {
  562. *dstp4++ = value4;
  563. }
  564. dstp1 = (Uint8 *) dstp4;
  565. switch (left) {
  566. case 3:
  567. *dstp1++ = value1;
  568. case 2:
  569. *dstp1++ = value1;
  570. case 1:
  571. *dstp1++ = value1;
  572. }
  573. return dst;
  574. #endif /* HAVE_MEMSET */
  575. }
  576. #if defined(HAVE_CTYPE_H) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
  577. int SDL_isblank(int x) { return isblank(x); }
  578. #else
  579. int SDL_isblank(int x) { return ((x) == ' ') || ((x) == '\t'); }
  580. #endif
  581. /* vi: set ts=4 sw=4 expandtab: */