1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - GX -
3 File: g3x.c
4
5 Copyright 2003-2008 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 $Date:: 2008-09-17#$
14 $Rev: 8556 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17 #include <nitro/gx/g3x.h>
18 #include <nitro/gx/g3imm.h>
19 #include <nitro/gx/gx.h>
20 #include <nitro/gx/gx_bgcnt.h>
21 #ifdef SDK_NITRO
22 #include <nitro/hw/ARM9/ioreg_GX.h>
23 #include <nitro/hw/ARM9/ioreg_G3.h>
24 #include <nitro/hw/ARM9/ioreg_G2.h>
25 #else
26 #include <twl/hw/ARM9/ioreg_GX.h>
27 #include <twl/hw/ARM9/ioreg_G3.h>
28 #include <twl/hw/ARM9/ioreg_G2.h>
29 #endif
30 #include <nitro/fx/fx_const.h>
31 #include <nitro/mi/dma.h>
32
33 #ifdef SDK_TWL
34 #include <twl/mi/common/dma.h>
35 #endif
36
37 #include <nitro/mi/memory.h>
38 #include "gxasm.h"
39
40
41 /*---------------------------------------------------------------------------*
42 Static function prototype definition.
43 *---------------------------------------------------------------------------*/
44 static asm void GXi_NopClearFifo128_( register void* pDest );
45
46
47 /*---------------------------------------------------------------------------*
48 Name: G3X_Init
49
50 Description: Initializes the registers for 3D graphics.
51
52 Arguments: none
53
54 Returns: none
55 *---------------------------------------------------------------------------*/
G3X_Init()56 void G3X_Init()
57 {
58 #ifdef SDK_DEBUG
59 {
60 GXPower power = GX_GetPower();
61 SDK_WARNING(power & GX_POWER_RE, "GX_POWER_RE is off now, registers for it not initialized.");
62 SDK_WARNING(power & GX_POWER_GE, "GX_POWER_GE is off now, registers for it not initialized.");
63 }
64 #endif
65
66 G3X_ClearFifo();
67 G3_End();
68
69 while ( G3X_IsGeometryBusy() ) { }
70
71 // clear registers before settings
72 reg_G3X_DISP3DCNT = 0;
73 reg_G3X_GXSTAT = 0;
74
75 // Horizontal Offset
76 reg_G2_BG0OFS = 0;
77
78 // DISP3DCNT
79 G3X_ResetListRamOverflow();
80 G3X_ResetLineBufferUnderflow();
81 G3X_SetShading(GX_SHADING_TOON);
82 G3X_AntiAlias(TRUE);
83 G3X_AlphaTest(FALSE, 0);
84
85 // GXSTAT
86 G3X_ResetMtxStackOverflow();
87
88 G3X_SetFifoIntrCond(GX_FIFOINTR_COND_EMPTY);
89
90 // matrix stack and GXSTAT
91 G3X_InitMtxStack();
92
93 // G3X_SetClearColor(GX_RGB(0, 0, 0), 0, 0x7fff, 0, FALSE);
94 reg_G3X_CLEAR_COLOR = 0;
95 reg_G3X_CLEAR_DEPTH = 0x7fff;
96
97 // G3X_SetClearImageOffset(0, 0);
98 reg_G3X_CLRIMAGE_OFFSET = 0;
99
100 // G3X_SetFogColor(GX_RGB(0, 0, 0), 0);
101 reg_G3X_FOG_COLOR = 0;
102
103 // FOG_OFFSET
104 reg_G3X_FOG_OFFSET = 0;
105
106 // BG0CNT
107 G2_SetBG0Priority(0);
108
109 G3X_InitTable();
110
111 // POLYGON_ATTR
112 G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_BACK, 0, 31, GX_POLYGON_ATTR_MISC_NONE);
113
114 // TEXIMAGE_PARAM
115 G3_TexImageParam(GX_TEXFMT_NONE,
116
117 GX_TEXGEN_NONE,
118 GX_TEXSIZE_S8, GX_TEXSIZE_T8, GX_TEXREPEAT_NONE, GX_TEXFLIP_NONE, GX_TEXPLTTCOLOR0_USE, 0);
119
120 // TEXPLTT_BASE
121 G3_Direct1(G3OP_TEXPLTT_BASE, 0);
122 }
123
124
125 /*---------------------------------------------------------------------------*
126 Name: G3X_Reset
127
128 Description: Resets FIFO, matrix stacks, overflow flags,
129 and attributes of polygons.
130
131 Arguments: none
132
133 Returns: none
134 *---------------------------------------------------------------------------*/
G3X_Reset()135 void G3X_Reset()
136 {
137 #ifdef SDK_DEBUG
138 {
139 GXPower power = GX_GetPower();
140 SDK_WARNING(power & GX_POWER_RE,
141 "GX_POWER_RE is off now, registers for it not initialized.");
142 SDK_WARNING(power & GX_POWER_GE,
143 "GX_POWER_GE is off now, registers for it not initialized.");
144 }
145 #endif
146 // DO NOT REMOVE THIS
147 // Swapbuffers may be canceled if you remove.
148 while (G3X_IsGeometryBusy())
149 {
150 }
151
152 G3X_ResetMtxStackOverflow();
153 G3X_ResetListRamOverflow();
154 G3X_ResetLineBufferUnderflow();
155
156 G3X_ResetMtxStack();
157 // POLYGON_ATTR
158 G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_BACK, 0, 31,
159 GX_POLYGON_ATTR_MISC_NONE);
160
161 // TEXIMAGE_PARAM
162 G3_TexImageParam(GX_TEXFMT_NONE,
163 GX_TEXGEN_NONE,
164 GX_TEXSIZE_S8, GX_TEXSIZE_T8, GX_TEXREPEAT_NONE, GX_TEXFLIP_NONE,
165 GX_TEXPLTTCOLOR0_USE, 0);
166
167 // TEXPLTT_BASE
168 G3_Direct1(G3OP_TEXPLTT_BASE, 0);
169 }
170
171
172
173 /*---------------------------------------------------------------------------*
174 Name: G3X_ClearFifo
175
176 Description: Clear FIFO
177
178 Arguments: none
179
180 Returns: none
181 *---------------------------------------------------------------------------*/
G3X_ClearFifo(void)182 void G3X_ClearFifo(void)
183 {
184
185 GXi_NopClearFifo128_((void *)®_G3X_GXFIFO);
186 // G3_End();
187
188 while (G3X_IsGeometryBusy())
189 {
190 }
191 }
192
193
194 /*---------------------------------------------------------------------------*
195 Name: G3X_InitMtxStack
196
197 Description: Initializes the level of matrix stacks and the current matrices.
198
199 Arguments: none
200
201 Returns: none
202 *---------------------------------------------------------------------------*/
G3X_InitMtxStack()203 void G3X_InitMtxStack()
204 {
205 s32 levelPV;
206 s32 levelPJ;
207 #ifdef SDK_DEBUG
208 {
209 GXPower power = GX_GetPower();
210 SDK_WARNING(power & GX_POWER_GE,
211 "GX_POWER_GE is off now, registers for it not initialized.");
212 }
213 #endif
214 G3X_ResetMtxStackOverflow();
215
216 while (G3X_GetMtxStackLevelPV(&levelPV))
217 ;
218 while (G3X_GetMtxStackLevelPJ(&levelPJ))
219 ;
220
221 G3_MtxMode(GX_MTXMODE_TEXTURE);
222 G3_Identity();
223
224 G3_MtxMode(GX_MTXMODE_PROJECTION);
225 if (levelPJ != 0)
226 {
227 G3_PopMtx(levelPJ);
228 }
229 G3_Identity();
230
231 G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
232 G3_PopMtx(levelPV);
233 G3_Identity();
234
235 }
236
237
238 /*---------------------------------------------------------------------------*
239 Name: G3X_ResetMtxStack
240
241 Description: Initializes the level of matrix stacks,
242 and the current matrices except the current projection matrix.
243
244 Arguments: none
245
246 Returns: none
247 *---------------------------------------------------------------------------*/
G3X_ResetMtxStack()248 void G3X_ResetMtxStack()
249 {
250 s32 levelPV;
251 s32 levelPJ;
252 #ifdef SDK_DEBUG
253 {
254 GXPower power = GX_GetPower();
255 SDK_WARNING(power & GX_POWER_GE, "GX_POWER_GE is off now, registers for it not changes.");
256 }
257 #endif
258 G3X_ResetMtxStackOverflow();
259
260 while (G3X_GetMtxStackLevelPV(&levelPV))
261 ;
262 while (G3X_GetMtxStackLevelPJ(&levelPJ))
263 ;
264
265 G3_MtxMode(GX_MTXMODE_TEXTURE);
266 G3_Identity();
267
268 G3_MtxMode(GX_MTXMODE_PROJECTION);
269 if (levelPJ != 0)
270 {
271 G3_PopMtx(levelPJ);
272 }
273 // G3_Identity(); // Projection Matrix may not be set in a main loop
274
275 G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
276 G3_PopMtx(levelPV);
277 G3_Identity();
278
279 }
280
281
282 /*---------------------------------------------------------------------------*
283 Name: G3X_SetFog
284
285 Description: Sets attributes for fog.
286
287 Arguments: enable enables fog if not FALSE
288 fogMode fog blending manner(alpha only/color and alpha)
289 fogSlope slope of fog blending
290 fogOffset depth where fog blending starts
291
292 Returns: none
293 *---------------------------------------------------------------------------*/
G3X_SetFog(BOOL enable,GXFogBlend fogMode,GXFogSlope fogSlope,int fogOffset)294 void G3X_SetFog(BOOL enable, GXFogBlend fogMode, GXFogSlope fogSlope, int fogOffset)
295 {
296 if (enable)
297 {
298 SDK_MINMAX_ASSERT(fogOffset, 0, 0x7fff);
299 SDK_MINMAX_ASSERT(fogSlope, GX_FOGSLOPE_0x8000, GX_FOGSLOPE_0x0020);
300 SDK_ASSERT(GX_FOGBLEND_COLOR_ALPHA == fogMode || GX_FOGBLEND_ALPHA == fogMode);
301
302 reg_G3X_FOG_OFFSET = (u16)fogOffset;
303
304 reg_G3X_DISP3DCNT = (u16)((reg_G3X_DISP3DCNT &
305 ~(REG_G3X_DISP3DCNT_FOG_SHIFT_MASK
306 | REG_G3X_DISP3DCNT_FMOD_MASK
307 | REG_G3X_DISP3DCNT_RO_MASK
308 | REG_G3X_DISP3DCNT_GO_MASK))
309 | ((fogSlope << REG_G3X_DISP3DCNT_FOG_SHIFT_SHIFT)
310 | (fogMode << REG_G3X_DISP3DCNT_FMOD_SHIFT)
311 | (REG_G3X_DISP3DCNT_FME_MASK)));
312 }
313 else
314 {
315 reg_G3X_DISP3DCNT &= (u16)~(REG_G3X_DISP3DCNT_FME_MASK
316 | REG_G3X_DISP3DCNT_RO_MASK | REG_G3X_DISP3DCNT_GO_MASK);
317 }
318 }
319
320
321 /*---------------------------------------------------------------------------*
322 Name: G3X_GetClipMtx
323
324 Description: Gets a clip matrix.
325
326 Arguments: m a pointer to a 4x4 matrix.
327
328 Returns: 0 if the result is in *m,
329 otherwise, the geometry engine is busy.
330 *---------------------------------------------------------------------------*/
G3X_GetClipMtx(MtxFx44 * m)331 int G3X_GetClipMtx(MtxFx44 *m)
332 {
333 SDK_NULL_ASSERT(m);
334
335 if (G3X_IsGeometryBusy())
336 {
337 return -1;
338 }
339 else
340 {
341 #if 1
342 MI_Copy64B((void *)REG_CLIPMTX_RESULT_0_ADDR, &m->_00);
343 #else
344 m->_00 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 0);
345 m->_01 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 1);
346 m->_02 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 2);
347 m->_03 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 3);
348
349 m->_10 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 4);
350 m->_11 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 5);
351 m->_12 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 6);
352 m->_13 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 7);
353
354 m->_20 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 8);
355 m->_21 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 9);
356 m->_22 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 10);
357 m->_23 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 11);
358
359 m->_30 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 12);
360 m->_31 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 13);
361 m->_32 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 14);
362 m->_33 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 15);
363 #endif
364 return 0;
365 }
366 }
367
368
369 /*---------------------------------------------------------------------------*
370 Name: G3X_GetVectorMtx
371
372 Description: Gets a vector matrix.
373
374 Arguments: m a pointer to a 3x3 matrix.
375
376 Returns: 0 if the result is in *m,
377 otherwise, the geometry engine is busy.
378 *---------------------------------------------------------------------------*/
G3X_GetVectorMtx(MtxFx33 * m)379 int G3X_GetVectorMtx(MtxFx33 *m)
380 {
381 SDK_NULL_ASSERT(m);
382
383 if (G3X_IsGeometryBusy())
384 {
385 return -1;
386 }
387 else
388 {
389 #if 1
390 MI_Copy36B((void *)(REG_VECMTX_RESULT_0_ADDR), &m->_00);
391 #else
392 m->_00 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 0);
393 m->_01 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 1);
394 m->_02 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 2);
395
396 m->_10 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 3);
397 m->_11 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 4);
398 m->_12 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 5);
399
400 m->_20 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 6);
401 m->_21 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 7);
402 m->_22 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 8);
403 #endif
404
405 return 0;
406 }
407 }
408
409
410 /*---------------------------------------------------------------------------*
411 Name: G3X_SetEdgeColorTable
412
413 Description: Sets a edge color table.
414
415 Arguments: m a pointer to a the data to set(16 bytes length).
416
417 Returns: None.
418 *---------------------------------------------------------------------------*/
G3X_SetEdgeColorTable(const GXRgb * rgb_8)419 void G3X_SetEdgeColorTable(const GXRgb *rgb_8)
420 {
421 SDK_NULL_ASSERT(rgb_8);
422 #if 1
423 MI_CpuCopy16(rgb_8, (void *)REG_EDGE_COLOR_0_L_ADDR, 16);
424 #else
425 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 0) = (u16)(*(rgb_8 + 0));
426 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 1) = (u16)(*(rgb_8 + 1));
427 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 2) = (u16)(*(rgb_8 + 2));
428 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 3) = (u16)(*(rgb_8 + 3));
429 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 4) = (u16)(*(rgb_8 + 4));
430 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 5) = (u16)(*(rgb_8 + 5));
431 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 6) = (u16)(*(rgb_8 + 6));
432 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 7) = (u16)(*(rgb_8 + 7));
433 #endif
434 }
435
436
437 /*---------------------------------------------------------------------------*
438 Name: G3X_SetFogTable
439
440 Description: Sets a fog table.
441
442 Arguments: fogTable a pointer to the data to set(32 bytes length)
443
444 Returns: none
445 *---------------------------------------------------------------------------*/
G3X_SetFogTable(const u32 * fogTable)446 void G3X_SetFogTable(const u32 *fogTable)
447 {
448 SDK_NULL_ASSERT(fogTable);
449 #if 1
450 MI_Copy32B(&fogTable[0], (void *)REG_FOG_TABLE_0_ADDR);
451 #else
452 *((REGType32 *)REG_FOG_TABLE_0_ADDR + 0) = *(fogTable + 0);
453 *((REGType32 *)REG_FOG_TABLE_0_ADDR + 1) = *(fogTable + 1);
454 *((REGType32 *)REG_FOG_TABLE_0_ADDR + 2) = *(fogTable + 2);
455 *((REGType32 *)REG_FOG_TABLE_0_ADDR + 3) = *(fogTable + 3);
456 *((REGType32 *)REG_FOG_TABLE_0_ADDR + 4) = *(fogTable + 4);
457 *((REGType32 *)REG_FOG_TABLE_0_ADDR + 5) = *(fogTable + 5);
458 *((REGType32 *)REG_FOG_TABLE_0_ADDR + 6) = *(fogTable + 6);
459 *((REGType32 *)REG_FOG_TABLE_0_ADDR + 7) = *(fogTable + 7);
460 #endif
461 }
462
463
464 /*---------------------------------------------------------------------------*
465 Name: G3X_SetToonTable
466
467 Description: Sets a toon table.
468
469 Arguments: rgb_32 a pointer to the data to set(64 bytes length)
470
471 Returns: none
472 *---------------------------------------------------------------------------*/
G3X_SetToonTable(const GXRgb * rgb_32)473 void G3X_SetToonTable(const GXRgb *rgb_32)
474 {
475 #if 1
476 SDK_NULL_ASSERT(rgb_32);
477 MI_CpuCopy16(rgb_32, (void *)REG_TOON_TABLE_0_L_ADDR, 64);
478 #else
479 int i;
480 SDK_NULL_ASSERT(rgb_32);
481 for (i = 0; i < 32; ++i)
482 {
483 *((REGType16 *)REG_TOON_TABLE_0_L_ADDR + i) = (u16)(*(rgb_32 + i));
484 }
485 #endif
486 }
487
488
489 /*---------------------------------------------------------------------------*
490 Name: G3X_SetClearColor
491
492 Description: Sets a clear color, alpha, depth, polygonID
493
494 Arguments: rgb clear color on the color buffer
495 alpha clear alpha on the color buffer
496 depth clear depth(15 bits) on the depth buffer
497 polygonID clear polygon ID(opaque) on the attribute buffer
498 fog fog enable flag on the attribute buffer
499
500 Returns: none
501 *---------------------------------------------------------------------------*/
G3X_SetClearColor(GXRgb rgb,int alpha,int depth,int polygonID,BOOL fog)502 void G3X_SetClearColor(GXRgb rgb, int alpha, int depth, int polygonID, BOOL fog)
503 {
504 u32 val;
505 GX_POLYGONID_ASSERT(polygonID);
506 GX_ALPHA_ASSERT(alpha);
507 GXRGB_ASSERT(rgb);
508 GX_DEPTH_ASSERT(depth);
509
510 val =
511 (u32)(rgb | (alpha << REG_G3X_CLEAR_COLOR_ALPHA_SHIFT) |
512 (polygonID << REG_G3X_CLEAR_COLOR_POLYGONID_SHIFT));
513 if (fog)
514 val |= REG_G3X_CLEAR_COLOR_F_MASK;
515
516 reg_G3X_CLEAR_COLOR = val;
517 reg_G3X_CLEAR_DEPTH = (u16)depth;
518 }
519
520
521 /*---------------------------------------------------------------------------*
522 Name: G3X_InitTable
523
524 Description: Initializes the edge color table, the fog table,
525 the toon table, and the shininess table.
526
527 Arguments: none
528
529 Returns: none
530 *---------------------------------------------------------------------------*/
G3X_InitTable()531 void G3X_InitTable()
532 {
533 int i;
534 #if 1
535 if (GXi_DmaId != GX_DMA_NOT_USE)
536 {
537 #ifdef SDK_TWL
538 if (GXi_DmaId > 3)
539 {
540 MI_NDmaFillAsync(GXi_DmaId-4, (void *)REG_EDGE_COLOR_0_L_ADDR, 0, 16, NULL, NULL);
541 MI_NDmaFill(GXi_DmaId-4, (void *)REG_FOG_TABLE_0_ADDR, 0, 96);
542 }
543 else
544 #endif
545 {
546 MI_DmaFill32Async(GXi_DmaId, (void *)REG_EDGE_COLOR_0_L_ADDR, 0, 16, NULL, NULL);
547 MI_DmaFill32(GXi_DmaId, (void *)REG_FOG_TABLE_0_ADDR, 0, 96);
548 }
549 }
550 else
551 {
552 MI_CpuFill32((void *)REG_EDGE_COLOR_0_L_ADDR, 0, 16);
553 MI_CpuFill32((void *)REG_FOG_TABLE_0_ADDR, 0, 96);
554 }
555 #else
556 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 0) = 0;
557 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 1) = 0;
558 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 2) = 0;
559 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 3) = 0;
560 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 4) = 0;
561 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 5) = 0;
562 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 6) = 0;
563 *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 7) = 0;
564
565 *((REGType32 *)REG_FOG_TABLE_0_ADDR + 0) = 0;
566 *((REGType32 *)REG_FOG_TABLE_0_ADDR + 1) = 0;
567 *((REGType32 *)REG_FOG_TABLE_0_ADDR + 2) = 0;
568 *((REGType32 *)REG_FOG_TABLE_0_ADDR + 3) = 0;
569
570 for (i = 0; i < 32; ++i)
571 {
572 *((REGType16 *)REG_TOON_TABLE_0_L_ADDR + i) = 0;
573 }
574 #endif
575 for (i = 0; i < 32; ++i)
576 {
577 reg_G3_SHININESS = 0;
578 }
579 }
580
581
582 /*---------------------------------------------------------------------------*
583 Name: G3X_GetMtxStackLevelPV
584
585 Description: Get the current level of the Position/Vector matrix stack.
586
587 Arguments: level a pointer to the current Position/Vector matrix
588 stack level
589
590 Returns: if 0, *level has the result(0 to 31),
591 otherwise, the matrix stack is busy.
592 *---------------------------------------------------------------------------*/
G3X_GetMtxStackLevelPV(s32 * level)593 int G3X_GetMtxStackLevelPV(s32 *level)
594 {
595 SDK_NULL_ASSERT(level);
596 if (reg_G3X_GXSTAT & REG_G3X_GXSTAT_SB_MASK)
597 {
598 return -1;
599 }
600 else
601 {
602 *level = (s32)((reg_G3X_GXSTAT & REG_G3X_GXSTAT_PV_MASK) >> REG_G3X_GXSTAT_PV_SHIFT);
603 return 0;
604 }
605 }
606
607
608 /*---------------------------------------------------------------------------*
609 Name: G3X_GetMtxStackLevelPJ
610
611 Description: Get the current level of the Projection matrix stack.
612
613 Arguments: level a pointer to the current Projection matrix
614 stack level
615
616 Returns: if 0, *level has the result(0 or 1),
617 otherwise, the matrix stack is busy.
618 *---------------------------------------------------------------------------*/
G3X_GetMtxStackLevelPJ(s32 * level)619 int G3X_GetMtxStackLevelPJ(s32 *level)
620 {
621 SDK_NULL_ASSERT(level);
622 if (reg_G3X_GXSTAT & REG_G3X_GXSTAT_SB_MASK)
623 {
624 return -1;
625 }
626 else
627 {
628 *level = (s32)((reg_G3X_GXSTAT & REG_G3X_GXSTAT_PJ_MASK) >> REG_G3X_GXSTAT_PJ_SHIFT);
629 return 0;
630 }
631 }
632
633
634 /*---------------------------------------------------------------------------*
635 Name: G3X_SetDisp1DotDepth
636
637 Description: If GX_POLYGON_ATTR_MISC_DISP_1DOT is set in G3*_PolygonAttr,
638 the depth(w) value set by this function is the boundary
639 to display or not to display the polygons which are mapped
640 to less than one dot square.
641
642 Arguments: w w-value(even if z-buffering mode) in fx32 format
643
644 Returns: None
645 *---------------------------------------------------------------------------*/
G3X_SetDisp1DotDepth(fx32 w)646 void G3X_SetDisp1DotDepth(fx32 w)
647 {
648 SDK_MINMAX_ASSERT(w, 0, FX32_ONE * 0x1000 - 1);
649 reg_G3X_DISP_1DOT_DEPTH = (u16)((w >> 9) & 0x7fff);
650 }
651
652
653 /*---------------------------------------------------------------------------*
654 Name: G3X_GetBoxTestResult
655
656 Description: Obtain the result of boxtest.
657 If *in is 0, the box is out the frustum.
658 otherwise, the box is in/across the frustum.
659
660 Arguments: in a pointer to the result
661
662 Returns: if 0, *in has the result.
663 otherwise, the test is on the way.
664 *---------------------------------------------------------------------------*/
G3X_GetBoxTestResult(s32 * in)665 int G3X_GetBoxTestResult(s32 *in)
666 {
667 SDK_NULL_ASSERT(in);
668 if (reg_G3X_GXSTAT & REG_G3X_GXSTAT_TB_MASK)
669 return -1;
670 else
671 {
672 *in = (s32)(reg_G3X_GXSTAT & REG_G3X_GXSTAT_TR_MASK);
673 return 0;
674 }
675 }
676
677
678 /*---------------------------------------------------------------------------*
679 Name: G3X_GetPositionTestResult
680
681 Description: Obtain the result of positiontest.
682
683 Arguments: vec, w a pointer to the result
684
685 Returns: if 0, *vec, *w have the result.
686 otherwise, the test is on the way.
687 *---------------------------------------------------------------------------*/
G3X_GetPositionTestResult(VecFx32 * vec,fx32 * w)688 int G3X_GetPositionTestResult(VecFx32 *vec, fx32 *w)
689 {
690 SDK_NULL_ASSERT(vec);
691 SDK_NULL_ASSERT(w);
692
693 if (reg_G3X_GXSTAT & REG_G3X_GXSTAT_TB_MASK)
694 {
695 return -1;
696 }
697 else
698 {
699 vec->x = (fx32)reg_G3X_POS_RESULT_X;
700 vec->y = (fx32)reg_G3X_POS_RESULT_Y;
701 vec->z = (fx32)reg_G3X_POS_RESULT_Z;
702 *w = (fx32)reg_G3X_POS_RESULT_W;
703 return 0;
704 }
705 }
706
707
708 /*---------------------------------------------------------------------------*
709 Name: G3X_GetVectorTestResult
710
711 Description: Obtain the result of vectortest.
712
713 Arguments: vec a pointer to the result
714
715 Returns: if 0, *vec has the result.
716 otherwise, the test is on the way.
717 *---------------------------------------------------------------------------*/
G3X_GetVectorTestResult(fx16 * vec)718 int G3X_GetVectorTestResult(fx16 *vec)
719 {
720 SDK_NULL_ASSERT(vec);
721 if (reg_G3X_GXSTAT & REG_G3X_GXSTAT_TB_MASK)
722 {
723 return -1;
724 }
725 else
726 {
727 *(vec + 0) = (fx16)reg_G3X_VEC_RESULT_X;
728 *(vec + 1) = (fx16)reg_G3X_VEC_RESULT_Y;
729 *(vec + 2) = (fx16)reg_G3X_VEC_RESULT_Z;
730 return 0;
731 }
732 }
733
734
735 /*---------------------------------------------------------------------------*
736 Name: G3X_SetHOffset
737
738 Description: Sets a horizontal offset of 3D plane.
739
740 Arguments: hOffset horizontal offset of 3D plane
741
742 Returns: none
743 *---------------------------------------------------------------------------*/
G3X_SetHOffset(int hOffset)744 void G3X_SetHOffset(int hOffset)
745 {
746 SDK_WARNING((reg_GX_DISPCNT & REG_GX_DISPCNT_BG02D3D_MASK) != 0,
747 "BG0 is in 2D mode now. call \'G2_SetBG0Offset\'\n");
748 SDK_ASSERT(hOffset >= -256 && hOffset <= 255);
749
750 reg_G2_BG0OFS = (u32)hOffset;
751 }
752
753
754 #include <nitro/code32.h>
755
756 /*---------------------------------------------------------------------------*
757 Name: G3Xi_NopClearFifo_
758
759 Description: Set Nop for clear FIFO
760
761 Arguments: pDest - pointer to Fifo command register.
762
763 Returns: none
764 *---------------------------------------------------------------------------*/
GXi_NopClearFifo128_(register void * pDest)765 static asm void GXi_NopClearFifo128_( register void* pDest )
766 {
767 mov r1, #0 // r0-r3, r12 need not be saved.
768 mov r2, #0
769 mov r3, #0
770 mov r12, #0
771
772 // set 128 NOP command for 4 PACKED Shineness command. (32 * 4 NOP)
773
774 stmia r0, {r1-r3, r12} // 0 - 15
775 stmia r0, {r1-r3, r12}
776 stmia r0, {r1-r3, r12}
777 stmia r0, {r1-r3, r12}
778
779 stmia r0, {r1-r3, r12} // 16 - 31
780 stmia r0, {r1-r3, r12}
781 stmia r0, {r1-r3, r12}
782 stmia r0, {r1-r3, r12}
783
784 stmia r0, {r1-r3, r12} // 32 - 47
785 stmia r0, {r1-r3, r12}
786 stmia r0, {r1-r3, r12}
787 stmia r0, {r1-r3, r12}
788
789 stmia r0, {r1-r3, r12} // 48 - 63
790 stmia r0, {r1-r3, r12}
791 stmia r0, {r1-r3, r12}
792 stmia r0, {r1-r3, r12}
793
794 stmia r0, {r1-r3, r12} // 64 - 79
795 stmia r0, {r1-r3, r12}
796 stmia r0, {r1-r3, r12}
797 stmia r0, {r1-r3, r12}
798
799 stmia r0, {r1-r3, r12} // 80 - 95
800 stmia r0, {r1-r3, r12}
801 stmia r0, {r1-r3, r12}
802 stmia r0, {r1-r3, r12}
803
804 stmia r0, {r1-r3, r12} // 96 - 111
805 stmia r0, {r1-r3, r12}
806 stmia r0, {r1-r3, r12}
807 stmia r0, {r1-r3, r12}
808
809 stmia r0, {r1-r3, r12} // 112 - 127
810 stmia r0, {r1-r3, r12}
811 stmia r0, {r1-r3, r12}
812 stmia r0, {r1-r3, r12}
813
814 bx lr
815 }
816
817 #include <nitro/codereset.h>
818