1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     frb-copy.c
4 
5   Copyright 1998-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 /*---------------------------------------------------------------------------*
14     frb-copy
15         texture copy test
16  *---------------------------------------------------------------------------*/
17 
18 
19 /*---------------------------------------------------------------------------*
20    Header files
21  *---------------------------------------------------------------------------*/
22 #include <demo.h>
23 #include <math.h>
24 
25 /*---------------------------------------------------------------------------*
26    Macro definitions
27  *---------------------------------------------------------------------------*/
28 #define PI                   3.14159265358979323846F
29 #define MAX_Z                0x00ffffff // max value of Z buffer
30 
31 #define Clamp(val,min,max) \
32     ((val) = (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)))
33 
34 #define ClearEFB() \
35     GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE)
36 
37 /*---------------------------------------------------------------------------*
38    Structure definitions
39  *---------------------------------------------------------------------------*/
40 // for camera
41 typedef struct
42 {
43     Vec    location;
44     Vec    up;
45     Vec    target;
46     f32    left;
47     f32    top;
48     f32    znear;
49     f32    zfar;
50 } CameraConfig;
51 
52 typedef struct
53 {
54     CameraConfig  cfg;
55     Mtx           view;
56     Mtx44         proj;
57     f32           theta;
58 } MyCameraObj;
59 
60 // for copied texture
61 typedef struct
62 {
63     GXTexObj      tobj;
64     u8*           data;
65     s32           top;
66     s32           left;
67     s32           width;
68     s32           height;
69     u32           format;
70     GXBool        mmFilter;
71     GXBool        clear;
72 } MyCopyTexObj;
73 
74 // for entire scene control
75 typedef struct
76 {
77     MyCameraObj       cam;
78     MyCopyTexObj      copyTex;
79     u16               screen_width;
80     u16               screen_height;
81     u16               copy_width_max;
82     u16               copy_height_max;
83 } MySceneCtrlObj;
84 
85 /*---------------------------------------------------------------------------*
86    Forward references
87  *---------------------------------------------------------------------------*/
88 void        main               ( void );
89 static void DrawInit           ( MySceneCtrlObj* sc );
90 static void DrawTick           ( MySceneCtrlObj* sc );
91 static void AnimTick           ( MySceneCtrlObj* sc );
92 static void DrawFloor          ( void );
93 static void DrawScreenPanel    ( void );
94 static void DrawCubes          ( Mtx view );
95 static void DrawTexCopyFrame   ( MyCopyTexObj* ct );
96 static void CopyTextureFromFB  ( MyCopyTexObj* ct );
97 static void SetCamera          ( MyCameraObj* cam );
98 static void SetScreenSpaceMode ( MySceneCtrlObj* sc );
99 static void SetLight           ( void );
100 static void DisableLight       ( void );
101 static void PrintIntro         ( void );
102 
103 /*---------------------------------------------------------------------------*
104   Model and texture data
105  *---------------------------------------------------------------------------*/
106 // for cube models
107 #define NUM_CUBES    8
108 #define REG_AMBIENT  ColorArray[NUM_CUBES]
109 #define LIGHT_COLOR  ColorArray[NUM_CUBES+1]
110 #define BG_COLOR     ColorArray[NUM_CUBES+2]
111 
112 static GXColor ColorArray[NUM_CUBES+3] ATTRIBUTE_ALIGN(32) =
113 {
114     { 0x80, 0xFF, 0x80, 0xFF },
115     { 0x00, 0xFF, 0xFF, 0xFF },
116     { 0xFF, 0x00, 0xFF, 0xFF },
117     { 0xFF, 0xFF, 0x00, 0xFF },
118     { 0x20, 0x20, 0xFF, 0x80 },
119     { 0x20, 0xA0, 0x00, 0x80 },
120     { 0xC0, 0xC0, 0xC0, 0x40 },
121     { 0xFF, 0x80, 0x80, 0x40 },
122     { 0x40, 0x40, 0x40, 0xFF },    // Gray  (Ambient etc.)
123     { 0xFF, 0xFF, 0xFF, 0xFF },    // White (Light etc.)
124     { 0x00, 0x00, 0x00, 0x00 }     // Background
125 };
126 
127 static Vec CubePosArray[NUM_CUBES] =
128 {
129     { -400, -150,  30 },
130     {  400, -150,  30 },
131     { -400,  250,   0 },
132     {  400,  250,   0 },
133     { -600,   50, -50 },
134     {  600,   50, -50 },
135     { -300,   50, -80 },
136     {  300,   50, -80 }
137 };
138 
139 static f32 CubeDegArray[NUM_CUBES] =
140 {
141      45.0F,
142     245.0F,
143     120.0F,
144     135.0F,
145     315.0F,
146      60.0F,
147     105.0F,
148     345.0F
149 };
150 
151 // floor texture
152 #define FLOOR_TEX_WIDTH   4
153 #define FLOOR_TEX_HEIGHT  4
154 #define FLOOR_TEX_FORMAT  GX_TF_RGB5A3
155 static u16 FloorTexData[] ATTRIBUTE_ALIGN(32) =
156 {
157     0x7CCC, 0x7CCC, 0x700F, 0x700F,
158     0x7CCC, 0x7CCC, 0x700F, 0x700F,
159     0x700F, 0x700F, 0x7CCC, 0x7CCC,
160     0x700F, 0x700F, 0x7CCC, 0x7CCC
161 };
162 
163 // blank texture for the first frame
164 #define BLANK_TEX_WIDTH   4
165 #define BLANK_TEX_HEIGHT  4
166 #define BLANK_TEX_FORMAT  GX_TF_RGB5A3
167 static u16 BlankTexData[] ATTRIBUTE_ALIGN(32) =
168 {
169     0x0000, 0x0000, 0x0000, 0x0000,
170     0x0000, 0x0000, 0x0000, 0x0000,
171     0x0000, 0x0000, 0x0000, 0x0000,
172     0x0000, 0x0000, 0x0000, 0x0000
173 };
174 
175 // texture formats for copy and display
176 #define TEX_FORMATS     22
177 
178 static struct
179 {
180     GXTexFmt    cpyFmt;
181     GXTexFmt    useFmt;
182     char*       cpyFmtStr;
183     char*       useFmtStr;
184 }
185 TexFormats[TEX_FORMATS] =
186 {
187     // Copy format, Display format
188     { GX_TF_RGB565, GX_TF_RGB565, "RGB565", "RGB565" },
189     { GX_TF_RGB5A3, GX_TF_RGB5A3, "RGB5A3", "RGB5A3" },
190     { GX_TF_RGBA8,  GX_TF_RGBA8,  "RGBA8",  "RGBA8"  },
191     { GX_TF_I4,     GX_TF_I4,     "I4",     "I4"     },
192     { GX_TF_I8,     GX_TF_I8,     "I8",     "I8"     },
193     { GX_TF_IA4,    GX_TF_IA4,    "IA4",    "IA4"    },
194     { GX_TF_IA8,    GX_TF_IA8,    "IA8",    "IA8"    },
195     { GX_TF_A8,     GX_TF_I8,     "A8",     "I8"     },
196     { GX_CTF_R4,    GX_TF_I4,     "R4",     "I4"     }, // copy as R4,  use as I4
197     { GX_CTF_RA4,   GX_TF_IA4,    "RA4",    "IA4"    }, // copy as RA4, use as IA4
198     { GX_CTF_RA8,   GX_TF_IA8,    "RA8",    "IA8"    }, // copy as RA8, use as IA8
199     { GX_CTF_R8,    GX_TF_I8,     "R8",     "I8"     }, // copy as R8,  use as I8
200     { GX_CTF_G8,    GX_TF_I8,     "G8",     "I8"     }, // copy as G8,  use as I8
201     { GX_CTF_B8,    GX_TF_I8,     "B8",     "I8"     }, // copy as B8,  use as I8
202     { GX_CTF_RG8,   GX_TF_IA8,    "RG8",    "IA8"    }, // copy as RG8, use as IA8
203     { GX_CTF_GB8,   GX_TF_IA8,    "GB8",    "IA8"    }, // copy as GB8, use as IA8
204     { GX_TF_Z16,    GX_TF_IA8,    "Z16",    "IA8"    }, // copy as Z16, use as IA8
205     { GX_TF_Z8,     GX_TF_I8,     "Z8",     "I8"     }, // copy as Z8,  use as I8
206     { GX_CTF_Z4,    GX_TF_I4,     "Z4",     "I4"     }, // copy as Z4,  use as I4
207     { GX_CTF_Z8M,   GX_TF_I8,     "Z8M",    "I8"     }, // copy as Z8M, use as I8
208     { GX_CTF_Z8L,   GX_TF_I8,     "Z8L",    "I8"     }, // copy as Z8L, use as I8
209     { GX_CTF_Z16L,  GX_TF_IA8,    "Z16L",   "IA8"    }, // copy as Z16L,use as IA8
210 };
211 
212 /*---------------------------------------------------------------------------*
213    Camera configuration
214  *---------------------------------------------------------------------------*/
215 static CameraConfig DefaultCamera =
216 {
217     {   0.0F, 0.0F, 800.0F }, // location
218     {   0.0F, 1.0F, 0.0F }, // up
219     {   0.0F, 0.0F, 0.0F }, // target
220     -320.0F,  // left
221     240.0F,   // top
222     400.0F,   // near
223     2000.0F   // far
224 };
225 
226 /*---------------------------------------------------------------------------*
227    Global variables
228  *---------------------------------------------------------------------------*/
229 static MySceneCtrlObj   SceneCtrl;                // scene control parameters
230 static GXTexObj         MyFloorTexture;           // texture for the floor
231 
232 /*---------------------------------------------------------------------------*
233    Application main loop
234  *---------------------------------------------------------------------------*/
main(void)235 void main ( void )
236 {
237     DEMOInit(NULL);  // Init the OS, game pad, graphics and video.
238 
239     DrawInit(&SceneCtrl); // Initialize vertex formats, array pointers
240                           // and default scene settings.
241 
242     PrintIntro();    // Print demo directions
243 
244     while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
245     {
246 		DEMOBeforeRender();
247         DrawTick(&SceneCtrl);    // Draw the model.
248         DEMODoneRender();
249         DEMOPadRead();           // Read controller
250         AnimTick(&SceneCtrl);    // Do animation
251     }
252     OSHalt("End of test");
253 }
254 
255 /*---------------------------------------------------------------------------*
256    Functions
257  *---------------------------------------------------------------------------*/
258 /*---------------------------------------------------------------------------*
259     Name:           DrawInit
260 
261     Description:    Initializes the vertex attribute format and sets up
262                     the array pointer for the indexed data.
263                     This function also initializes scene control parameters.
264 
265     Arguments:      sc : pointer to the structure of scene control parameters
266 
267     Returns:        none
268  *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)269 static void DrawInit( MySceneCtrlObj* sc )
270 {
271     GXRenderModeObj *rmp;
272     u32             size;
273 
274     // Get framebuffer size of current rendering mode
275     rmp = DEMOGetRenderModeObj();
276     sc->screen_width  = rmp->fbWidth;
277     sc->screen_height = rmp->efbHeight;
278     sc->copy_width_max  = (u16)((sc->screen_width  * 5 / 32) * 4);
279     sc->copy_height_max = (u16)((sc->screen_height * 5 / 12) * 2);
280 
281     //  Vertex Attribute
282     GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
283     GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_S16, 8);
284     GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
285 
286     //  Array Pointers and Strides
287     GXSetArray(GX_VA_CLR0, ColorArray, 4 * sizeof(u8));
288 
289     // Z compare, pixel format and background color
290     GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
291     GXSetPixelFmt(GX_PF_RGBA6_Z24, GX_ZC_LINEAR);
292     GXSetCopyClear(BG_COLOR, MAX_Z);
293     GXSetAlphaUpdate(GX_ENABLE);
294 
295     // Set number of tev stages, tex coord generators and color channels
296     GXSetNumTevStages(1);
297     GXSetNumTexGens(1);
298     GXSetNumChans(1);
299 
300 
301     // Default scene control parameter settings
302 
303     // camera
304     sc->cam.cfg   = DefaultCamera;
305     sc->cam.theta = 0;
306 
307     // for floor texture and blank texture
308     GXInitTexObj(
309         &MyFloorTexture,
310         FloorTexData,
311         FLOOR_TEX_WIDTH,
312         FLOOR_TEX_HEIGHT,
313         FLOOR_TEX_FORMAT,
314         GX_REPEAT,
315         GX_REPEAT,
316         GX_FALSE );
317     GXInitTexObjLOD(
318         &MyFloorTexture,
319         GX_LINEAR,
320         GX_NEAR,
321         0.0F,
322         0.0F,
323         0.0F,
324         GX_FALSE,
325         GX_FALSE,
326         GX_ANISO_1 );
327 
328     // for copied texture
329     sc->copyTex.top      = 64;
330     sc->copyTex.left     = 64;
331     sc->copyTex.width    = 32;
332     sc->copyTex.height   = 32;
333     sc->copyTex.format   = 0;
334     sc->copyTex.mmFilter = GX_FALSE;
335     sc->copyTex.clear    = GX_FALSE;
336 
337     // Allocate memory for maximum size
338     size = GXGetTexBufferSize(
339                sc->copy_width_max,
340                sc->copy_height_max,
341                GX_TF_RGBA8,
342                GX_FALSE,
343                0 );
344     sc->copyTex.data = MEMAllocFromAllocator(&DemoAllocator1, size);
345     ASSERTMSG(sc->copyTex.data != NULL, "No enough memory for texture buffer.\n");
346     DCInvalidateRange(sc->copyTex.data, size);
347 }
348 
349 /*---------------------------------------------------------------------------*
350     Name:           DrawTick
351 
352     Description:    Draw the model by using given scene parameters
353 
354     Arguments:      sc : pointer to the structure of scene control parameters
355 
356     Returns:        none
357  *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)358 static void DrawTick( MySceneCtrlObj* sc )
359 {
360     Mtx    mv;
361 
362     // Texture data is changed every frame
363     GXInvalidateTexAll();
364 
365     // Set up camera
366     SetCamera(&sc->cam);
367 
368     // Draw cube models
369     DrawCubes(sc->cam.view);
370 
371     // Draw the floor
372     GXLoadTexObj(&MyFloorTexture, GX_TEXMAP0);
373     MTXCopy(sc->cam.view, mv);
374     GXLoadPosMtxImm(mv, GX_PNMTX0);
375     DrawFloor();
376 
377     // Draw a screen panel which shows copied texture
378     GXLoadTexObj(&sc->copyTex.tobj, GX_TEXMAP0);
379     MTXCopy(sc->cam.view, mv);
380     GXLoadPosMtxImm(mv, GX_PNMTX0);
381     DrawScreenPanel();
382 
383     // Draw the frame which shows the area of copy texture
384     SetScreenSpaceMode(sc);
385     MTXIdentity(mv);
386     GXLoadPosMtxImm(mv, GX_PNMTX0);
387     DrawTexCopyFrame(&sc->copyTex);
388 
389     // Copy texture from the frame buffer
390     CopyTextureFromFB(&sc->copyTex);
391 
392     // Caption
393     DEMOInitCaption(DM_FT_OPQ, (s16)sc->screen_width, (s16)sc->screen_height);
394     DEMOPrintf(32, (s16)(sc->screen_height - 40 ), 0,
395                " COPY : %s ", TexFormats[sc->copyTex.format].cpyFmtStr);
396     DEMOPrintf(32, (s16)(sc->screen_height - 32 ), 0,
397                " USE  : %s ", TexFormats[sc->copyTex.format].useFmtStr);
398     // Resume Z mode
399     GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
400 }
401 
402 /*---------------------------------------------------------------------------*
403     Name:           AnimTick
404 
405     Description:    Changes scene parameters according to the pad status.
406 
407     Arguments:      sc : pointer to the structure of scene control parameters
408 
409     Returns:        none
410  *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)411 static void AnimTick( MySceneCtrlObj* sc )
412 {
413     u16  button, down;
414 
415     button = DEMOPadGetButton(0);
416     down   = DEMOPadGetButtonDown(0);
417 
418     // Moves copy area
419     sc->copyTex.width  += ( DEMOPadGetSubStickX(0) / 32 ) * 4;
420     sc->copyTex.height -= ( DEMOPadGetSubStickY(0) / 24 ) * 2;
421 
422     // Moves copy area
423     sc->copyTex.left += ( DEMOPadGetStickX(0) / 32 ) * 4;
424     sc->copyTex.top  -= ( DEMOPadGetStickY(0) / 24 ) * 2;
425 
426     Clamp(sc->copyTex.width, 16, sc->copy_width_max);
427     Clamp(sc->copyTex.height, 16, sc->copy_height_max);
428     Clamp(sc->copyTex.left, 0, sc->screen_width - sc->copyTex.width);
429     Clamp(sc->copyTex.top, 0, sc->screen_height - sc->copyTex.height);
430 
431     // Camera location control
432     sc->cam.theta += (f32)DEMOPadGetTriggerR(0) / 100.0F
433                    - (f32)DEMOPadGetTriggerL(0) / 100.0F;
434 
435     Clamp(sc->cam.theta, -30.0F, 30.0F);
436     sc->cam.cfg.location.x = 800.0F * sinf(sc->cam.theta * PI / 180.0F);
437     sc->cam.cfg.location.y = 0.0F;
438     sc->cam.cfg.location.z = 800.0F * cosf(sc->cam.theta * PI / 180.0F);
439 
440     // Change texture format
441     if ( down & PAD_BUTTON_A )
442     {
443         sc->copyTex.format = ( sc->copyTex.format + 1 ) % TEX_FORMATS;
444         //OSReport("Format: %s\n",TexFormats[sc->copyTex.format].cpyFmtStr);
445     }
446 
447     if ( down & PAD_BUTTON_B )
448     {
449         sc->copyTex.format = ( sc->copyTex.format + TEX_FORMATS - 1 ) % TEX_FORMATS;
450         //OSReport("Format: %s\n",TexFormats[sc->copyTex.format].cpyFmtStr);
451     }
452 
453     // Mipmap(box) filter option on/off
454     if ( down & PAD_BUTTON_Y )
455     {
456         if ( sc->copyTex.mmFilter )
457         {
458             sc->copyTex.mmFilter = GX_FALSE;
459             OSReport("Mipmap filter option OFF\n");
460         }
461         else
462         {
463             sc->copyTex.mmFilter = GX_TRUE;
464             OSReport("Mipmap filter option ON\n");
465         }
466     }
467 
468     // Clear option on/off
469     if ( down & PAD_BUTTON_X )
470     {
471         if ( sc->copyTex.clear )
472         {
473             sc->copyTex.clear = GX_FALSE;
474             OSReport("Clear option OFF\n");
475         }
476         else
477         {
478             sc->copyTex.clear = GX_TRUE;
479             OSReport("Clear option ON\n");
480         }
481     }
482 }
483 
484 /*---------------------------------------------------------------------------*
485     Name:           DrawFloor
486 
487     Description:    Draw the floor.
488 
489     Arguments:      none
490 
491     Returns:        none
492  *---------------------------------------------------------------------------*/
DrawFloor(void)493 static void DrawFloor( void )
494 {
495     // set Tev operation
496     GXSetNumTexGens( 1 );
497 	GXSetNumChans( 0 );
498     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
499     GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
500     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
501 
502     // set vertex descriptor
503     GXClearVtxDesc();
504     GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
505     GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
506 
507     // draw the floor
508     GXBegin(GX_QUADS, GX_VTXFMT1, 4);
509         GXPosition3s16( -1200, -256, -400 );
510         GXTexCoord2s16( 0x0000, 0x0000 );     // ( 0, 0 )
511         GXPosition3s16(  1200, -256, -400 );
512         GXTexCoord2s16( 0x0000, 0x0800 );     // ( 0, 8 )
513         GXPosition3s16(  1200, -256,  400 );
514         GXTexCoord2s16( 0x0C00, 0x0800 );     // ( 12, 8 )
515         GXPosition3s16( -1200, -256,  400 );
516         GXTexCoord2s16( 0x0C00, 0x0000 );     // ( 12, 0 )
517     GXEnd();
518 }
519 
520 /*---------------------------------------------------------------------------*
521     Name:           DrawScreenPanel
522 
523     Description:    Draw a textured screen panel
524 
525     Arguments:      none
526 
527     Returns:        none
528  *---------------------------------------------------------------------------*/
DrawScreenPanel(void)529 static void DrawScreenPanel( void )
530 {
531     // Frame
532 
533     // set Tev operation to use vertex color
534     GXSetNumTexGens( 0 );
535 	GXSetNumChans( 1 );
536     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
537     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
538 
539     // set vertex descriptor
540     GXClearVtxDesc();
541     GXSetVtxDesc(GX_VA_POS,  GX_DIRECT);
542     GXSetVtxDesc(GX_VA_CLR0, GX_INDEX8);
543 
544     GXBegin(GX_QUADS, GX_VTXFMT1, 4);
545         GXPosition3s16( -256,  256, -1 );
546         GXColor1x8((u8)NUM_CUBES);        // Gray
547         GXPosition3s16(  256,  256, -1 );
548         GXColor1x8((u8)NUM_CUBES);        // Gray
549         GXPosition3s16(  256, -256, -1 );
550         GXColor1x8((u8)NUM_CUBES);        // Gray
551         GXPosition3s16( -256, -256, -1 );
552         GXColor1x8((u8)NUM_CUBES);        // Gray
553     GXEnd();
554 
555 
556     // Screen
557 
558     // set Tev operation to use texture with decal mode
559     GXSetNumTexGens( 1 );
560 	GXSetNumChans( 1 );
561     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
562     GXSetTevOp(GX_TEVSTAGE0, GX_DECAL);
563     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
564 
565     // set vertex descriptor
566     GXClearVtxDesc();
567     GXSetVtxDesc(GX_VA_POS,  GX_DIRECT);
568     GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
569     GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
570 
571     GXBegin(GX_QUADS, GX_VTXFMT1, 4);
572         GXPosition3s16( -240,  240, 0 );
573         GXColor4u8( 0, 0, 0, 255 );
574         GXTexCoord2s16( 0x0000, 0x0000 );
575         GXPosition3s16(  240,  240, 0 );
576         GXColor4u8( 128, 0, 0, 255 );
577         GXTexCoord2s16( 0x0100, 0x0000 );
578         GXPosition3s16(  240, -240, 0 );
579         GXColor4u8( 128, 128, 0, 255 );
580         GXTexCoord2s16( 0x0100, 0x0100 );
581         GXPosition3s16( -240, -240, 0 );
582         GXColor4u8( 0, 128, 0, 255 );
583         GXTexCoord2s16( 0x0000, 0x0100 );
584     GXEnd();
585 }
586 
587 /*---------------------------------------------------------------------------*
588     Name:           DrawCubes
589 
590     Description:    Draw cube models
591 
592     Arguments:      view : view matrix
593 
594     Returns:        none
595  *---------------------------------------------------------------------------*/
DrawCubes(Mtx view)596 static void DrawCubes( Mtx view )
597 {
598     static u32 deg = 0;
599     u32 i;
600     Mtx mt, mr, ms, mv, mvi;
601     Vec pos;
602 
603     // enable lighting
604     SetLight();
605 
606     // set Tev operation to use vertex color
607     GXSetNumTexGens( 0 );
608 	GXSetNumChans( 1 );
609     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
610     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
611 
612     for ( i = 0 ; i < NUM_CUBES ; ++i )
613     {
614         pos = CubePosArray[i];
615         MTXTrans(mt, pos.x, pos.y, pos.z);
616         MTXConcat(view, mt, mv);
617         MTXScale(ms, 100.0F, 100.0F, 100.0F);
618         MTXConcat(mv, ms, mv);
619         MTXRotDeg(mr, 'x', CubeDegArray[i]);
620         MTXConcat(mv, mr, mv);
621         MTXRotDeg(mr, 'z', (f32)deg);
622         MTXConcat(mv, mr, mv);
623         GXLoadPosMtxImm(mv, GX_PNMTX0);
624         MTXInverse(mv, mvi);
625         MTXTranspose(mvi, mv);
626         GXLoadNrmMtxImm(mv, GX_PNMTX0);
627 
628         GXSetChanMatColor(GX_COLOR0A0, ColorArray[i]);
629 
630         GXDrawCube();
631     }
632 
633     // disable lighting
634     DisableLight();
635 
636     // animation parameter
637     deg += 5;
638     if ( deg > 360 )
639     {
640         deg -= 360;
641     }
642 }
643 
644 /*---------------------------------------------------------------------------*
645     Name:           DrawTexCopyFrame
646 
647     Description:    Draw the frame of the texture copy area
648 
649     Arguments:      ct : a pointer to MyCopyTexObj structure
650 
651     Returns:        none
652  *---------------------------------------------------------------------------*/
DrawTexCopyFrame(MyCopyTexObj * ct)653 static void DrawTexCopyFrame( MyCopyTexObj* ct )
654 {
655     s16  x0, x1, y0, y1;
656 
657     // set Tev operation
658     GXSetNumTexGens( 0 );
659 	GXSetNumChans( 1 );
660     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
661     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
662 
663     // set vertex descriptor
664     GXClearVtxDesc();
665     GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
666     GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
667 
668     x0 = (s16)( ct->left - 1 );
669     x1 = (s16)( ct->left + ct->width );
670     y0 = (s16)( ct->top - 1 );
671     y1 = (s16)( ct->top + ct->height );
672 
673     // draw the box
674     GXBegin(GX_LINESTRIP, GX_VTXFMT1, 5);
675         GXPosition3s16(x0, y0, 0);
676         GXColor4u8(255, 255, 255, 255);
677         GXPosition3s16(x1, y0, 0);
678         GXColor4u8(255, 255, 255, 255);
679         GXPosition3s16(x1, y1, 0);
680         GXColor4u8(255, 255, 255, 255);
681         GXPosition3s16(x0, y1, 0);
682         GXColor4u8(255, 255, 255, 255);
683         GXPosition3s16(x0, y0, 0);
684         GXColor4u8(255, 255, 255, 255);
685     GXEnd();
686 }
687 
688 /*---------------------------------------------------------------------------*
689     Name:           CopyTextureFromFB
690 
691     Description:    Copies texture from the frame buffer image
692 
693     Arguments:      ct : a pointer to MyCopyTexObj structure
694 
695     Returns:        none
696  *---------------------------------------------------------------------------*/
CopyTextureFromFB(MyCopyTexObj * ct)697 static void CopyTextureFromFB( MyCopyTexObj* ct )
698 {
699     //u32      size;
700     u16      twidth, theight;
701     GXTexFmt cpyFmt, useFmt;
702 
703     cpyFmt  = TexFormats[ct->format].cpyFmt;
704     useFmt  = TexFormats[ct->format].useFmt;
705     twidth  = (u16)ct->width;
706     theight = (u16)ct->height;
707 
708     // If the box(mipmap) filter is used, actual width/height become half.
709     if ( ct->mmFilter )
710     {
711         twidth  /= 2;
712         theight /= 2;
713     }
714 
715     // Copy image
716     GXSetTexCopySrc(
717         (u16)ct->left,
718         (u16)ct->top,
719         (u16)ct->width,
720         (u16)ct->height );
721     GXSetTexCopyDst(twidth, theight, cpyFmt, ct->mmFilter );
722     GXCopyTex(ct->data, ct->clear);
723 
724     // Initialize texture object
725     GXInitTexObj(
726         &ct->tobj,
727         ct->data,
728         twidth,
729         theight,
730         useFmt,
731         GX_CLAMP,
732         GX_CLAMP,
733         GX_FALSE );
734     GXInitTexObjLOD(
735         &ct->tobj,
736         GX_LINEAR,
737         GX_LINEAR,
738         0.0F,
739         0.0F,
740         0.0F,
741         GX_FALSE,
742         GX_FALSE,
743         GX_ANISO_1 );
744 }
745 
746 /*---------------------------------------------------------------------------*
747     Name:           SetCamera
748 
749     Description:    set view matrix and load projection matrix into hardware
750 
751     Arguments:      cam : pointer to the MyCameraObj structure
752 
753     Returns:        none
754  *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)755 static void SetCamera( MyCameraObj* cam )
756 {
757     MTXLookAt(
758         cam->view,
759         &cam->cfg.location,
760         &cam->cfg.up,
761         &cam->cfg.target );
762 
763     MTXFrustum(
764         cam->proj,
765         cam->cfg.top,
766         - (cam->cfg.top),
767         cam->cfg.left,
768         - (cam->cfg.left),
769         cam->cfg.znear,
770         cam->cfg.zfar );
771     GXSetProjection(cam->proj, GX_PERSPECTIVE);
772 }
773 
774 /*---------------------------------------------------------------------------*
775     Name:           SetScreenSpaceMode
776 
777     Description:    set projection matrix up to screen coordinate system
778 
779     Arguments:      none
780 
781     Returns:        none
782  *---------------------------------------------------------------------------*/
SetScreenSpaceMode(MySceneCtrlObj * sc)783 static void SetScreenSpaceMode( MySceneCtrlObj* sc )
784 {
785     Mtx44  proj;
786 
787     GXSetViewport(
788         1.0F, 1.0F, sc->screen_width, sc->screen_height,
789         0.0F, 1.0F);
790     MTXOrtho( proj, 0.0F, sc->screen_height, 0.0f, sc->screen_width, 0.0f, - MAX_Z );
791 
792     GXSetProjection( proj, GX_ORTHOGRAPHIC );
793 }
794 
795 /*---------------------------------------------------------------------------*
796     Name:           SetLight
797 
798     Description:    Sets light objects and color channels
799 
800     Arguments:      le   : pointer to a MyLightEnvObj structure
801                     view : view matrix.
802 
803     Returns:        none
804  *---------------------------------------------------------------------------*/
SetLight(void)805 static void SetLight( void )
806 {
807     GXLightObj  lobj;
808 
809     // set up light position and color
810     GXInitLightPos(&lobj, 0.0F, 0.0F, 10000.0F); // almost parallel
811     GXInitLightColor(&lobj, LIGHT_COLOR);
812     GXLoadLightObjImm(&lobj, GX_LIGHT0);
813 
814     // channel setting
815     GXSetChanCtrl(
816         GX_COLOR0A0,
817         GX_ENABLE,        // enable channel
818         GX_SRC_REG,       // amb source
819         GX_SRC_REG,       // mat source
820         GX_LIGHT0,        // light mask
821         GX_DF_CLAMP,      // diffuse function
822         GX_AF_NONE);      // attenuation function
823     // channel ambient
824     GXSetChanAmbColor(GX_COLOR0A0, REG_AMBIENT);
825 }
826 
827 /*---------------------------------------------------------------------------*
828     Name:           DisableLight
829 
830     Description:    Disables lighting
831 
832     Arguments:      none
833 
834     Returns:        none
835  *---------------------------------------------------------------------------*/
DisableLight(void)836 static void DisableLight( void )
837 {
838     GXSetChanCtrl(
839         GX_COLOR0A0,
840         GX_DISABLE,    // disable channel
841         GX_SRC_REG,    // amb source
842         GX_SRC_VTX,    // mat source
843         GX_LIGHT_NULL, // light mask
844         GX_DF_NONE,    // diffuse function
845         GX_AF_NONE);
846 }
847 
848 /*---------------------------------------------------------------------------*
849     Name:           PrintIntro
850 
851     Description:    Prints the directions on how to use this demo.
852 
853     Arguments:      none
854 
855     Returns:        none
856  *---------------------------------------------------------------------------*/
PrintIntro(void)857 static void PrintIntro( void )
858 {
859     OSReport("\n\n");
860     OSReport("************************************************\n");
861     OSReport("frb-copy: texture copy from EFB test\n");
862     OSReport("************************************************\n");
863     OSReport("to quit hit the start button\n");
864     OSReport("\n");
865     OSReport("  Main stick   : move the capture frame\n");
866     OSReport("  Sub stick    : change scale of the capture frame\n");
867     OSReport("  A/B button   : change texture format\n");
868     OSReport("  Y button     : mipmap filter option on/off\n");
869     OSReport("  X button     : clear option on/off\n");
870     OSReport("  L/R triggers : move the camera\n");
871     OSReport("************************************************\n\n");
872 }
873 
874 /*============================================================================*/
875