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