1 module allegro5.fixed; 2 3 import allegro5.error; 4 5 version (Tango) 6 { 7 import tango.stdc.errno; 8 } 9 else 10 { 11 version(D_Version2) 12 { 13 import core.stdc.errno; 14 } 15 else 16 { 17 import std.c.stdlib; 18 // Phobos doesn't define EDOM 19 enum { EDOM = 33 } 20 } 21 } 22 23 extern (C) 24 { 25 alias int al_fixed; 26 27 const al_fixed al_fixtorad_r = cast(al_fixed)1608; 28 const al_fixed al_radtofix_r = cast(al_fixed)2670177; 29 30 al_fixed al_fixsqrt(al_fixed x); 31 al_fixed al_fixhypot(al_fixed x, al_fixed y); 32 al_fixed al_fixatan(al_fixed x); 33 al_fixed al_fixatan2(al_fixed y, al_fixed x); 34 35 al_fixed al_ftofix(double x) 36 { 37 if (x > 32767.0) 38 { 39 al_set_errno(ERANGE); 40 return 0x7FFFFFFF; 41 } 42 43 if (x < -32767.0) 44 { 45 al_set_errno(ERANGE); 46 return -0x7FFFFFFF; 47 } 48 49 return cast(al_fixed)(x * 65536.0 + (x < 0 ? -0.5 : 0.5)); 50 } 51 52 double al_fixtof(al_fixed x) 53 { 54 return cast(double)x / 65536.0; 55 } 56 57 al_fixed al_fixadd(al_fixed x, al_fixed y) 58 { 59 al_fixed result = x + y; 60 61 if (result >= 0) 62 { 63 if ((x < 0) && (y < 0)) 64 { 65 al_set_errno(ERANGE); 66 return -0x7FFFFFFF; 67 } 68 else 69 return result; 70 } 71 else { 72 if ((x > 0) && (y > 0)) 73 { 74 al_set_errno(ERANGE); 75 return 0x7FFFFFFF; 76 } 77 else 78 return result; 79 } 80 } 81 82 83 al_fixed al_fixsub(al_fixed x, al_fixed y) 84 { 85 al_fixed result = x - y; 86 87 if (result >= 0) 88 { 89 if ((x < 0) && (y > 0)) 90 { 91 al_set_errno(ERANGE); 92 return -0x7FFFFFFF; 93 } 94 else 95 return result; 96 } 97 else 98 { 99 if ((x > 0) && (y < 0)) 100 { 101 al_set_errno(ERANGE); 102 return 0x7FFFFFFF; 103 } 104 else 105 return result; 106 } 107 } 108 109 al_fixed al_fixmul(al_fixed x, al_fixed y) 110 { 111 long lx = x; 112 long ly = y; 113 long lres = (lx*ly); 114 115 if (lres > 0x7FFFFFFF0000L) 116 { 117 al_set_errno(ERANGE); 118 return 0x7FFFFFFF; 119 } 120 else if (lres < -0x7FFFFFFF0000L) 121 { 122 al_set_errno(ERANGE); 123 return 0x80000000; 124 } 125 else 126 { 127 int res = cast(int)(lres >> 16); 128 return cast(al_fixed)res; 129 } 130 } 131 132 al_fixed al_fixdiv(al_fixed x, al_fixed y) 133 { 134 long lres = x; 135 if (y == 0) 136 { 137 al_set_errno(ERANGE); 138 return (x < 0) ? -0x7FFFFFFF : 0x7FFFFFFF; 139 } 140 lres <<= 16; 141 lres /= y; 142 if (lres > 0x7FFFFFFF) 143 { 144 al_set_errno(ERANGE); 145 return 0x7FFFFFFF; 146 } 147 else if (lres < -0x7FFFFFFF) 148 { 149 al_set_errno(ERANGE); 150 return 0x80000000; 151 } 152 else 153 { 154 return cast(al_fixed)(lres); 155 } 156 } 157 158 int al_fixfloor(al_fixed x) 159 { 160 /* (x >> 16) is not portable */ 161 if (x >= 0) 162 return (x >> 16); 163 else 164 return ~((~x) >> 16); 165 } 166 167 168 int al_fixceil(al_fixed x) 169 { 170 if (x > 0x7FFF0000) 171 { 172 al_set_errno(ERANGE); 173 return 0x7FFF; 174 } 175 176 return al_fixfloor(cast(al_fixed)(x + 0xFFFF)); 177 } 178 179 al_fixed al_itofix(int x) 180 { 181 return cast(al_fixed)(x << 16); 182 } 183 184 int al_fixtoi(al_fixed x) 185 { 186 return al_fixfloor(x) + ((x & 0x8000) >> 15); 187 } 188 189 al_fixed al_fixcos(al_fixed x) 190 { 191 return _al_fix_cos_tbl[((x + 0x4000) >> 15) & 0x1FF]; 192 } 193 194 al_fixed al_fixsin(al_fixed x) 195 { 196 return _al_fix_cos_tbl[((x - 0x400000 + 0x4000) >> 15) & 0x1FF]; 197 } 198 199 al_fixed al_fixtan(al_fixed x) 200 { 201 return _al_fix_tan_tbl[((x + 0x4000) >> 15) & 0xFF]; 202 } 203 204 al_fixed al_fixacos(al_fixed x) 205 { 206 if ((x < -65536) || (x > 65536)) 207 { 208 al_set_errno(EDOM); 209 return 0; 210 } 211 212 return _al_fix_acos_tbl[(x+65536+127)>>8]; 213 } 214 215 al_fixed al_fixasin(al_fixed x) 216 { 217 if ((x < -65536) || (x > 65536)) 218 { 219 al_set_errno(EDOM); 220 return 0; 221 } 222 223 return cast(al_fixed)(0x00400000 - _al_fix_acos_tbl[(x+65536+127)>>8]); 224 } 225 226 227 private const(al_fixed[512]) _al_fix_cos_tbl = 228 [ 229 /* precalculated fixed point (16.16) cosines for a full circle (0-255) */ 230 231 65536, 65531, 65516, 65492, 65457, 65413, 65358, 65294, 232 65220, 65137, 65043, 64940, 64827, 64704, 64571, 64429, 233 64277, 64115, 63944, 63763, 63572, 63372, 63162, 62943, 234 62714, 62476, 62228, 61971, 61705, 61429, 61145, 60851, 235 60547, 60235, 59914, 59583, 59244, 58896, 58538, 58172, 236 57798, 57414, 57022, 56621, 56212, 55794, 55368, 54934, 237 54491, 54040, 53581, 53114, 52639, 52156, 51665, 51166, 238 50660, 50146, 49624, 49095, 48559, 48015, 47464, 46906, 239 46341, 45769, 45190, 44604, 44011, 43412, 42806, 42194, 240 41576, 40951, 40320, 39683, 39040, 38391, 37736, 37076, 241 36410, 35738, 35062, 34380, 33692, 33000, 32303, 31600, 242 30893, 30182, 29466, 28745, 28020, 27291, 26558, 25821, 243 25080, 24335, 23586, 22834, 22078, 21320, 20557, 19792, 244 19024, 18253, 17479, 16703, 15924, 15143, 14359, 13573, 245 12785, 11996, 11204, 10411, 9616, 8820, 8022, 7224, 246 6424, 5623, 4821, 4019, 3216, 2412, 1608, 804, 247 0, -804, -1608, -2412, -3216, -4019, -4821, -5623, 248 -6424, -7224, -8022, -8820, -9616, -10411, -11204, -11996, 249 -12785, -13573, -14359, -15143, -15924, -16703, -17479, -18253, 250 -19024, -19792, -20557, -21320, -22078, -22834, -23586, -24335, 251 -25080, -25821, -26558, -27291, -28020, -28745, -29466, -30182, 252 -30893, -31600, -32303, -33000, -33692, -34380, -35062, -35738, 253 -36410, -37076, -37736, -38391, -39040, -39683, -40320, -40951, 254 -41576, -42194, -42806, -43412, -44011, -44604, -45190, -45769, 255 -46341, -46906, -47464, -48015, -48559, -49095, -49624, -50146, 256 -50660, -51166, -51665, -52156, -52639, -53114, -53581, -54040, 257 -54491, -54934, -55368, -55794, -56212, -56621, -57022, -57414, 258 -57798, -58172, -58538, -58896, -59244, -59583, -59914, -60235, 259 -60547, -60851, -61145, -61429, -61705, -61971, -62228, -62476, 260 -62714, -62943, -63162, -63372, -63572, -63763, -63944, -64115, 261 -64277, -64429, -64571, -64704, -64827, -64940, -65043, -65137, 262 -65220, -65294, -65358, -65413, -65457, -65492, -65516, -65531, 263 -65536, -65531, -65516, -65492, -65457, -65413, -65358, -65294, 264 -65220, -65137, -65043, -64940, -64827, -64704, -64571, -64429, 265 -64277, -64115, -63944, -63763, -63572, -63372, -63162, -62943, 266 -62714, -62476, -62228, -61971, -61705, -61429, -61145, -60851, 267 -60547, -60235, -59914, -59583, -59244, -58896, -58538, -58172, 268 -57798, -57414, -57022, -56621, -56212, -55794, -55368, -54934, 269 -54491, -54040, -53581, -53114, -52639, -52156, -51665, -51166, 270 -50660, -50146, -49624, -49095, -48559, -48015, -47464, -46906, 271 -46341, -45769, -45190, -44604, -44011, -43412, -42806, -42194, 272 -41576, -40951, -40320, -39683, -39040, -38391, -37736, -37076, 273 -36410, -35738, -35062, -34380, -33692, -33000, -32303, -31600, 274 -30893, -30182, -29466, -28745, -28020, -27291, -26558, -25821, 275 -25080, -24335, -23586, -22834, -22078, -21320, -20557, -19792, 276 -19024, -18253, -17479, -16703, -15924, -15143, -14359, -13573, 277 -12785, -11996, -11204, -10411, -9616, -8820, -8022, -7224, 278 -6424, -5623, -4821, -4019, -3216, -2412, -1608, -804, 279 0, 804, 1608, 2412, 3216, 4019, 4821, 5623, 280 6424, 7224, 8022, 8820, 9616, 10411, 11204, 11996, 281 12785, 13573, 14359, 15143, 15924, 16703, 17479, 18253, 282 19024, 19792, 20557, 21320, 22078, 22834, 23586, 24335, 283 25080, 25821, 26558, 27291, 28020, 28745, 29466, 30182, 284 30893, 31600, 32303, 33000, 33692, 34380, 35062, 35738, 285 36410, 37076, 37736, 38391, 39040, 39683, 40320, 40951, 286 41576, 42194, 42806, 43412, 44011, 44604, 45190, 45769, 287 46341, 46906, 47464, 48015, 48559, 49095, 49624, 50146, 288 50660, 51166, 51665, 52156, 52639, 53114, 53581, 54040, 289 54491, 54934, 55368, 55794, 56212, 56621, 57022, 57414, 290 57798, 58172, 58538, 58896, 59244, 59583, 59914, 60235, 291 60547, 60851, 61145, 61429, 61705, 61971, 62228, 62476, 292 62714, 62943, 63162, 63372, 63572, 63763, 63944, 64115, 293 64277, 64429, 64571, 64704, 64827, 64940, 65043, 65137, 294 65220, 65294, 65358, 65413, 65457, 65492, 65516, 65531L 295 ]; 296 297 private const(al_fixed[256]) _al_fix_tan_tbl = 298 [ 299 /* precalculated fixed point (16.16) tangents for a half circle (0-127) */ 300 301 0, 804, 1609, 2414, 3220, 4026, 4834, 5644, 302 6455, 7268, 8083, 8901, 9721, 10545, 11372, 12202, 303 13036, 13874, 14717, 15564, 16416, 17273, 18136, 19005, 304 19880, 20762, 21650, 22546, 23449, 24360, 25280, 26208, 305 27146, 28093, 29050, 30018, 30996, 31986, 32988, 34002, 306 35030, 36071, 37126, 38196, 39281, 40382, 41500, 42636, 307 43790, 44963, 46156, 47369, 48605, 49863, 51145, 52451, 308 53784, 55144, 56532, 57950, 59398, 60880, 62395, 63947, 309 65536, 67165, 68835, 70548, 72308, 74116, 75974, 77887, 310 79856, 81885, 83977, 86135, 88365, 90670, 93054, 95523, 311 98082, 100736, 103493, 106358, 109340, 112447, 115687, 119071, 312 122609, 126314, 130198, 134276, 138564, 143081, 147847, 152884, 313 158218, 163878, 169896, 176309, 183161, 190499, 198380, 206870, 314 216043, 225990, 236817, 248648, 261634, 275959, 291845, 309568, 315 329472, 351993, 377693, 407305, 441808, 482534, 531352, 590958, 316 665398, 761030, 888450, 1066730,1334016,1779314,2669641,5340086, 317 -2147483647,-5340086,-2669641,-1779314,-1334016,-1066730,-888450,-761030, 318 -665398,-590958,-531352,-482534,-441808,-407305,-377693,-351993, 319 -329472,-309568,-291845,-275959,-261634,-248648,-236817,-225990, 320 -216043,-206870,-198380,-190499,-183161,-176309,-169896,-163878, 321 -158218,-152884,-147847,-143081,-138564,-134276,-130198,-126314, 322 -122609,-119071,-115687,-112447,-109340,-106358,-103493,-100736, 323 -98082, -95523, -93054, -90670, -88365, -86135, -83977, -81885, 324 -79856, -77887, -75974, -74116, -72308, -70548, -68835, -67165, 325 -65536, -63947, -62395, -60880, -59398, -57950, -56532, -55144, 326 -53784, -52451, -51145, -49863, -48605, -47369, -46156, -44963, 327 -43790, -42636, -41500, -40382, -39281, -38196, -37126, -36071, 328 -35030, -34002, -32988, -31986, -30996, -30018, -29050, -28093, 329 -27146, -26208, -25280, -24360, -23449, -22546, -21650, -20762, 330 -19880, -19005, -18136, -17273, -16416, -15564, -14717, -13874, 331 -13036, -12202, -11372, -10545, -9721, -8901, -8083, -7268, 332 -6455, -5644, -4834, -4026, -3220, -2414, -1609, -804L 333 ]; 334 335 private const(al_fixed[513]) _al_fix_acos_tbl = 336 [ 337 /* precalculated fixed point (16.16) inverse cosines (-1 to 1) */ 338 339 0x800000, 0x7C65C7, 0x7AE75A, 0x79C19E, 0x78C9BE, 0x77EF25, 0x772953, 0x76733A, 340 0x75C991, 0x752A10, 0x74930C, 0x740345, 0x7379C1, 0x72F5BA, 0x72768F, 0x71FBBC, 341 0x7184D3, 0x711174, 0x70A152, 0x703426, 0x6FC9B5, 0x6F61C9, 0x6EFC36, 0x6E98D1, 342 0x6E3777, 0x6DD805, 0x6D7A5E, 0x6D1E68, 0x6CC40B, 0x6C6B2F, 0x6C13C1, 0x6BBDAF, 343 0x6B68E6, 0x6B1558, 0x6AC2F5, 0x6A71B1, 0x6A217E, 0x69D251, 0x698420, 0x6936DF, 344 0x68EA85, 0x689F0A, 0x685465, 0x680A8D, 0x67C17D, 0x67792C, 0x673194, 0x66EAAF, 345 0x66A476, 0x665EE5, 0x6619F5, 0x65D5A2, 0x6591E7, 0x654EBF, 0x650C26, 0x64CA18, 346 0x648890, 0x64478C, 0x640706, 0x63C6FC, 0x63876B, 0x63484F, 0x6309A5, 0x62CB6A, 347 0x628D9C, 0x625037, 0x621339, 0x61D69F, 0x619A68, 0x615E90, 0x612316, 0x60E7F7, 348 0x60AD31, 0x6072C3, 0x6038A9, 0x5FFEE3, 0x5FC56E, 0x5F8C49, 0x5F5372, 0x5F1AE7, 349 0x5EE2A7, 0x5EAAB0, 0x5E7301, 0x5E3B98, 0x5E0473, 0x5DCD92, 0x5D96F3, 0x5D6095, 350 0x5D2A76, 0x5CF496, 0x5CBEF2, 0x5C898B, 0x5C545E, 0x5C1F6B, 0x5BEAB0, 0x5BB62D, 351 0x5B81E1, 0x5B4DCA, 0x5B19E7, 0x5AE638, 0x5AB2BC, 0x5A7F72, 0x5A4C59, 0x5A1970, 352 0x59E6B6, 0x59B42A, 0x5981CC, 0x594F9B, 0x591D96, 0x58EBBD, 0x58BA0E, 0x588889, 353 0x58572D, 0x5825FA, 0x57F4EE, 0x57C40A, 0x57934D, 0x5762B5, 0x573243, 0x5701F5, 354 0x56D1CC, 0x56A1C6, 0x5671E4, 0x564224, 0x561285, 0x55E309, 0x55B3AD, 0x558471, 355 0x555555, 0x552659, 0x54F77B, 0x54C8BC, 0x549A1B, 0x546B98, 0x543D31, 0x540EE7, 356 0x53E0B9, 0x53B2A7, 0x5384B0, 0x5356D4, 0x532912, 0x52FB6B, 0x52CDDD, 0x52A068, 357 0x52730C, 0x5245C9, 0x52189E, 0x51EB8B, 0x51BE8F, 0x5191AA, 0x5164DC, 0x513825, 358 0x510B83, 0x50DEF7, 0x50B280, 0x50861F, 0x5059D2, 0x502D99, 0x500175, 0x4FD564, 359 0x4FA967, 0x4F7D7D, 0x4F51A6, 0x4F25E2, 0x4EFA30, 0x4ECE90, 0x4EA301, 0x4E7784, 360 0x4E4C19, 0x4E20BE, 0x4DF574, 0x4DCA3A, 0x4D9F10, 0x4D73F6, 0x4D48EC, 0x4D1DF1, 361 0x4CF305, 0x4CC829, 0x4C9D5A, 0x4C729A, 0x4C47E9, 0x4C1D45, 0x4BF2AE, 0x4BC826, 362 0x4B9DAA, 0x4B733B, 0x4B48D9, 0x4B1E84, 0x4AF43B, 0x4AC9FE, 0x4A9FCD, 0x4A75A7, 363 0x4A4B8D, 0x4A217E, 0x49F77A, 0x49CD81, 0x49A393, 0x4979AF, 0x494FD5, 0x492605, 364 0x48FC3F, 0x48D282, 0x48A8CF, 0x487F25, 0x485584, 0x482BEC, 0x48025D, 0x47D8D6, 365 0x47AF57, 0x4785E0, 0x475C72, 0x47330A, 0x4709AB, 0x46E052, 0x46B701, 0x468DB7, 366 0x466474, 0x463B37, 0x461201, 0x45E8D0, 0x45BFA6, 0x459682, 0x456D64, 0x45444B, 367 0x451B37, 0x44F229, 0x44C920, 0x44A01C, 0x44771C, 0x444E21, 0x44252A, 0x43FC38, 368 0x43D349, 0x43AA5F, 0x438178, 0x435894, 0x432FB4, 0x4306D8, 0x42DDFE, 0x42B527, 369 0x428C53, 0x426381, 0x423AB2, 0x4211E5, 0x41E91A, 0x41C051, 0x41978A, 0x416EC5, 370 0x414601, 0x411D3E, 0x40F47C, 0x40CBBB, 0x40A2FB, 0x407A3C, 0x40517D, 0x4028BE, 371 0x400000, 0x3FD742, 0x3FAE83, 0x3F85C4, 0x3F5D05, 0x3F3445, 0x3F0B84, 0x3EE2C2, 372 0x3EB9FF, 0x3E913B, 0x3E6876, 0x3E3FAF, 0x3E16E6, 0x3DEE1B, 0x3DC54E, 0x3D9C7F, 373 0x3D73AD, 0x3D4AD9, 0x3D2202, 0x3CF928, 0x3CD04C, 0x3CA76C, 0x3C7E88, 0x3C55A1, 374 0x3C2CB7, 0x3C03C8, 0x3BDAD6, 0x3BB1DF, 0x3B88E4, 0x3B5FE4, 0x3B36E0, 0x3B0DD7, 375 0x3AE4C9, 0x3ABBB5, 0x3A929C, 0x3A697E, 0x3A405A, 0x3A1730, 0x39EDFF, 0x39C4C9, 376 0x399B8C, 0x397249, 0x3948FF, 0x391FAE, 0x38F655, 0x38CCF6, 0x38A38E, 0x387A20, 377 0x3850A9, 0x38272A, 0x37FDA3, 0x37D414, 0x37AA7C, 0x3780DB, 0x375731, 0x372D7E, 378 0x3703C1, 0x36D9FB, 0x36B02B, 0x368651, 0x365C6D, 0x36327F, 0x360886, 0x35DE82, 379 0x35B473, 0x358A59, 0x356033, 0x353602, 0x350BC5, 0x34E17C, 0x34B727, 0x348CC5, 380 0x346256, 0x3437DA, 0x340D52, 0x33E2BB, 0x33B817, 0x338D66, 0x3362A6, 0x3337D7, 381 0x330CFB, 0x32E20F, 0x32B714, 0x328C0A, 0x3260F0, 0x3235C6, 0x320A8C, 0x31DF42, 382 0x31B3E7, 0x31887C, 0x315CFF, 0x313170, 0x3105D0, 0x30DA1E, 0x30AE5A, 0x308283, 383 0x305699, 0x302A9C, 0x2FFE8B, 0x2FD267, 0x2FA62E, 0x2F79E1, 0x2F4D80, 0x2F2109, 384 0x2EF47D, 0x2EC7DB, 0x2E9B24, 0x2E6E56, 0x2E4171, 0x2E1475, 0x2DE762, 0x2DBA37, 385 0x2D8CF4, 0x2D5F98, 0x2D3223, 0x2D0495, 0x2CD6EE, 0x2CA92C, 0x2C7B50, 0x2C4D59, 386 0x2C1F47, 0x2BF119, 0x2BC2CF, 0x2B9468, 0x2B65E5, 0x2B3744, 0x2B0885, 0x2AD9A7, 387 0x2AAAAB, 0x2A7B8F, 0x2A4C53, 0x2A1CF7, 0x29ED7B, 0x29BDDC, 0x298E1C, 0x295E3A, 388 0x292E34, 0x28FE0B, 0x28CDBD, 0x289D4B, 0x286CB3, 0x283BF6, 0x280B12, 0x27DA06, 389 0x27A8D3, 0x277777, 0x2745F2, 0x271443, 0x26E26A, 0x26B065, 0x267E34, 0x264BD6, 390 0x26194A, 0x25E690, 0x25B3A7, 0x25808E, 0x254D44, 0x2519C8, 0x24E619, 0x24B236, 391 0x247E1F, 0x2449D3, 0x241550, 0x23E095, 0x23ABA2, 0x237675, 0x23410E, 0x230B6A, 392 0x22D58A, 0x229F6B, 0x22690D, 0x22326E, 0x21FB8D, 0x21C468, 0x218CFF, 0x215550, 393 0x211D59, 0x20E519, 0x20AC8E, 0x2073B7, 0x203A92, 0x20011D, 0x1FC757, 0x1F8D3D, 394 0x1F52CF, 0x1F1809, 0x1EDCEA, 0x1EA170, 0x1E6598, 0x1E2961, 0x1DECC7, 0x1DAFC9, 395 0x1D7264, 0x1D3496, 0x1CF65B, 0x1CB7B1, 0x1C7895, 0x1C3904, 0x1BF8FA, 0x1BB874, 396 0x1B7770, 0x1B35E8, 0x1AF3DA, 0x1AB141, 0x1A6E19, 0x1A2A5E, 0x19E60B, 0x19A11B, 397 0x195B8A, 0x191551, 0x18CE6C, 0x1886D4, 0x183E83, 0x17F573, 0x17AB9B, 0x1760F6, 398 0x17157B, 0x16C921, 0x167BE0, 0x162DAF, 0x15DE82, 0x158E4F, 0x153D0B, 0x14EAA8, 399 0x14971A, 0x144251, 0x13EC3F, 0x1394D1, 0x133BF5, 0x12E198, 0x1285A2, 0x1227FB, 400 0x11C889, 0x11672F, 0x1103CA, 0x109E37, 0x10364B, 0xFCBDA, 0xF5EAE, 0xEEE8C, 401 0xE7B2D, 0xE0444, 0xD8971, 0xD0A46, 0xC863F, 0xBFCBB, 0xB6CF4, 0xAD5F0, 402 0xA366F, 0x98CC6, 0x8D6AD, 0x810DB, 0x73642, 0x63E62, 0x518A6, 0x39A39, 403 0x0L 404 ]; 405 406 }