/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "common/endian.h" #include "m4/core/imath.h" namespace M4 { unsigned long sqrtul(unsigned long v) { unsigned long r = 0, s; #define STEP(k) s = r + (1L << (k * 2)); r >>= 1; \ if (s <= v) { v -= s; r |= (1L << (k * 2)); } STEP(15); STEP(14); STEP(13); STEP(12); STEP(11); STEP(10); STEP(9); STEP(8); STEP(7); STEP(6); STEP(5); STEP(4); STEP(3); STEP(2); STEP(1); STEP(0); return r; #undef STEP } int32 imath_min(int32 a, int32 b) { return ((a < b) ? a : b); } int32 imath_max(int32 a, int32 b) { return ((a > b) ? a : b); } int32 imath_abs(int32 a) { return ((a >= 0) ? a : -a); } static int32 seed; void imath_seed(int32 seedNum) { seed = seedNum; } uint32 imath_random() { return(seed = (25173 * seed + 13849) & 0xffff); } int32 imath_ranged_rand(int32 a, int32 b) { const int32 result = (a + (((1 + imath_abs(b - a)) * imath_random()) >> 16)); return result; } frac16 imath_ranged_rand16(frac16 a, frac16 b) { const frac16 result = ((a + MulSF16(1 + imath_abs(b - a), imath_random()))); return result; } bool imath_rand_bool(int max) { return imath_ranged_rand(1, max) == 1; } frac16 dist2d(int32 x1, int32 y1, int32 x2, int32 y2) { if ((x2 -= x1) < 0) x2 = -x2; if ((y2 -= y1) < 0) y2 = -y2; return (x2 + y2 - (((x2 > y2) ? y2 : x2) >> 1)); } #define STEP(k) s = r + (1L << (k * 2)); r >>= 1; \ if (s <= v) { v -= s; r |= (1L << (k * 2)); } frac16 SqrtF16(frac16 n) { ulong r = 0, s; ulong v = (ulong)n; STEP(15); STEP(14); STEP(13); STEP(12); STEP(11); STEP(10); STEP(9); STEP(8); STEP(7); STEP(6); STEP(5); STEP(4); STEP(3); STEP(2); STEP(1); STEP(0); return (frac16)r; } #define DIV_128_PI 0x28be61 frac16 ArcTan(frac16 x, frac16 y) { const double floatX = (float)(x >> 16) + (float)((float)(x & 0xffff) / (float)65536); const double floatY = (float)(y >> 16) + (float)((float)(y & 0xffff) / (float)65536); const double result = atan2(floatY, floatX); frac16 fracResult = (((int32)(floor(result))) << 16) + (int32)(floor((result - floor(result)) * 65536)); fracResult = MulSF16(fracResult, DIV_128_PI); if (fracResult < 0) fracResult += 0x1000000; return fracResult; } uint16 HighWord(uint32 n) { return (uint16)(n >> 16); } uint16 LowWord(uint32 n) { return (uint16)(n & 0xffff); } uint32 convert_intel32(uint32 a) { return FROM_LE_32(a); } uint16 convert_intel16(uint16 a) { return FROM_LE_16(a); } frac16 FixedMul(frac16 a, frac16 b) { const float ta = a; const float tb = b; return (frac16)((ta * tb) / 65536.0); } frac16 FixedDiv(frac16 a, frac16 b) { const float ta = a; const float tb = b; return (frac16)((ta / tb) * 65536.0); } frac16 FixedMulDiv(frac16 a, frac16 b, frac16 c) { const float ta = a; const float tb = b; const float tc = c; return (frac16)((ta * tb) / tc); } } // namespace M4