1 /*---------------------------------------------------------------------------*
2   Project:  NitroSDK - FX - demos - test
3   File:     main.c
4 
5   Copyright 2003-2006 Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: main.c,v $
14   Revision 1.14  2006/01/18 02:11:21  kitase_hirotake
15   do-indent
16 
17   Revision 1.13  2005/02/28 05:26:13  yosizaki
18   do-indent.
19 
20   Revision 1.12  2004/06/08 00:15:43  yada
21   add '#pragma unused()' for FINALROM
22 
23   Revision 1.11  2004/04/07 01:27:57  yada
24   fix header comment
25 
26   Revision 1.10  2004/02/10 09:49:57  nishida_kenji
27   Improve some tests.
28 
29   Revision 1.9  2004/02/05 07:09:02  yasu
30   change SDK prefix iris -> nitro
31 
32   Revision 1.8  2004/01/29 01:35:09  kitani_toshikazu
33   Fix some bugs for debug build, restore appended test cases.
34 
35   Revision 1.7  2004/01/27 04:41:47  kitani_toshikazu
36   Removed new tests for a while
37 
38   Revision 1.6  2004/01/27 01:35:40  kitani_toshikazu
39   Appended some test cases
40 
41   Revision 1.4  2004/01/18 04:40:35  nishida_kenji
42   revises the interfaces for asynchronous calculation
43 
44   Revision 1.3  2004/01/17 07:06:24  nishida_kenji
45   add MTX_MultVec33
46 
47   Revision 1.2  2004/01/16 10:41:50  nishida_kenji
48   tests the sin/cos table
49 
50   Revision 1.1  2003/12/12 08:11:15  nishida_kenji
51   testing fixed point library
52 
53   $NoKeywords: $
54  *---------------------------------------------------------------------------*/
55 
56 #include <nitro.h>
57 #include <math.h>
58 
59 #ifndef  FX_TEST_COMMON_H_
60 #include "fx_test_common.h"
61 #endif //  FX_TEST_COMMON_H_
62 
63 #ifndef  FX_APPEND_VEC_H_
64 #include "fx_append_vec.h"
65 #endif //  FX_APPEND_VEC_H_
66 
67 #ifndef  FX_APPEND_MTX_H_
68 #include "fx_append_mtx.h"
69 #endif //  FX_APPEND_MTX_H_
70 
71 
72 extern const fx16 testTable[];
73 
74 
75 
76 
77 
test_FX_VEC()78 static void test_FX_VEC()
79 {
80     VecFx32 a = { FX32_ONE, FX32_ONE * 2, FX32_ONE * 3 };
81     VecFx32 b = { FX32_ONE * 5, FX32_ONE * 7, FX32_ONE * 11 };
82     VecFx32 c;
83     fx32    tmp;
84 
85     OS_Printf("----- testing fx_vec.h -----\n");
86 
87     VEC_Add(&a, &b, &c);
88     SDK_ASSERTMSG(c.x == 6 * FX32_ONE && c.y == 9 * FX32_ONE && c.z == 14 * FX32_ONE, "VEC_Add");
89 
90     VEC_Subtract(&a, &b, &c);
91     SDK_ASSERTMSG(c.x == -4 * FX32_ONE && c.y == -5 * FX32_ONE
92                   && c.z == -8 * FX32_ONE, "VEC_Subtract");
93 
94     tmp = VEC_DotProduct(&a, &b);
95     SDK_ASSERTMSG(tmp == 52 * FX32_ONE, "VEC_DotProduct %d", tmp);
96 
97     VEC_CrossProduct(&a, &b, &c);
98     SDK_ASSERTMSG(c.x == FX32_ONE && c.y == 4 * FX32_ONE
99                   && c.z == -3 * FX32_ONE, "VEC_CrossProduct");
100 
101     tmp = VEC_Mag(&a);
102     SDK_ASSERTMSG(tmp == 15326, "VEC_Mag");
103 
104 
105     VEC_Normalize(&a, &c);
106     SDK_ASSERTMSG(c.x == 1095 &&
107                   c.y == 2189 && c.z == 3284, "VEC_Normalize: %d %d %d", c.x, c.y, c.z);
108 
109     OS_Printf(" done.\n");
110 }
111 
112 
113 
test_FX_TRIG()114 static void test_FX_TRIG()
115 {
116 
117     OS_Printf("----- testing fx_trig.h -----\n");
118 
119     {
120         fx32    tmp = FX_DEG_TO_RAD(180 * FX32_ONE);
121         SDK_ASSERTMSG(tmp == 12868, "FX_DEG_TO_RAD");
122     }
123 
124     {
125         int     tmp = FX_DEG_TO_IDX(180 * FX32_ONE);
126         SDK_ASSERTMSG(tmp == 32768, "FX_DEG_TO_IDX");
127     }
128 
129     {
130         fx32    tmp = FX_RAD_TO_DEG((fx32)((2 * FX64C_PI + 0x80000LL) >> 20));
131         SDK_ASSERTMSG(tmp == 1474564, "FX_RAD_TO_DEG");
132     }
133 
134     {
135         int     tmp = FX_RAD_TO_IDX((fx32)((FX64C_PI + 0x80000LL) >> 20));
136         SDK_ASSERTMSG(tmp == 32768, "FX_RAD_TO_IDX");
137     }
138 
139     // FX_SinIdx, FX_CosIdx, FX_Atan, FX_Atan2 not tested
140     {
141         double  max = 0.0;
142         fx32    x;
143         fx32    xmax = 0;
144 
145         for (x = 0; x < 25736; ++x)
146         {                              // 0 ... 2pi
147             double  a = sin((double)x / 4096.0);
148             fx64c   b = FX_SinFx64c(x);
149             double  miss = fabs(a - b / 4294967296.0);
150             if (miss > max)
151             {
152                 max = miss;
153                 xmax = x;
154             }
155         }
156         OS_Printf("Maximum margin of error of FX_SinFx64c is %.10f(rad = %f)\n", max,
157                   (double)xmax / 4096.0);
158     }
159 
160     {
161         double  max = 0.0;
162         fx32    x;
163         fx32    xmax = 0;
164 
165         for (x = 0; x < 25736; ++x)
166         {                              // 0 ... 2pi
167             double  a = cos((double)x / 4096.0);
168             fx64c   b = FX_CosFx64c(x);
169             double  miss = fabs(a - b / 4294967296.0);
170             if (miss > max)
171             {
172                 max = miss;
173                 xmax = x;
174             }
175         }
176         OS_Printf("Maximum margin of error of FX_CosFx64c is %.10f(rad = %f)\n", max,
177                   (double)xmax / 4096.0);
178     }
179 
180     OS_Printf(" done.\n");
181 }
182 
183 typedef double (*BINARY_FUNC_PTR) (f32 lhs, f32 rhs);
184 
185 
getErrorBtweenFx32AnbF32_Multiple(f32 lhs,f32 rhs)186 static double getErrorBtweenFx32AnbF32_Multiple(f32 lhs, f32 rhs)
187 {
188     double  errorVal;
189     fx32    fxl = FX_F32_TO_FX32(lhs);
190     fx32    fxr = FX_F32_TO_FX32(rhs);
191     fx32    fxResult;
192 
193     fxResult = FX_Mul(fxl, fxr);
194     errorVal = fabs((double)lhs * (double)rhs - (FX_FX32_TO_F32(fxResult)));
195 
196     return errorVal;
197 }
198 
199 
test_FX_CP(void)200 static void test_FX_CP(void)
201 {
202     OS_Printf("----- testing fx_cp.h -----\n");
203     {
204         fx32    tmp = FX_Div(FX32_ONE * 2, FX32_ONE * 3);
205         SDK_ASSERTMSG(tmp == 2731, "FX_Div");
206     }
207     {
208         fx32    tmp = FX_Inv(FX32_ONE + (FX32_ONE >> 1));
209         SDK_ASSERTMSG(tmp == 2731, "FX_Inv");
210     }
211     {
212         fx32    tmp = FX_Sqrt(FX32_ONE * 2);
213         SDK_ASSERTMSG(tmp == 5793, "FX_Sqrt %d", tmp);
214     }
215     {
216         fx32    tmp;
217         FX_DivAsync(FX32_ONE * 2, FX32_ONE * 3);
218         tmp = FX_GetDivResult();
219         SDK_ASSERTMSG(tmp == 2731, "FX_DivAsync/FX_GetDivResultAsync");
220     }
221     {
222         fx32    tmp;
223         FX_InvAsync(FX32_ONE + (FX32_ONE >> 1));
224         tmp = FX_GetInvResult();
225         SDK_ASSERTMSG(tmp == 2731, "FX_InvAsync/FX_GetInvResultAsync");
226     }
227     {
228         fx32    tmp;
229         FX_SqrtAsync(FX32_ONE * 2);
230         tmp = FX_GetSqrtResult();
231         SDK_ASSERTMSG(tmp == 5793, "FX_SqrtAsync/FX_GetSqrtResultAsync");
232     }
233     {
234         fx32    tmp;
235         tmp = FX_InvSqrt(FX32_ONE * 4);
236         SDK_ASSERTMSG(tmp == (FX32_ONE >> 1), "FX_InvSqrt");
237     }
238 
239     OS_Printf(" done.\n");
240 }
241 
print_mtx33(const MtxFx33 * m)242 static void print_mtx33(const MtxFx33 *m)
243 {
244 #ifdef SDK_FINALROM
245 #pragma unused( m )
246 #endif
247 
248     OS_Printf("_\n");
249     OS_Printf("%f %f %f\n", m->_00 / 4096.0, m->_01 / 4096.0, m->_02 / 4096.0);
250     OS_Printf("%f %f %f\n", m->_10 / 4096.0, m->_11 / 4096.0, m->_12 / 4096.0);
251     OS_Printf("%f %f %f\n", m->_20 / 4096.0, m->_21 / 4096.0, m->_22 / 4096.0);
252     OS_Printf("_\n");
253 }
254 
equal_mtx33(const MtxFx33 * a,const MtxFx33 * b)255 static BOOL equal_mtx33(const MtxFx33 *a, const MtxFx33 *b)
256 {
257     return (a->_00 == b->_00 &&
258             a->_01 == b->_01 &&
259             a->_02 == b->_02 &&
260             a->_10 == b->_10 &&
261             a->_11 == b->_11 &&
262             a->_12 == b->_12 && a->_20 == b->_20 && a->_21 == b->_21 && a->_22 == b->_22);
263 }
264 
equal_mtx43(const MtxFx43 * a,const MtxFx43 * b)265 static BOOL equal_mtx43(const MtxFx43 *a, const MtxFx43 *b)
266 {
267     return (a->_00 == b->_00 &&
268             a->_01 == b->_01 &&
269             a->_02 == b->_02 &&
270             a->_10 == b->_10 &&
271             a->_11 == b->_11 &&
272             a->_12 == b->_12 &&
273             a->_20 == b->_20 &&
274             a->_21 == b->_21 &&
275             a->_22 == b->_22 && a->_30 == b->_30 && a->_31 == b->_31 && a->_32 == b->_32);
276 }
277 
print_mtx44(const MtxFx44 * m)278 static void print_mtx44(const MtxFx44 *m)
279 {
280 #ifdef SDK_FINALROM
281 #pragma unused( m )
282 #endif
283 
284     OS_Printf("_\n");
285     OS_Printf("%f %f %f %f\n", m->_00 / 4096.0, m->_01 / 4096.0, m->_02 / 4096.0, m->_03 / 4096.0);
286     OS_Printf("%f %f %f %f\n", m->_10 / 4096.0, m->_11 / 4096.0, m->_12 / 4096.0, m->_13 / 4096.0);
287     OS_Printf("%f %f %f %f\n", m->_20 / 4096.0, m->_21 / 4096.0, m->_22 / 4096.0, m->_23 / 4096.0);
288     OS_Printf("%f %f %f %f\n", m->_30 / 4096.0, m->_31 / 4096.0, m->_32 / 4096.0, m->_33 / 4096.0);
289     OS_Printf("_\n");
290 }
291 
equal_mtx44(const MtxFx44 * a,const MtxFx44 * b)292 static BOOL equal_mtx44(const MtxFx44 *a, const MtxFx44 *b)
293 {
294     return (a->_00 == b->_00 &&
295             a->_01 == b->_01 &&
296             a->_02 == b->_02 &&
297             a->_03 == b->_03 &&
298             a->_10 == b->_10 &&
299             a->_11 == b->_11 &&
300             a->_12 == b->_12 &&
301             a->_13 == b->_13 &&
302             a->_20 == b->_20 &&
303             a->_21 == b->_21 &&
304             a->_22 == b->_22 &&
305             a->_23 == b->_23 &&
306             a->_30 == b->_30 && a->_31 == b->_31 && a->_32 == b->_32 && a->_33 == b->_33);
307 }
308 
test_FX_MTX33(void)309 static void test_FX_MTX33(void)
310 {
311     OS_Printf("----- testing fx_mtx33.h -----\n");
312 
313     {
314         MtxFx33 m;
315         MtxFx33 m33;
316         MtxFx43 m43;
317         MtxFx44 m44;
318 
319         const MtxFx33 ans = {
320             FX32_ONE, 0, 0,
321             0, FX32_ONE, 0,
322             0, 0, FX32_ONE
323         };
324         const MtxFx43 ans43 = {
325             FX32_ONE, 0, 0,
326             0, FX32_ONE, 0,
327             0, 0, FX32_ONE,
328             0, 0, 0
329         };
330         const MtxFx44 ans44 = {
331             FX32_ONE, 0, 0, 0,
332             0, FX32_ONE, 0, 0,
333             0, 0, FX32_ONE, 0,
334             0, 0, 0, FX32_ONE
335         };
336 
337         // they must be changed.
338         m43._30 = m43._31 = m43._32 = 1;
339         m44._30 = m44._31 = m44._32 = m44._33 = 1;
340         m44._03 = m44._13 = m44._23 = 1;
341 
342         MTX_Identity33(&m);
343         SDK_ASSERTMSG(equal_mtx33(&m, &ans), "MTX_Identity33");
344         MTX_Copy33(&m, &m33);
345         SDK_ASSERTMSG(equal_mtx33(&m, &m33), "MTX_Copy33");
346         MTX_Copy33To43(&m, &m43);
347         SDK_ASSERTMSG(equal_mtx43(&m43, &ans43), "MTX_Copy33To43");
348         MTX_Copy33To44(&m, &m44);
349         SDK_ASSERTMSG(equal_mtx44(&m44, &ans44), "MTX_Copy33To44");
350     }
351 
352     {
353         MtxFx33 m = {
354             0, 3, 6,
355             1, 4, 7,
356             2, 5, 8
357         };
358         const MtxFx33 ans = {
359             0, 1, 2,
360             3, 4, 5,
361             6, 7, 8
362         };
363         MTX_Transpose33(&m, &m);
364         SDK_ASSERTMSG(equal_mtx33(&m, &ans), "MTX_Transpose33");
365     }
366     {
367         MtxFx33 m;
368         const MtxFx33 ans = {
369             FX32_ONE, 0, 0,
370             0, FX32_ONE * 2, 0,
371             0, 0, FX32_ONE * 3
372         };
373         MTX_Scale33(&m, FX32_ONE, FX32_ONE * 2, FX32_ONE * 3);
374         SDK_ASSERTMSG(equal_mtx33(&m, &ans), "MTX_Scale33");
375     }
376     {
377         MtxFx33 m1;
378         MtxFx33 m2;
379         MtxFx33 m;
380         MtxFx33 ans = {
381             FX32_ONE, 0, 0,
382             0, FX32_ONE, 0,
383             0, 0, FX32_ONE
384         };
385 
386         MTX_RotX33(&m1, FX32_ONE, 0);  // + 90
387         MTX_RotX33(&m2, 0, -FX32_ONE); // + 180
388         MTX_Concat33(&m1, &m2, &m);
389         MTX_Concat33(&m, &m1, &m);
390         SDK_ASSERTMSG(equal_mtx33(&m, &ans), "MTX_RotX33/MTX_Concat33");
391 
392         MTX_RotY33(&m1, FX32_ONE, 0);  // + 90
393         MTX_RotY33(&m2, 0, -FX32_ONE); // + 180
394         MTX_Concat33(&m1, &m2, &m);
395         MTX_Concat33(&m, &m1, &m);
396         SDK_ASSERTMSG(equal_mtx33(&m, &ans), "MTX_RotY33/MTX_Concat33");
397 
398         MTX_RotZ33(&m1, FX32_ONE, 0);  // + 90
399         MTX_RotZ33(&m2, 0, -FX32_ONE); // + 180
400         MTX_Concat33(&m1, &m2, &m);
401         MTX_Concat33(&m, &m1, &m);
402         SDK_ASSERTMSG(equal_mtx33(&m, &ans), "MTX_RotZ33/MTX_Concat33");
403     }
404     {
405 
406         MtxFx33 ans, m;
407         const VecFx32 xAxis = { FX32_ONE, 0, 0 };
408         const VecFx32 yAxis = { 0, FX32_ONE, 0 };
409         const VecFx32 zAxis = { 0, 0, FX32_ONE };
410 
411         MTX_RotX33(&ans, FX32_ONE, 0); // + 90
412         MTX_RotAxis33(&m, &xAxis, FX32_ONE, 0);
413         SDK_ASSERTMSG(equal_mtx33(&ans, &m), "MTX_RotAxis33");
414 
415         MTX_RotY33(&ans, FX32_ONE, 0); // + 90
416         MTX_RotAxis33(&m, &yAxis, FX32_ONE, 0);
417         SDK_ASSERTMSG(equal_mtx33(&ans, &m), "MTX_RotAxis33");
418 
419         MTX_RotZ33(&ans, FX32_ONE, 0); // + 90
420         MTX_RotAxis33(&m, &zAxis, FX32_ONE, 0);
421         SDK_ASSERTMSG(equal_mtx33(&ans, &m), "MTX_RotAxis33");
422     }
423     {
424         MtxFx33 ans, m;
425         int     flag;
426 
427         MTX_RotX33(&ans, FX32_ONE, 0);
428         flag = MTX_Inverse33(&ans, &m);
429         SDK_ASSERTMSG(!flag, "MTX_Inverse33");
430         MTX_RotX33(&ans, -FX32_ONE, 0);
431         SDK_ASSERTMSG(equal_mtx33(&ans, &m), "MTX_Inverse33");
432 
433         MTX_RotY33(&ans, FX32_ONE, 0);
434         flag = MTX_Inverse33(&ans, &m);
435         SDK_ASSERTMSG(!flag, "MTX_Inverse33");
436         MTX_RotY33(&ans, -FX32_ONE, 0);
437         SDK_ASSERTMSG(equal_mtx33(&ans, &m), "MTX_Inverse33");
438 
439         MTX_RotZ33(&ans, FX32_ONE, 0);
440         flag = MTX_Inverse33(&ans, &m);
441         SDK_ASSERTMSG(!flag, "MTX_Inverse33");
442         MTX_RotZ33(&ans, -FX32_ONE, 0);
443         SDK_ASSERTMSG(equal_mtx33(&ans, &m), "MTX_Inverse33");
444     }
445 
446     {
447         int     flag;
448         MtxFx33 m = {
449             FX32_ONE, FX32_ONE, FX32_ONE,
450             FX32_ONE, FX32_ONE, FX32_ONE,
451             FX32_ONE, FX32_ONE, FX32_ONE
452         };
453         MtxFx33 ans = {
454             FX32_ONE, FX32_ONE, FX32_ONE,
455             FX32_ONE, FX32_ONE, FX32_ONE,
456             FX32_ONE, FX32_ONE, FX32_ONE
457         };
458         flag = MTX_Inverse33(&m, &m);
459         SDK_ASSERTMSG(flag, "MTX_Inverse33");
460         SDK_ASSERTMSG(equal_mtx33(&ans, &m), "MTX_Inverse33");
461     }
462 
463     {
464         MtxFx33 m = {
465             FX32_ONE, FX32_ONE * 2, FX32_ONE * 3,
466             FX32_ONE * 4, FX32_ONE * 5, FX32_ONE * 6,
467             FX32_ONE * 7, FX32_ONE * 8, FX32_ONE * 9
468         };
469         VecFx32 vec = { FX32_ONE, FX32_ONE, FX32_ONE };
470         VecFx32 ans = { FX32_ONE * 12, FX32_ONE * 15, FX32_ONE * 18 };
471         MTX_MultVec33(&vec, &m, &vec);
472         SDK_ASSERTMSG(vec.x == ans.x && vec.y == ans.y && vec.z == ans.z, "MTX_MultVec33");
473     }
474 
475     OS_Printf(" done.\n");
476 }
477 
test_FX_MTX43(void)478 static void test_FX_MTX43(void)
479 {
480     OS_Printf("----- testing fx_mtx43.h -----\n");
481 
482     {
483         MtxFx43 m;
484         MtxFx33 m33;
485         MtxFx43 m43;
486         MtxFx44 m44;
487         const MtxFx33 ans33 = {
488             FX32_ONE, 0, 0,
489             0, FX32_ONE, 0,
490             0, 0, FX32_ONE
491         };
492         const MtxFx43 ans43 = {
493             FX32_ONE, 0, 0,
494             0, FX32_ONE, 0,
495             0, 0, FX32_ONE,
496             0, 0, 0
497         };
498         const MtxFx44 ans44 = {
499             FX32_ONE, 0, 0, 0,
500             0, FX32_ONE, 0, 0,
501             0, 0, FX32_ONE, 0,
502             0, 0, 0, FX32_ONE
503         };
504         m44._03 = m44._13 = m44._23 = m44._33 = 1;
505 
506         MTX_Identity43(&m);
507         SDK_ASSERTMSG(equal_mtx43(&m, &ans43), "MTX_Identity43");
508         MTX_Copy43(&m, &m43);
509         SDK_ASSERTMSG(equal_mtx43(&m, &m43), "MTX_Copy43");
510         MTX_Copy43To33(&m, &m33);
511         SDK_ASSERTMSG(equal_mtx33(&m33, &ans33), "MTX_Copy43To33");
512         MTX_Copy43To44(&m, &m44);
513         SDK_ASSERTMSG(equal_mtx44(&m44, &ans44), "MTX_Copy43To44");
514     }
515 
516     {
517         MtxFx43 m = {
518             0, 3, 6,
519             1, 4, 7,
520             2, 5, 8,
521             9, 10, 11
522         };
523         const MtxFx43 ans = {
524             0, 1, 2,
525             3, 4, 5,
526             6, 7, 8,
527             0, 0, 0
528         };
529         MTX_Transpose43(&m, &m);
530         SDK_ASSERTMSG(equal_mtx43(&m, &ans), "MTX_Transpose43");
531     }
532     {
533         MtxFx43 m;
534         const MtxFx43 ans = {
535             FX32_ONE, 0, 0,
536             0, FX32_ONE * 2, 0,
537             0, 0, FX32_ONE * 3,
538             0, 0, 0
539         };
540         MTX_Scale43(&m, FX32_ONE, FX32_ONE * 2, FX32_ONE * 3);
541         SDK_ASSERTMSG(equal_mtx43(&m, &ans), "MTX_Scale43");
542     }
543     {
544         MtxFx43 m1;
545         MtxFx43 m2;
546         MtxFx43 m;
547         MtxFx43 ans = {
548             FX32_ONE, 0, 0,
549             0, FX32_ONE, 0,
550             0, 0, FX32_ONE,
551             0, 0, 0
552         };
553 
554         MTX_RotX43(&m1, FX32_ONE, 0);  // + 90
555         MTX_RotX43(&m2, 0, -FX32_ONE); // + 180
556         MTX_Concat43(&m1, &m2, &m);
557         MTX_Concat43(&m, &m1, &m);
558         SDK_ASSERTMSG(equal_mtx43(&m, &ans), "MTX_RotX43/MTX_Concat43");
559 
560         MTX_RotY43(&m1, FX32_ONE, 0);  // + 90
561         MTX_RotY43(&m2, 0, -FX32_ONE); // + 180
562         MTX_Concat43(&m1, &m2, &m);
563         MTX_Concat43(&m, &m1, &m);
564         SDK_ASSERTMSG(equal_mtx43(&m, &ans), "MTX_RotY43/MTX_Concat43");
565 
566         MTX_RotZ43(&m1, FX32_ONE, 0);  // + 90
567         MTX_RotZ43(&m2, 0, -FX32_ONE); // + 180
568         MTX_Concat43(&m1, &m2, &m);
569         MTX_Concat43(&m, &m1, &m);
570         SDK_ASSERTMSG(equal_mtx43(&m, &ans), "MTX_RotZ43/MTX_Concat43");
571     }
572     {
573         MtxFx43 ans, m;
574         const VecFx32 xAxis = { FX32_ONE, 0, 0 };
575         const VecFx32 yAxis = { 0, FX32_ONE, 0 };
576         const VecFx32 zAxis = { 0, 0, FX32_ONE };
577 
578         MTX_RotX43(&ans, FX32_ONE, 0); // + 90
579         MTX_RotAxis43(&m, &xAxis, FX32_ONE, 0);
580         SDK_ASSERTMSG(equal_mtx43(&ans, &m), "MTX_RotAxis43");
581 
582         MTX_RotY43(&ans, FX32_ONE, 0); // + 90
583         MTX_RotAxis43(&m, &yAxis, FX32_ONE, 0);
584         SDK_ASSERTMSG(equal_mtx43(&ans, &m), "MTX_RotAxis43");
585 
586         MTX_RotZ43(&ans, FX32_ONE, 0); // + 90
587         MTX_RotAxis43(&m, &zAxis, FX32_ONE, 0);
588         SDK_ASSERTMSG(equal_mtx43(&ans, &m), "MTX_RotAxis43");
589 
590     }
591     {
592         MtxFx43 ans, m;
593         int     flag;
594 
595         MTX_RotX43(&ans, FX32_ONE, 0);
596         flag = MTX_Inverse43(&ans, &m);
597         SDK_ASSERTMSG(!flag, "MTX_Inverse43");
598         MTX_RotX43(&ans, -FX32_ONE, 0);
599         SDK_ASSERTMSG(equal_mtx43(&ans, &m), "MTX_Inverse43");
600 
601         MTX_RotY43(&ans, FX32_ONE, 0);
602         flag = MTX_Inverse43(&ans, &m);
603         SDK_ASSERTMSG(!flag, "MTX_Inverse43");
604         MTX_RotY43(&ans, -FX32_ONE, 0);
605         SDK_ASSERTMSG(equal_mtx43(&ans, &m), "MTX_Inverse43");
606 
607         MTX_RotZ43(&ans, FX32_ONE, 0);
608         flag = MTX_Inverse43(&ans, &m);
609         SDK_ASSERTMSG(!flag, "MTX_Inverse43");
610         MTX_RotZ43(&ans, -FX32_ONE, 0);
611         SDK_ASSERTMSG(equal_mtx43(&ans, &m), "MTX_Inverse43");
612     }
613 
614     {
615         int     flag;
616         MtxFx43 m = {
617             FX32_ONE, FX32_ONE, FX32_ONE,
618             FX32_ONE, FX32_ONE, FX32_ONE,
619             FX32_ONE, FX32_ONE, FX32_ONE,
620             FX32_ONE, FX32_ONE, FX32_ONE
621         };
622         MtxFx43 ans = {
623             FX32_ONE, FX32_ONE, FX32_ONE,
624             FX32_ONE, FX32_ONE, FX32_ONE,
625             FX32_ONE, FX32_ONE, FX32_ONE,
626             FX32_ONE, FX32_ONE, FX32_ONE
627         };
628         flag = MTX_Inverse43(&m, &m);
629         SDK_ASSERTMSG(flag, "MTX_Inverse43");
630         SDK_ASSERTMSG(equal_mtx43(&ans, &m), "MTX_Inverse43");
631     }
632 
633     OS_Printf(" done.\n");
634 }
635 
test_FX_MTX44(void)636 static void test_FX_MTX44(void)
637 {
638     OS_Printf("----- testing fx_mtx44.h -----\n");
639 
640     {
641         MtxFx44 m44;
642         MtxFx43 m43;
643         MtxFx33 m33;
644         MtxFx44 m;
645         const MtxFx33 ans33 = {
646             FX32_ONE, 0, 0,
647             0, FX32_ONE, 0,
648             0, 0, FX32_ONE
649         };
650         const MtxFx43 ans43 = {
651             FX32_ONE, 0, 0,
652             0, FX32_ONE, 0,
653             0, 0, FX32_ONE,
654             0, 0, 0
655         };
656         const MtxFx44 ans44 = {
657             FX32_ONE, 0, 0, 0,
658             0, FX32_ONE, 0, 0,
659             0, 0, FX32_ONE, 0,
660             0, 0, 0, FX32_ONE
661         };
662 
663         MTX_Identity44(&m);
664         SDK_ASSERTMSG(equal_mtx44(&m, &ans44), "MTX_Identity44");
665         MTX_Copy44(&m, &m44);
666         SDK_ASSERTMSG(equal_mtx44(&m, &m44), "MTX_Copy44");
667         MTX_Copy44To33(&m, &m33);
668         SDK_ASSERTMSG(equal_mtx33(&m33, &ans33), "MTX_Copy44To33");
669         MTX_Copy44To43(&m, &m43);
670         SDK_ASSERTMSG(equal_mtx43(&m43, &ans43), "MTX_Copy44To43");
671     }
672 
673     {
674         MtxFx44 m = {
675             0, 4, 8, 12,
676             1, 5, 9, 13,
677             2, 6, 10, 14,
678             3, 7, 11, 15
679         };
680         const MtxFx44 ans = {
681             0, 1, 2, 3,
682             4, 5, 6, 7,
683             8, 9, 10, 11,
684             12, 13, 14, 15
685         };
686         MTX_Transpose44(&m, &m);
687         SDK_ASSERTMSG(equal_mtx44(&m, &ans), "MTX_Transpose44");
688     }
689     {
690         MtxFx44 m;
691         const MtxFx44 ans = {
692             FX32_ONE, 0, 0, 0,
693             0, FX32_ONE * 2, 0, 0,
694             0, 0, FX32_ONE * 3, 0,
695             0, 0, 0, FX32_ONE
696         };
697         MTX_Scale44(&m, FX32_ONE, FX32_ONE * 2, FX32_ONE * 3);
698         SDK_ASSERTMSG(equal_mtx44(&m, &ans), "MTX_Scale44");
699     }
700     {
701         MtxFx44 m1;
702         MtxFx44 m2;
703         MtxFx44 m;
704         MtxFx44 ans = {
705             FX32_ONE, 0, 0, 0,
706             0, FX32_ONE, 0, 0,
707             0, 0, FX32_ONE, 0,
708             0, 0, 0, FX32_ONE
709         };
710         MTX_RotX44(&m1, FX32_ONE, 0);  // + 90
711         MTX_RotX44(&m2, 0, -FX32_ONE); // + 180
712         MTX_Concat44(&m1, &m2, &m);
713         MTX_Concat44(&m, &m1, &m);
714         print_mtx44(&m);
715 
716         SDK_ASSERTMSG(equal_mtx44(&m, &ans), "MTX_RotX44/MTX_Concat44");
717 
718         MTX_RotY44(&m1, FX32_ONE, 0);  // + 90
719         MTX_RotY44(&m2, 0, -FX32_ONE); // + 180
720         MTX_Concat44(&m1, &m2, &m);
721         MTX_Concat44(&m, &m1, &m);
722         SDK_ASSERTMSG(equal_mtx44(&m, &ans), "MTX_RotY44/MTX_Concat44");
723 
724         MTX_RotZ44(&m1, FX32_ONE, 0);  // + 90
725         MTX_RotZ44(&m2, 0, -FX32_ONE); // + 180
726         MTX_Concat44(&m1, &m2, &m);
727         MTX_Concat44(&m, &m1, &m);
728         SDK_ASSERTMSG(equal_mtx44(&m, &ans), "MTX_RotZ44/MTX_Concat44");
729     }
730     {
731         MtxFx44 ans, m;
732         const VecFx32 xAxis = { FX32_ONE, 0, 0 };
733         const VecFx32 yAxis = { 0, FX32_ONE, 0 };
734         const VecFx32 zAxis = { 0, 0, FX32_ONE };
735 
736         MTX_RotX44(&ans, FX32_ONE, 0); // + 90
737         MTX_RotAxis44(&m, &xAxis, FX32_ONE, 0);
738         SDK_ASSERTMSG(equal_mtx44(&ans, &m), "MTX_RotAxis44");
739 
740         MTX_RotY44(&ans, FX32_ONE, 0); // + 90
741         MTX_RotAxis44(&m, &yAxis, FX32_ONE, 0);
742         SDK_ASSERTMSG(equal_mtx44(&ans, &m), "MTX_RotAxis44");
743 
744         MTX_RotZ44(&ans, FX32_ONE, 0); // + 90
745         MTX_RotAxis44(&m, &zAxis, FX32_ONE, 0);
746         SDK_ASSERTMSG(equal_mtx44(&ans, &m), "MTX_RotAxis44");
747     }
748 
749     OS_Printf(" done.\n");
750 }
751 
test_Table(void)752 static void test_Table(void)
753 {
754     u16     i;
755     fx32    s, c;
756     OS_Printf("----- testing FX_SinIdx, FX_CosIdx -----\n");
757 
758     for (i = 0; i < 4096; ++i)
759     {
760         s = FX_SinIdx((u16)(i * 16));
761         c = FX_CosIdx((u16)(i * 16));
762         SDK_ASSERTMSG(testTable[i * 2] == s || testTable[i * 2 + 1] == c, "FX_SinIdx, FX_CosIdx\n");
763     }
764 
765     OS_Printf(" done.\n");
766 }
767 
NitroMain(void)768 void NitroMain(void)
769 {
770     OS_Init();
771     OS_Printf("OS_Init() done.\n");
772     FX_Init();
773     OS_Printf("FX_Init() done.\n");
774 
775 
776 
777     test_FX_VEC();
778     test_FX_TRIG();
779     test_FX_CP();
780     test_FX_MTX33();
781     test_FX_MTX43();
782     test_FX_MTX44();
783     test_Table();
784 
785     // appended test cases
786     VECTest_Appended();
787     MTXTest_appended();
788 
789 
790     OS_Printf("all tests passed\n");
791     while (1)
792         ;
793 }
794