1 /*
2  * Copyright (c) 2006-2012 Hypertriton, Inc. <http://hypertriton.com/>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
17  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
22  * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24 
25 /*
26  * Basic matrix operations.
27  */
28 
29 #include <agar/core/core.h>
30 #include <agar/math/m.h>
31 
32 #include <string.h>
33 
34 const M_MatrixOps *mMatOps = NULL;
35 const M_MatrixOps44 *mMatOps44 = NULL;
36 
37 void
M_MatrixInitEngine(void)38 M_MatrixInitEngine(void)
39 {
40 	mMatOps = &mMatOps_FPU;
41 	mMatOps44 = &mMatOps44_FPU;
42 #ifdef HAVE_SSE
43 	if (agCPU.ext & AG_EXT_SSE) {
44 		mMatOps44 = &mMatOps44_SSE;
45 	}
46 # ifdef INLINE_SSE
47 	else {
48 		AG_FatalError("Compiled for SSE, but no SSE support in CPU! "
49 		              "(recompile Agar without: --with-sse-inline)");
50 	}
51 # endif
52 # ifdef HAVE_SSE2
53 	if (!(agCPU.ext & AG_EXT_SSE2)) {
54 #  ifdef INLINE_SSE
55 		AG_FatalError("Compiled for SSE2, but CPU only supports SSE1! "
56 			      "(recompile Agar with: --without-{sse2,sse3})");
57 #  else
58 		AG_Verbose("Compiled for SSE2, but CPU only supports SSE1! "
59 			   "(recompile Agar with: --without-{sse2,sse3})\n");
60 		mMatOps44 = &mMatOps44_FPU;
61 #  endif
62 	}
63 # endif
64 # ifdef HAVE_SSE3
65 	if (!(agCPU.ext & AG_EXT_SSE3)) {
66 #  ifdef INLINE_SSE
67 		AG_FatalError("Compiled for SSE3, but CPU only supports SSE2! "
68 			      "(recompile Agar with: --without-sse3)");
69 #  else
70 		AG_Verbose("Compiled for SSE3, but CPU only supports SSE2! "
71 			   "(recompile Agar with: --without-sse3)\n");
72 		mMatOps44 = &mMatOps44_FPU;
73 #  endif
74 	}
75 # endif
76 #endif /* HAVE_SSE */
77 }
78 
79 M_Matrix44
M_ReadMatrix44(AG_DataSource * ds)80 M_ReadMatrix44(AG_DataSource *ds)
81 {
82 	M_Matrix44 A;
83 
84 	M_ReadMatrix44v(ds, &A);
85 	return (A);
86 }
87 
88 void
M_ReadMatrix44v(AG_DataSource * ds,M_Matrix44 * A)89 M_ReadMatrix44v(AG_DataSource *ds, M_Matrix44 *A)
90 {
91 	int i, j;
92 
93 	for (i = 0; i < 4; i++) {
94 		for (j = 0; i < 4; i++) {
95 #ifdef HAVE_SSE
96 			A->m[i][j] = (float)M_ReadReal(ds);
97 #else
98 			A->m[i][j] = M_ReadReal(ds);
99 #endif
100 		}
101 	}
102 }
103 
104 void
M_WriteMatrix44(AG_DataSource * ds,const M_Matrix44 * A)105 M_WriteMatrix44(AG_DataSource *ds, const M_Matrix44 *A)
106 {
107 	int i, j;
108 
109 	for (i = 0; i < 4; i++) {
110 		for (j = 0; i < 4; i++) {
111 #ifdef HAVE_SSE
112 			AG_WriteUint8(ds, 1);		/* Single-precision */
113 			AG_WriteFloat(ds, A->m[i][j]);
114 #else
115 			M_WriteReal(ds, A->m[i][j]);
116 #endif
117 		}
118 	}
119 }
120