1 #pragma once
2 
3 //********************************************************************************************
4 //*
5 //*    This file is part of Egoboo.
6 //*
7 //*    Egoboo is free software: you can redistribute it and/or modify it
8 //*    under the terms of the GNU General Public License as published by
9 //*    the Free Software Foundation, either version 3 of the License, or
10 //*    (at your option) any later version.
11 //*
12 //*    Egoboo is distributed in the hope that it will be useful, but
13 //*    WITHOUT ANY WARRANTY; without even the implied warranty of
14 //*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 //*    General Public License for more details.
16 //*
17 //*    You should have received a copy of the GNU General Public License
18 //*    along with Egoboo.  If not, see <http://www.gnu.org/licenses/>.
19 //*
20 //********************************************************************************************
21 
22 /// @file egoboo_math.h
23 /// @details The name's pretty self explanatory, doncha think?
24 
25 #include "egoboo_typedef.h"
26 
27 #include <math.h>
28 #include <float.h>
29 
30 #if defined(__cplusplus)
31 extern "C"
32 {
33 #endif
34 
35 //--------------------------------------------------------------------------------------------
36 //--------------------------------------------------------------------------------------------
37 // basic constants
38 
39 #if !defined(PI)
40 #   define PI                  3.1415926535897932384626433832795f
41 #endif
42 
43 #if !defined(TWO_PI)
44 #   define TWO_PI              6.283185307179586476925286766559f
45 #endif
46 
47 #if !defined(SQRT_TWO)
48 #   define SQRT_TWO            1.4142135623730950488016887242097f
49 #endif
50 
51 #if !defined(INV_SQRT_TWO)
52 #   define INV_SQRT_TWO        0.70710678118654752440084436210485f
53 #endif
54 
55 #if !defined(RAD_TO_TURN)
56 #   define RAD_TO_TURN         10430.378350470452724949566316381f
57 #endif
58 
59 #if !defined(TURN_TO_RAD)
60 #   define TURN_TO_RAD         0.000095873799242852576857380474343257f
61 #endif
62 
63 //--------------------------------------------------------------------------------------------
64 // the lookup tables for sine and cosine
65 
66 #define TRIG_TABLE_BITS   14
67 #define TRIG_TABLE_SIZE   (1<<TRIG_TABLE_BITS)
68 #define TRIG_TABLE_MASK   (TRIG_TABLE_SIZE-1)
69 #define TRIG_TABLE_OFFSET (TRIG_TABLE_SIZE>>2)
70 
71 /// @note - Aaron uses two terms without much attention to their meaning
72 ///         I think that we should use "face" or "facing" to mean the fill 16-bit value
73 ///         and use "turn" to be the TRIG_TABLE_BITS-bit value
74 
75     extern float turntosin[TRIG_TABLE_SIZE];           ///< Convert TURN_T == FACING_T>>2...  to sine
76     extern float turntocos[TRIG_TABLE_SIZE];           ///< Convert TURN_T == FACING_T>>2...  to cosine
77 
78 /// pre defined directions
79 #define FACE_WEST    0x0000
80 #define FACE_NORTH   0x4000                                 ///< Character facings
81 #define FACE_EAST    0x8000
82 #define FACE_SOUTH   0xC000
83 
84 //--------------------------------------------------------------------------------------------
85 //--------------------------------------------------------------------------------------------
86 // Just define ABS, MIN, and MAX using macros for the moment. This is likely to be the
87 // fastest and most cross-platform solution
88 
89 #if !defined(ABS)
90 #    define ABS(X)  (((X) > 0) ? (X) : -(X))
91 #endif
92 
93 #if !defined(SGN)
94 #    define SGN(X)  ((0 == (X)) ? 0 : (((X) > 0) ? 1 : -1) )
95 #endif
96 
97 #if !defined(MIN)
98 #    define MIN(x, y)  (((x) > (y)) ? (y) : (x))
99 #endif
100 
101 #if !defined(MAX)
102 #    define MAX(x, y)  (((x) > (y)) ? (x) : (y))
103 #endif
104 
105 #if !defined(SQR)
106 #    define SQR(A) ((A)*(A))
107 #endif
108 
109 #if !defined(SQRT)
110 #    define SQRT(A) ((float)sqrt((float)(A)))
111 #endif
112 
113 #if !defined(LOG)
114 #    define LOG(A) ((float)log((float)(A)))
115 #endif
116 
117 #if !defined(SIN)
118 #    define SIN(A) ((float)sin((float)(A)))
119 #endif
120 
121 #if !defined(COS)
122 #    define COS(A) ((float)cos((float)(A)))
123 #endif
124 
125 #if !defined(POW)
126 #    define POW(A, B) ((float)pow((float)(A), (float)(B)))
127 #endif
128 
129 #if !defined(ATAN2)
130 #    define ATAN2(A, B) ((float)atan2((float)(A), (float)(B)))
131 #endif
132 
133 #if !defined(CLIP)
134 #    define CLIP(VAL,VMIN,VMAX) MIN(MAX(VAL,VMIN),VMAX)
135 #endif
136 
137 #if !defined(SWAP)
138 #    define SWAP(TYPE, A, B) { TYPE temp; temp = A; A = B; B = temp; }
139 #endif
140 
141 #if !defined(CEIL)
142 #    define CEIL(VAL) ( (float)ceil((float)VAL) )
143 #endif
144 
145 #if !defined(FLOOR)
146 #    define FLOOR(VAL) ( (float)floor((float)VAL) )
147 #endif
148 
149 #define MAT_IDX(I,J) (4*(I)+(J))
150 #define CNV(I,J)     v[MAT_IDX(I,J)]
151 #define CopyMatrix( pMatrixDest, pMatrixSource ) memmove( pMatrixDest, pMatrixSource, sizeof( *pMatrixDest ) )
152 
153     Uint32 float32_to_uint32( float );
154     float  uint32_to_float32( Uint32 );
155 
156     bool_t ieee32_infinite( float );
157     bool_t ieee32_nan( float );
158 
159 #if defined(TEST_NAN_RESULT)
160 #    define LOG_NAN(XX)      if( isnan(XX) ) log_error( "**** A math operation resulted in an invalid result (NAN) ****\n    (\"%s\" - %d)\n", __FILE__, __LINE__ );
161 #else
162 #    define LOG_NAN(XX)
163 #endif
164 
165 //--------------------------------------------------------------------------------------------
166 // FAST CONVERSIONS
167 
168 #if !defined(INV_FF)
169 #   define INV_FF              0.003921568627450980392156862745098f
170 #endif
171 
172 #if !defined(INV_0100)
173 #   define INV_0100            0.00390625f
174 #endif
175 
176 #if !defined(INV_FFFF)
177 #   define INV_FFFF            0.000015259021896696421759365224689097f
178 #endif
179 
180 #define FF_TO_FLOAT( V1 )  ( (float)(V1) * INV_FF )
181 
182 #define FFFF_TO_FLOAT( V1 )  ( (float)(V1) * INV_FFFF )
183 #define FLOAT_TO_FFFF( V1 )  ( ((V1) * 0xFFFF) )
184 
185 //--------------------------------------------------------------------------------------------
186 //--------------------------------------------------------------------------------------------
187 // vector definitions
188 
189     enum { kX = 0, kY, kZ, kW };             ///< Enumerated indices for the elements of the base vector types
190 
191     typedef float fmat_4x4_base_t[16];       ///< the basic 4x4 floating point matrix type
192     typedef float fvec2_base_t[2];           ///< the basic floating point 2-vector type
193     typedef float fvec3_base_t[3];           ///< the basic floating point 3-vector type
194     typedef float fvec4_base_t[4];           ///< the basic floating point 4-vector type
195 
196     typedef double dmat_4x4_base_t[16];      ///< the basic 4x4 double precision matrix type
197     typedef double dvec2_base_t[2];          ///< the basic double precision 2-vector type
198     typedef double dvec3_base_t[3];          ///< the basic double precision 3-vector type
199     typedef double dvec4_base_t[4];          ///< the basic double precision 4-vector type
200 
201 /// A wrapper for fmat_4x4_base_t
202 /// Necessary in c so that the function return can be assigned to another matrix more simply.
203     typedef struct s_fmat_4x4  { fmat_4x4_base_t  v; } fmat_4x4_t;
204 
205 /// A 2-vector type that allows more than one form of access
206     typedef union  u_fvec2     { fvec2_base_t v; struct { float x, y; }; struct { float s, t; }; } fvec2_t;
207 
208 /// A 3-vector type that allows more than one form of access
209     typedef union  u_fvec3     { fvec3_base_t v; struct { float x, y, z; }; struct { float r, g, b; }; } fvec3_t;
210 
211 /// A 4-vector type that allows more than one form of access
212     typedef union  u_fvec4     { fvec4_base_t v; struct { float x, y, z, w; }; struct { float r, g, b, a; }; } fvec4_t;
213 
214 // macros for initializing vectors to zero
215 #define ZERO_VECT2   { {0.0f,0.0f} }
216 #define ZERO_VECT3   { {0.0f,0.0f,0.0f} }
217 #define ZERO_VECT4   { {0.0f,0.0f,0.0f,0.0f} }
218 #define ZERO_MAT_4X4 { {0.0f,0.0f,0.0f,0.0f, 0.0f,0.0f,0.0f,0.0f, 0.0f,0.0f,0.0f,0.0f, 0.0f,0.0f,0.0f,0.0f} }
219 
220 // Macros for initializing vectors to specific values. Most C compilers will allow you to initialize
221 // to non-constant values, but they do complain.
222 #define VECT2(XX,YY) { {XX,YY} }
223 #define VECT3(XX,YY,ZZ) { {XX,YY,ZZ} }
224 #define VECT4(XX,YY,ZZ,WW) { {XX,YY,ZZ,WW} }
225 
226 //--------------------------------------------------------------------------------------------
227 //--------------------------------------------------------------------------------------------
228 // My lil' random number table
229 
230 // swig chokes on the definition below
231 #if defined(SWIG)
232 #    define RANDIE_BITS    12
233 #    define RANDIE_COUNT 4096
234 #else
235 #    define RANDIE_BITS   12
236 #    define RANDIE_COUNT (1 << RANDIE_BITS)
237 #endif
238 
239 #define RANDIE_MASK  ((Uint32)(RANDIE_COUNT - 1))
240 #define RANDIE       randie[randindex & RANDIE_MASK ];  randindex++; randindex &= RANDIE_MASK
241 
242     extern Uint32  randindex;
243     extern Uint16  randie[RANDIE_COUNT];   ///< My lil' random number table
244 
245 //--------------------------------------------------------------------------------------------
246 //--------------------------------------------------------------------------------------------
247 
248 // prototypes of other math functions
249 
250     void make_turntosin( void );
251     void make_randie();
252 
253 //--------------------------------------------------------------------------------------------
254 //--------------------------------------------------------------------------------------------
255 
256 #if defined(__cplusplus)
257 }
258 #endif
259 
260 //--------------------------------------------------------------------------------------------
261 //--------------------------------------------------------------------------------------------
262 
263 #define _egoboo_math_h
264