ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

math.h

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 // Based on eos' math code
00024 
00025 #ifndef COMMON_MATH_H
00026 #define COMMON_MATH_H
00027 
00028 #include "common/scummsys.h"
00029 #ifdef _MSC_VER
00030 // HACK:
00031 // intrin.h on MSVC includes setjmp.h, which will fail compiling due to our
00032 // forbidden symbol colde. Since we also can not assure that defining
00033 // FORBIDDEN_SYMBOL_EXCEPTION_setjmp and FORBIDDEN_SYMBOL_EXCEPTION_longjmp
00034 // will actually allow the symbols, since forbidden.h might be included
00035 // earlier already we need to undefine them here...
00036 #undef setjmp
00037 #undef longjmp
00038 #include <intrin.h>
00039 // ...and redefine them here so no code can actually use it.
00040 // This could be resolved by including intrin.h on MSVC in scummsys.h before
00041 // the forbidden.h include. This might make sense, in case we use MSVC
00042 // extensions like _BitScanReverse in more places. But for now this hack should
00043 // be ok...
00044 #ifndef FORBIDDEN_SYMBOL_EXCEPTION_setjmp
00045 #undef setjmp
00046 #define setjmp(a)   FORBIDDEN_SYMBOL_REPLACEMENT
00047 #endif
00048 
00049 #ifndef FORBIDDEN_SYMBOL_EXCEPTION_longjmp
00050 #undef longjmp
00051 #define longjmp(a,b)    FORBIDDEN_SYMBOL_REPLACEMENT
00052 #endif
00053 #endif
00054 
00055 #ifndef FLT_MIN
00056     #define FLT_MIN 1E-37
00057 #endif
00058 
00059 #ifndef FLT_MAX
00060     #define FLT_MAX 1E+37
00061 #endif
00062 
00063 namespace Common {
00064 
00066 struct Complex {
00067     float re, im;
00068 };
00069 
00070 #if GCC_ATLEAST(3, 4)
00071 inline int intLog2(uint32 v) {
00072     // This is a slightly optimized implementation of log2 for natural numbers
00073     // targeting gcc. It also saves some binary size over our fallback
00074     // implementation, since it does not need any table.
00075     if (v == 0)
00076         return -1;
00077     else
00078         // This is really "sizeof(unsigned int) * CHAR_BIT - 1" but using 8
00079         // instead of CHAR_BIT is sane enough and it saves us from including
00080         // limits.h
00081         return (sizeof(unsigned int) * 8 - 1) - __builtin_clz(v);
00082 }
00083 #elif defined(_MSC_VER)
00084 inline int intLog2(uint32 v) {
00085     unsigned long result = 0;
00086     unsigned char nonZero = _BitScanReverse(&result, v);
00087     // _BitScanReverse stores the position of the MSB set in case its result
00088     // is non zero, thus we can just return it as is.
00089     return nonZero ? result : -1;
00090 }
00091 #else
00092 // See http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup
00093 static const char LogTable256[256] = {
00094 #define LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
00095     -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
00096     LT(4), LT(5), LT(5), LT(6), LT(6), LT(6), LT(6),
00097     LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7)
00098 };
00099 
00100 inline int intLog2(uint32 v) {
00101     uint32 t, tt;
00102 
00103     if ((tt = v >> 16))
00104         return (t = tt >> 8) ? 24 + LogTable256[t] : 16 + LogTable256[tt];
00105     else
00106         return (t =  v >> 8) ?  8 + LogTable256[t] : LogTable256[v];
00107 }
00108 #endif
00109 
00110 // Convert radians to degrees
00111 // Input and Output type can be different
00112 // Upconvert everything to floats
00113 template<class InputT, class OutputT> 
00114 inline OutputT rad2deg(InputT rad) {
00115     return (OutputT)( (float)rad * (float)57.2957795130823); // 180.0/M_PI = 57.2957795130823
00116 }
00117 
00118 // Handle the case differently when the input type is double
00119 template<class OutputT> 
00120 inline OutputT rad2deg(double rad) {
00121     return (OutputT)( rad * 57.2957795130823);
00122 }
00123 
00124 // Convert radians to degrees
00125 // Input and Output type are the same
00126 template<class T> 
00127 inline T rad2deg(T rad) {
00128     return rad2deg<T,T>(rad);
00129 }
00130 
00131 // Convert degrees to radians
00132 // Input and Output type can be different
00133 // Upconvert everything to floats
00134 template<class InputT, class OutputT> 
00135 inline OutputT deg2rad(InputT deg) {
00136     return (OutputT)( (float)deg * (float)0.0174532925199433); // M_PI/180.0 = 0.0174532925199433
00137 }
00138 
00139 // Handle the case differently when the input type is double
00140 template<class OutputT> 
00141 inline OutputT deg2rad(double deg) {
00142     return (OutputT)( deg * 0.0174532925199433);
00143 }
00144 
00145 // Convert degrees to radians
00146 // Input and Output type are the same
00147 template<class T> 
00148 inline T deg2rad(T deg) {
00149     return deg2rad<T,T>(deg);
00150 }
00151 
00152 } // End of namespace Common
00153 
00154 #endif // COMMON_MATH_H


Generated on Sat May 18 2019 05:01:09 for ResidualVM by doxygen 1.7.1
curved edge   curved edge