1 /*---------------------------------------------------------------------------*
2   Project: matrix vector Library
3   File:    mtxstack.c
4 
5   Copyright 1998-2011 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 
12  *---------------------------------------------------------------------------*/
13 
14 #include <math.h>
15 #include <stdio.h>
16 #include <cafe/mtx.h>
17 #include <cafe/mtx/mtx44.h>
18 #include "mtxAssert.h"
19 #include "mtx44Assert.h"
20 
21 /*---------------------------------------------------------------------*
22 
23                              STACK SECTION
24 
25 *---------------------------------------------------------------------*/
26 
27 
28 /*---------------------------------------------------------------------*
29 
30 Name:           MTXInitStack
31 
32 Description:    initializes a matrix stack size and stack ptr from
33                 a previously allocated stack.
34 
35 
36 Arguments:      sPtr      ptr to MtxStack structure to be initialized.
37 
38                 numMtx    number of matrices in the stack.
39 
40                 note:     the stack (array) memory must have been
41                           previously allocated.
42                           MtxVec.h provides a macro
43                           ( MTXAllocStack( sPtr, numMtx ) )
44                           to accomplish this using OSAlloc().
45 
46 
47 
48 Return:         none.
49 
50 *---------------------------------------------------------------------*/
MTXInitStack(MtxStack * sPtr,u32 numMtx)51 void MTXInitStack( MtxStack *sPtr, u32 numMtx )
52 {
53 
54 
55     ASSERTMSG( (sPtr != 0),              MTX_INITSTACK_1     );
56     ASSERTMSG( (sPtr->stackBase != 0),   MTX_INITSTACK_2     );
57     ASSERTMSG( (numMtx != 0),            MTX_INITSTACK_3     );
58 
59 
60     sPtr->numMtx   = numMtx;
61     sPtr->stackPtr = NULL;
62 
63 }
64 
65 /*---------------------------------------------------------------------*
66 
67 Name:           MTXPush
68 
69 Description:    copy a matrix to stack pointer + 1.
70                 increment stack pointer.
71 
72 
73 Arguments:      sPtr    ptr to MtxStack structure.
74 
75                 m       matrix to copy into (stack pointer + 1) location.
76 
77 
78 Return:         stack pointer.
79 
80 *---------------------------------------------------------------------*/
MTXPush(MtxStack * sPtr,MTX_CONST Mtx m)81 MtxPtr MTXPush ( MtxStack *sPtr, MTX_CONST Mtx m )
82 {
83 
84 
85     ASSERTMSG( (sPtr != 0),             MTX_PUSH_1    );
86     ASSERTMSG( (sPtr->stackBase != 0),  MTX_PUSH_2    );
87     ASSERTMSG( (m != 0),                MTX_PUSH_3    );
88 
89 
90     if( sPtr->stackPtr == NULL )
91     {
92         sPtr->stackPtr = sPtr->stackBase;
93         MTXCopy( m, sPtr->stackPtr );
94     }
95 
96     else
97     {
98         // check for stack overflow
99         if( (u32)((sPtr->stackPtr - sPtr->stackBase) / MTX_PTR_OFFSET) >=
100             (sPtr->numMtx - 1) )
101         {
102             ASSERTMSG( 0,  MTX_PUSH_4  );
103         }
104 
105     MTXCopy( m, (sPtr->stackPtr + MTX_PTR_OFFSET) );
106     sPtr->stackPtr += MTX_PTR_OFFSET;
107     }
108 
109 
110     return sPtr->stackPtr;
111 }
112 
113 /*---------------------------------------------------------------------*
114 
115 Name:           MTXPushFwd
116 
117 Description:    concatenate a matrix with the current top of the stack,
118                 increment the stack ptr and push the resultant matrix to
119                 the new top of stack.
120 
121                 this is intended for use in building forward transformations,
122                 so concatenation is post-order
123                 ( top of stack x mtx ) = ( top of stack + 1 ).
124 
125 
126 Arguments:      sPtr    ptr to MtxStack structure.
127 
128                 m        matrix to concatenate with stack ptr and
129                          push to stack ptr + 1.
130 
131 
132 Return:         stack pointer.
133 
134 *---------------------------------------------------------------------*/
MTXPushFwd(MtxStack * sPtr,MTX_CONST Mtx m)135 MtxPtr MTXPushFwd ( MtxStack *sPtr, MTX_CONST Mtx m )
136 {
137 
138     ASSERTMSG( (sPtr != 0),             MTX_PUSHFWD_1  );
139     ASSERTMSG( (sPtr->stackBase != 0),  MTX_PUSHFWD_2  );
140     ASSERTMSG( (m != 0),                MTX_PUSHFWD_3  );
141 
142 
143     if( sPtr->stackPtr == NULL )
144     {
145         sPtr->stackPtr = sPtr->stackBase;
146         MTXCopy( m, sPtr->stackPtr );
147     }
148 
149     else
150     {
151         // check for stack overflow
152         if( (u32)((sPtr->stackPtr - sPtr->stackBase) / MTX_PTR_OFFSET) >=
153             (sPtr->numMtx - 1) )
154         {
155             ASSERTMSG( 0,  MTX_PUSHFWD_4  );
156         }
157 
158         MTXConcat( sPtr->stackPtr, m, ( sPtr->stackPtr + MTX_PTR_OFFSET ) );
159         sPtr->stackPtr += MTX_PTR_OFFSET;
160     }
161 
162 
163     return sPtr->stackPtr;
164 }
165 
166 /*---------------------------------------------------------------------*
167 
168 Name:           MTXPushInv
169 
170 Description:    take a matrix, compute its inverse and concatenate that
171                 inverse with the current top of the stack,
172                 increment the stack ptr and push the resultant matrix to
173                 the new top of stack.
174 
175                 this is intended for use in building inverse transformations,
176                 so concatenation is pre-order
177                 ( mtx x top of stack ) = ( top of stack + 1 ).
178 
179 
180 Arguments:      sPtr    ptr to MtxStack structure.
181 
182                 m       matrix to concatenate with stack ptr and
183                         push to stack ptr + 1.
184 
185                         m is not modified by this function.
186 
187 
188 Return:         stack pointer.
189 
190 *---------------------------------------------------------------------*/
MTXPushInv(MtxStack * sPtr,MTX_CONST Mtx m)191 MtxPtr    MTXPushInv ( MtxStack *sPtr, MTX_CONST Mtx m )
192 {
193 
194     Mtx mInv;
195 
196 
197     ASSERTMSG( (sPtr != 0),             MTX_PUSHINV_1  );
198     ASSERTMSG( (sPtr->stackBase != 0),  MTX_PUSHINV_2  );
199     ASSERTMSG( (m != 0),                MTX_PUSHINV_3  );
200 
201 
202     MTXInverse( m, mInv );
203 
204 
205     if( sPtr->stackPtr == NULL )
206     {
207         sPtr->stackPtr = sPtr->stackBase;
208         MTXCopy( mInv, sPtr->stackPtr );
209     }
210 
211     else
212     {
213         // check for stack overflow
214         if( (u32)((sPtr->stackPtr - sPtr->stackBase) / MTX_PTR_OFFSET) >=
215             (sPtr->numMtx - 1) )
216         {
217             ASSERTMSG( 0,  MTX_PUSHINV_4  );
218         }
219 
220         MTXConcat( mInv, sPtr->stackPtr, ( sPtr->stackPtr + MTX_PTR_OFFSET ) );
221         sPtr->stackPtr += MTX_PTR_OFFSET;
222     }
223 
224 
225     return sPtr->stackPtr;
226 }
227 
228 /*---------------------------------------------------------------------*
229 
230 Name:           MTXPushInvXpose
231 
232 Description:    take a matrix, compute its inverse-transpose and concatenate it
233                 with the current top of the stack,
234                 increment the stack ptr and push the resultant matrix to
235                 the new top of stack.
236 
237                 this is intended for use in building an inverse-transpose
238                 matrix for forward transformations of normals, so
239                 concatenation is post-order.
240                 ( top of stack x mtx ) = ( top of stack + 1 ).
241 
242 
243 Arguments:      sPtr   ptr to MtxStack structure.
244 
245                 m      matrix to concatenate with stack ptr and
246                        push to stack ptr + 1.
247 
248                        m is not modified by this function.
249 
250 
251 Return:         stack pointer.
252 
253 *---------------------------------------------------------------------*/
MTXPushInvXpose(MtxStack * sPtr,MTX_CONST Mtx m)254 MtxPtr MTXPushInvXpose ( MtxStack *sPtr, MTX_CONST Mtx m )
255 {
256 
257     Mtx mIT;
258 
259 
260     ASSERTMSG( (sPtr != 0),             MTX_PUSHINVXPOSE_1    );
261     ASSERTMSG( (sPtr->stackBase != 0),  MTX_PUSHINVXPOSE_2    );
262     ASSERTMSG( (m != 0),                MTX_PUSHINVXPOSE_3    );
263 
264 
265     MTXInverse(     m, mIT );
266     MTXTranspose( mIT, mIT );
267 
268 
269     if( sPtr->stackPtr == NULL )
270     {
271         sPtr->stackPtr = sPtr->stackBase;
272         MTXCopy( mIT, sPtr->stackPtr );
273     }
274 
275     else
276     {
277         // check for stack overflow
278         if( (u32)((sPtr->stackPtr - sPtr->stackBase) / MTX_PTR_OFFSET) >=
279             (sPtr->numMtx - 1) )
280         {
281             ASSERTMSG( 0,  MTX_PUSHINVXPOSE_4  );
282         }
283 
284         MTXConcat( sPtr->stackPtr, mIT, ( sPtr->stackPtr + MTX_PTR_OFFSET ) );
285         sPtr->stackPtr += MTX_PTR_OFFSET;
286     }
287 
288 
289     return sPtr->stackPtr;
290 }
291 
292 /*---------------------------------------------------------------------*
293 
294 Name:           MTXPop
295 
296 Description:    decrement the stack pointer
297 
298 
299 Arguments:      sPtr        pointer to stack structure
300 
301 
302 Return:         stack pointer.
303 
304 *---------------------------------------------------------------------*/
MTXPop(MtxStack * sPtr)305 MtxPtr MTXPop ( MtxStack *sPtr )
306 {
307 
308 
309     ASSERTMSG( (sPtr != 0),               MTX_POP_1  );
310     ASSERTMSG( (sPtr->stackBase != 0),    MTX_POP_2  );
311 
312 
313     if( sPtr->stackPtr == NULL )
314     {
315         return NULL;
316     }
317 
318     else if( sPtr->stackBase == sPtr->stackPtr )
319     {
320         sPtr->stackPtr = NULL;
321         return NULL;
322     }
323     else
324     {
325         sPtr->stackPtr -= MTX_PTR_OFFSET;
326         return sPtr->stackPtr;
327     }
328 
329 }
330 
331 /*---------------------------------------------------------------------*
332 
333 Name:           MTXGetStackPtr
334 
335 Description:    return the stack pointer
336 
337 
338 Arguments:      sPtr pointer to stack structure
339 
340 
341 Return:         stack pointer.
342 
343 *---------------------------------------------------------------------*/
MTXGetStackPtr(const MtxStack * sPtr)344 MtxPtr MTXGetStackPtr( const MtxStack *sPtr )
345 {
346 
347     ASSERTMSG( (sPtr != 0),               MTX_GETSTACKPTR_1  );
348     ASSERTMSG( (sPtr->stackBase != 0),    MTX_GETSTACKPTR_2  );
349 
350     return sPtr->stackPtr;
351 
352 }
353 
354 
355 /*===========================================================================*/
356