1 /*---------------------------------------------------------------------------*
2   Project:  REX DEMO shared
3   File:     report.c
4 
5   Copyright 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   $Log: graphic.c,v $
14   Revision 1.3  2007/07/18 06:55:43  inaba_kimitaka
15   Added support for image encoding methods other than NTSC
16 
17   Revision 1.2  2006/08/31 14:05:18  yosizaki
18   Added render setting function.
19 
20   Revision 1.1  2006/08/29 07:18:14  adachi_hiroaki
21   Added common graphic processing
22 
23 
24   $NoKeywords: $
25  *---------------------------------------------------------------------------*/
26 
27 #include <revolution.h>
28 #include <revolution/kpad.h>
29 #include <revolution/mem.h>
30 #include <string.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include "rexdemo/graphic.h"
34 
35 /*---------------------------------------------------------------------------*
36     Constant Definitions
37  *---------------------------------------------------------------------------*/
38 #define     REXDEMO_FIFO_SIZE    ( 256 * 1024 )
39 #define     REXDEMO_XFB_COUNT    ( 2 )
40 
41 #define     REXDEMO_RAW_COUNT    ( 24 + 1 )
42 #define     REXDEMO_COL_COUNT    ( 64 )
43 
44 #define     REXDEMO_SHOW_FRAME_COUNT     1
45 
46 /*---------------------------------------------------------------------------*
47     Structure definitions
48  *---------------------------------------------------------------------------*/
49 typedef struct REXDEMOCamera
50 {
51     Vec     pos;
52     Vec     up;
53     Vec     target;
54     f32     fovy;
55     f32     aspect;
56     f32     znear;
57     f32     zfar;
58 
59 } REXDEMOCamera;
60 
61 /*---------------------------------------------------------------------------*
62     Internal variable definitions
63  *---------------------------------------------------------------------------*/
64 static s32              sampleFrameCount    = 0;
65 static s32              sampleFrameCycle;
66 static GXRenderModeObj  sampleRend;
67 static u8               sampleFifoBuf[ REXDEMO_FIFO_SIZE ] ATTRIBUTE_ALIGN( 32 );
68 static void*            sampleXFB[ REXDEMO_XFB_COUNT ];
69 
70 static u8               sampleFontBuf[ OSRoundUp32B( OS_FONT_SIZE_ANSI + OS_FONT_SIZE_SJIS ) ] ATTRIBUTE_ALIGN( 32 );
71 static OSFontHeader*    sampleFont  = (OSFontHeader*)( &( sampleFontBuf[ 0 ] ) );
72 static char             sampleString[ REXDEMO_RAW_COUNT ][ 256 ];
73 static GXColor          sampleStringCol[ REXDEMO_RAW_COUNT ][ 256 ];
74 static s32              sampleRawIndex;
75 static s32              sampleNextRawIndex;
76 static s32              sampleNextColIndex;
77 static REXDEMOCamera    sampleCamera;
78 static GXLightObj       sampleLight;
79 
80 static GXColor          sampleTextCol;
81 static GXColor          sampleGroundCol;
82 static int              sampleFontWidth;
83 static int              sampleFontHeight;
84 static BOOL             sampleIsBeginRenderCalled;
85 
86 /*---------------------------------------------------------------------------*
87     Internal function prototype
88  *---------------------------------------------------------------------------*/
89 static void     InitString( void );
90 static void     RenderString( void );
91 static void*    RenderThread( void* arg );
92 static int      REXDEMODrawChar( int x, int y, int z, int w, int h, const char **string );
93 
94 
95 /*===========================================================================*/
96 
97 /*---------------------------------------------------------------------------*
98   Name: REXDEMOGraphicInit
99   Description: Performs initialization required for on-screen display.
100   Arguments: None
101   Returns: None
102  *---------------------------------------------------------------------------*/
103 void
REXDEMOInitScreen(BOOL autoRender)104 REXDEMOInitScreen( BOOL autoRender )
105 {
106     /* Initialize VI */
107     {
108         GXRenderModeObj*  viConf  = &GXNtsc480IntDf;
109 
110         VIInit();
111 
112         switch (VIGetTvFormat())
113         {
114           case VI_NTSC:
115             viConf = &GXNtsc480IntDf;
116             break;
117           case VI_PAL:
118             viConf = &GXPal528IntDf;
119             break;
120           case VI_EURGB60:
121             viConf = &GXEurgb60Hz480IntDf;
122             break;
123           case VI_MPAL:
124             viConf = &GXMpal480IntDf;
125             break;
126           default:
127             OSHalt("DEMOInit: invalid TV format\n");
128             break;
129         }
130 
131         (void)memcpy( &sampleRend, viConf, sizeof( GXRenderModeObj ) );
132 
133         // Trim off from top & bottom 16 scanlines (which will be overscanned).
134         // So almost all demos actually render only 448 lines (in NTSC case.)
135         // Since this setting is just for SDK demos, you can specify this
136         // in order to match your application requirements.
137         GXAdjustForOverscan( &sampleRend, &sampleRend, 0, 16 );
138         sampleFrameCycle    = ( ( ( sampleRend.viTVmode >> 2 ) == VI_PAL ) ? 50 : 60 );
139         VIConfigure( &sampleRend );
140     }
141 
142     /* Allocate external frame buffer */
143     {
144         void*   arena_s;
145         u32     xfbSize;
146         s32     i;
147 
148         arena_s = OSGetMEM1ArenaLo();
149         xfbSize = (u32)( VIPadFrameBufferWidth( sampleRend.fbWidth ) * sampleRend.xfbHeight * VI_DISPLAY_PIX_SZ );
150         for( i = 0; i < REXDEMO_XFB_COUNT; i ++ )
151         {
152             sampleXFB[ i ]  = (void*)OSRoundUp32B( (u32)arena_s );
153             arena_s = (void*)OSRoundUp32B( (u32)( sampleXFB[ i ] ) + xfbSize );
154         }
155         OSSetMEM1ArenaLo( arena_s );
156     }
157 
158     /* Initialize GX */
159     {
160         GXFifoObj*  gxFifo;
161         f32         yScale;
162         u16         xfbHeight;
163 
164         gxFifo  = GXInit( sampleFifoBuf, REXDEMO_FIFO_SIZE );
165         GXSetViewport( 0.0F, 0.0F, (f32)sampleRend.fbWidth, (f32)sampleRend.efbHeight, 0.0F, 1.0F );
166         GXSetScissor( 0, 0, (u32)sampleRend.fbWidth, (u32)sampleRend.efbHeight );
167         yScale  = GXGetYScaleFactor( sampleRend.efbHeight, sampleRend.xfbHeight );
168         xfbHeight   = (u16)GXSetDispCopyYScale( yScale );
169         GXSetDispCopySrc( 0, 0, sampleRend.fbWidth, sampleRend.efbHeight );
170         GXSetDispCopyDst( sampleRend.fbWidth, xfbHeight );
171         GXSetCopyFilter( sampleRend.aa, sampleRend.sample_pattern, GX_TRUE, sampleRend.vfilter );
172         GXSetDispCopyGamma( GX_GM_1_0 );
173         if( sampleRend.aa )
174         {
175             GXSetPixelFmt( GX_PF_RGB565_Z16, GX_ZC_LINEAR );
176         }
177         else
178         {
179             GXSetPixelFmt( GX_PF_RGB8_Z24, GX_ZC_LINEAR );
180         }
181         GXCopyDisp( sampleXFB[ 0 ], GX_TRUE );
182     }
183 
184     /* Initialize display settings */
185     {
186         static const GXColor strCol = { 0x00, 0x00, 0x00, 0xff };
187         static const GXColor backCol = { 0xff, 0xff, 0xff, 0xff };
188         sampleTextCol             = strCol;
189         sampleGroundCol           = backCol;
190         sampleIsBeginRenderCalled = FALSE;
191         sampleFontWidth           = -1;
192         sampleFontHeight          = -1;
193     }
194 
195     InitString();
196 
197     /* Wait for first frame */
198     {
199         VISetNextFrameBuffer( sampleXFB[ 0 ] );
200         VISetBlack( FALSE );
201         VIFlush();
202         VIWaitForRetrace();
203         if( (u32)( sampleRend.viTVmode ) & 0x1 )
204         {
205             VIWaitForRetrace();
206         }
207     }
208     if (autoRender)
209     {
210         static OSThread thread;
211         static u32      stack[2048];
212         if ( !OSCreateThread( &thread, RenderThread, NULL,
213                              (void*)( (u8*)stack + sizeof(stack) ),
214                              sizeof(stack), 17, OS_THREAD_ATTR_DETACH ) )
215         {
216             OSReport("OSCreateThread() failed.\n");
217             return;
218         }
219         (void)OSResumeThread(&thread);
220     }
221 }
222 
223 /*---------------------------------------------------------------------------*
224   Name: REXDEMOWaitRetrace
225   Description: Wait until V-Blank interrupt is generated.
226   Arguments: None
227   Returns: None
228  *---------------------------------------------------------------------------*/
229 void
REXDEMOWaitRetrace(void)230 REXDEMOWaitRetrace( void )
231 {
232     REXDEMOBeginRender();
233     RenderString();
234     GXCopyDisp( sampleXFB[ sampleFrameCount % REXDEMO_XFB_COUNT ], GX_TRUE );
235     VISetNextFrameBuffer( sampleXFB[ sampleFrameCount % REXDEMO_XFB_COUNT ] );
236     VIFlush();
237     VIWaitForRetrace();
238     sampleFrameCount ++;
239     sampleIsBeginRenderCalled = FALSE;
240 }
241 
242 /*---------------------------------------------------------------------------*
243   Name: REXDEMOReportEx
244   Description: Performs debug display of text.
245   Arguments: col - Character color.
246                 msg - The character string to be displayed
247                 ...     -   Virtual argument.
248   Returns: None
249  *---------------------------------------------------------------------------*/
250 void
REXDEMOReportEx(GXColor col,const char * msg,...)251 REXDEMOReportEx( GXColor col, const char* msg, ... )
252 {
253     va_list     vl;
254     char        temp[ 256 ];
255     int         len;
256     s32         i;
257     char*       p;
258 
259     (void)memset( temp, 0, sizeof( temp ) );
260     va_start( vl, msg );
261     len = vsprintf( temp, msg, vl );
262     ASSERT( len < 256 );
263     va_end( vl );
264 
265     OSReport( temp );
266     p   = &temp[ 0 ];
267     for( i = 0; i < 256; i ++ )
268     {
269         if( *p == 0x00 )
270         {
271             sampleString[ sampleNextRawIndex % REXDEMO_RAW_COUNT ][ sampleNextColIndex ] = 0x00;
272             break;
273         }
274         if( *p == 0x0d )
275         {
276             p ++;
277             continue;
278         }
279         if( *p == 0x0a )
280         {
281             sampleString[ sampleNextRawIndex % REXDEMO_RAW_COUNT ][ sampleNextColIndex ] = 0x00;
282             sampleNextColIndex  = 0;
283             sampleNextRawIndex  ++;
284             if( sampleNextRawIndex >= REXDEMO_RAW_COUNT )
285             {
286                 sampleRawIndex = ( sampleRawIndex + 1 ) % REXDEMO_RAW_COUNT;
287             }
288             p ++;
289             continue;
290         }
291         sampleString[ sampleNextRawIndex % REXDEMO_RAW_COUNT ][ sampleNextColIndex ] = *p;
292         sampleStringCol[ sampleNextRawIndex % REXDEMO_RAW_COUNT ][ sampleNextColIndex ] = col;
293         if( ( ++ sampleNextColIndex ) > 255 )
294         {
295             sampleNextColIndex  = 0;
296             sampleNextRawIndex  ++;
297             if( sampleNextRawIndex >= REXDEMO_RAW_COUNT )
298             {
299                 sampleRawIndex = ( sampleRawIndex + 1 ) % REXDEMO_RAW_COUNT;
300             }
301         }
302         p ++;
303     }
304 }
305 
306 /*---------------------------------------------------------------------------*
307   Name: REXDEMOSetTextColor
308   Description: Sets the rendered text color.
309   Arguments: col    - Text color
310   Returns: None
311  *---------------------------------------------------------------------------*/
312 void
REXDEMOSetTextColor(const GXColor col)313 REXDEMOSetTextColor( const GXColor col )
314 {
315     sampleTextCol = col;
316     GXSetTevColor(GX_TEVREG0, col);
317 }
318 
319 /*---------------------------------------------------------------------------*
320   Name: REXDEMOSetGroundColor
321   Description: Sets the render background color.
322   Arguments: col    - Background color.
323   Returns: None
324  *---------------------------------------------------------------------------*/
325 void
REXDEMOSetGroundColor(const GXColor col)326 REXDEMOSetGroundColor( const GXColor col )
327 {
328     sampleGroundCol = col;
329     sampleGroundCol.a = 0xFF;
330 }
331 
332 /*---------------------------------------------------------------------------*
333   Name: REXDEMOSetFontSize
334   Description: Set the font size.
335   Arguments   : width  - x width (auto-calculate if a value less than 0 is specified)
336                 height - y width (auto-calculate if a value less than 0 is specified)
337   Returns: None
338  *---------------------------------------------------------------------------*/
339 void
REXDEMOSetFontSize(int width,int height)340 REXDEMOSetFontSize( int width, int height )
341 {
342     sampleFontWidth  = width;
343     sampleFontHeight = height;
344 }
345 
346 /*---------------------------------------------------------------------------*
347   Name: REXDEMOBeginRender
348   Description: Performs processing before rendering starts for each frame.
349   Arguments: None
350   Returns: None
351  *---------------------------------------------------------------------------*/
352 void
REXDEMOBeginRender(void)353 REXDEMOBeginRender(void)
354 {
355     f32     scrWidth    = (f32)sampleRend.fbWidth;
356     f32     scrHeight   = (f32)sampleRend.efbHeight;
357 
358     const GXColor   ambientCol  = { 0xff, 0xff, 0xff, 0xff };
359 
360     if (sampleIsBeginRenderCalled)
361     {
362         return;
363     }
364     sampleIsBeginRenderCalled = TRUE;
365 
366     /* Rendering preparation */
367     {
368         Mtx44   projMtx;
369         Mtx     posMtx;
370 
371         GXInvalidateTexAll();
372         /* Viewport settings */
373         if( (u32)( sampleRend.viTVmode ) & 0x1 )
374         {
375             GXSetViewportJitter( 0.0f, 0.0f, scrWidth, scrHeight, 0.0F, 1.0F, VIGetNextField() );
376         }
377         else
378         {
379             GXSetViewport( 0.0f, 0.0f, scrWidth, scrHeight, 0.0F, 1.0F );
380         }
381         GXSetScissor( 0, 0, (u32)scrWidth, (u32)scrHeight );
382         /* Camera settings */
383         MTXOrtho( projMtx, 0.0f, scrHeight, 0.0f, scrWidth, sampleCamera.znear, sampleCamera.zfar );
384         GXSetProjection( projMtx, GX_ORTHOGRAPHIC );
385         MTXIdentity( posMtx );
386         GXLoadPosMtxImm( posMtx, GX_PNMTX0 );
387         GXSetCurrentMtx( GX_PNMTX0 );
388         GXSetZMode( GX_TRUE, GX_LEQUAL, GX_TRUE );
389         GXSetBlendMode( GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR );
390         /* Light settings */
391         GXSetNumChans( 1 );
392         GXSetChanAmbColor( GX_COLOR0A0, ambientCol );
393         GXLoadLightObjImm( &sampleLight, GX_LIGHT0 );
394         GXSetChanCtrl( GX_COLOR0, GX_ENABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT0, GX_DF_NONE, GX_AF_NONE );
395         GXSetChanCtrl( GX_ALPHA0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT0, GX_DF_NONE, GX_AF_NONE );
396     }
397 
398     /* Draw background */
399     {
400         s16     z   = -1023;
401 
402         /* Set vertex */
403         GXClearVtxDesc();
404         GXSetVtxDesc( GX_VA_POS, GX_DIRECT );
405         GXSetVtxAttrFmt( GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_S16, 0 );
406         /* Texture configuration */
407         GXSetNumTexGens( 0 );
408         GXSetNumTevStages( 1 );
409         GXSetTevOp( GX_TEVSTAGE0, GX_PASSCLR );
410         GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0 );
411         /* Draw quadrangular polygons */
412         GXSetChanMatColor( GX_COLOR0A0, sampleGroundCol );
413         GXBegin( GX_QUADS, GX_VTXFMT1, 4 );
414             GXPosition3s16( 0, 0, z );
415             GXPosition3s16( (s16)scrWidth, 0, z );
416             GXPosition3s16( (s16)scrWidth, (s16)scrHeight, z );
417             GXPosition3s16( 0, (s16)scrHeight, z );
418         GXEnd();
419     }
420 
421     /* Prepare to render character string */
422     {
423         static const GXColor strCol = { 0x00, 0x00, 0x00, 0xff };
424         Mtx         scaleMtx;
425 
426         /* Set vertex */
427         GXClearVtxDesc();
428         GXSetVtxDesc( GX_VA_POS, GX_DIRECT );
429         GXSetVtxDesc( GX_VA_TEX0, GX_DIRECT );
430         GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0 );
431         GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0 );
432         /* Texture configuration */
433         GXSetNumTexGens( 1 );
434         MTXScale( scaleMtx, ( 1.0f / sampleFont->sheetWidth ), ( 1.0f / sampleFont->sheetHeight ), 1.0f );
435         GXLoadTexMtxImm( scaleMtx, GX_TEXMTX0, GX_MTX2x4 );
436         GXSetTexCoordGen( GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0 );
437         GXSetNumTevStages( 1 );
438         GXSetTevOp( GX_TEVSTAGE0, GX_MODULATE );
439         GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0 );
440         GXSetChanMatColor( GX_COLOR0A0, strCol );
441         GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_C0, GX_CC_TEXC, GX_CC_ZERO);
442         GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
443         GXSetTevColor( GX_TEVREG0, sampleTextCol );
444     }
445 }
446 
447 /*---------------------------------------------------------------------------*
448   Name: REXDEMOPrintf
449   Description: Draws the character string in a freely specified position.
450   Arguments   : x     - x coordinate
451                 y     - y coordinate
452                 z      - z coordinate
453                 fmt    - Formatted character string
454                 ...  - Variable argument
455   Returns: None
456  *---------------------------------------------------------------------------*/
457 void
REXDEMOPrintf(int x,int y,int z,const char * fmt,...)458 REXDEMOPrintf( int x, int y, int z, const char *fmt, ... )
459 {
460     /* Convert the formatted character string to temporary buffer */
461     char    tmpbuf[256];
462     va_list va;
463     va_start(va, fmt);
464     (void)vsprintf(tmpbuf, fmt, va);
465     va_end(va);
466     /* Render character string */
467     {
468         const char* ptr = tmpbuf;
469         int         h;
470         int         ox = x;
471         h = (sampleFontHeight > 0) ? sampleFontHeight :
472             (int)( sampleRend.efbHeight / ( REXDEMO_RAW_COUNT - 1 ) );
473         while( *ptr )
474         {
475             if( ( *ptr == '\r' ) || ( *ptr == '\n' ) )
476             {
477                 y += h;
478 
479                 ox = x;
480                 ++ptr;
481             }
482             else
483             {
484                 ox += REXDEMODrawChar( ox, y, z, -1, -1, &ptr );
485             }
486         }
487     }
488 }
489 
490 /*===========================================================================*/
491 
492 /*---------------------------------------------------------------------------*
493   Name: InitString
494   Description: Performs the necessary initialization for displaying strings in debug.
495   Arguments: None
496   Returns: None
497  *---------------------------------------------------------------------------*/
498 static void
InitString(void)499 InitString( void )
500 {
501     /* Initialize the string buffer*/
502     (void)memset( sampleString, 0, sizeof( sampleString ) );
503     sampleRawIndex  = 0;
504     sampleNextRawIndex  = 0;
505     sampleNextColIndex  = 0;
506 
507     /* Load font data */
508     (void)OSInitFont( sampleFont );
509 
510     /* Initialize camera */
511     {
512         sampleCamera.fovy       = 33.3f;
513         sampleCamera.aspect     = (f32)( 10.0f / 7.0f );
514         sampleCamera.znear      = 0.001f;
515         sampleCamera.zfar       = 65535.999f;
516         sampleCamera.pos.x      = 0.0f;
517         sampleCamera.pos.y      = 0.0f;
518         sampleCamera.pos.z      = -20.0f;
519         sampleCamera.up.x       = 0.0f;
520         sampleCamera.up.y       = 1.0f;
521         sampleCamera.up.z       = 0.0f;
522         sampleCamera.target.x   = 0.0f;
523         sampleCamera.target.y   = 0.0f;
524         sampleCamera.target.z   = 0.0f;
525     }
526 
527     /* Initialize lighting */
528     {
529         const Vec       lpos    = { 0.0f, 0.0f, 0.0f };
530         const Vec       ldir    = { 0.0f, 0.0f, -1.0f };
531 
532         GXInitLightPosv( &sampleLight, &lpos );
533         GXInitLightDirv( &sampleLight, &ldir );
534         GXInitLightColor( &sampleLight, REXDEMO_COLOR_WHITE );
535         GXInitLightSpot( &sampleLight, 0.03f, GX_SP_COS );
536         GXInitLightDistAttn( &sampleLight, 3.0f, 0.5f, GX_DA_GENTLE );
537     }
538 }
539 
540 /*---------------------------------------------------------------------------*
541   Name: REXDEMODrawChar
542   Description: Draws just one character at the specified coordinate position.
543   Arguments   : x     - x coordinate
544                 y     - y coordinate
545                 z      - z coordinate
546                 w      - x width
547                 h      - y width
548                 string - Pointer of the pointer to the character to be drawn
549   Returns: Rendered x width.
550  *---------------------------------------------------------------------------*/
551 static int
REXDEMODrawChar(int x,int y,int z,int w,int h,const char ** string)552 REXDEMODrawChar( int x, int y, int z, int w, int h, const char **string )
553 {
554     f32     scrWidth    = (f32)( sampleRend.fbWidth );
555     f32     scrHeight   = (f32)( sampleRend.efbHeight );
556 
557     GXTexObj    tobj;
558     void*       image;
559     s32         fx, fy, fw;
560 
561     const char *ptr = *string;
562     ptr = OSGetFontTexture( ptr, &image, &fx, &fy, &fw );
563     *string = ptr;
564 
565     if (w < 0)
566     {
567         w = (sampleFontWidth > 0) ? sampleFontWidth :
568             (int)( ( fw * scrWidth ) / ( 12 * REXDEMO_COL_COUNT ) );
569     }
570     if (h < 0)
571     {
572         h = (sampleFontHeight > 0) ? sampleFontHeight :
573             (int)( scrHeight / ( REXDEMO_RAW_COUNT - 1 ) );
574     }
575 
576     GXInitTexObj( &tobj, image, sampleFont->sheetWidth, sampleFont->sheetHeight, GX_TF_I4, GX_REPEAT, GX_REPEAT, GX_FALSE );
577     GXLoadTexObj( &tobj, GX_TEXMAP0 );
578     GXBegin( GX_QUADS, GX_VTXFMT0, 4 );
579     {
580         GXPosition3s16( (s16)( x + 0 ), (s16)( y + 0 ), (s16)z );
581         GXTexCoord2s16( (s16)( fx +  0 ), (s16)( fy +  0 ) );
582         GXPosition3s16( (s16)( x + w ), (s16)( y + 0 ), (s16)z );
583         GXTexCoord2s16( (s16)( fx + fw ), (s16)( fy +  0 ) );
584         GXPosition3s16( (s16)( x + w ), (s16)( y + h ), (s16)z );
585         GXTexCoord2s16( (s16)( fx + fw ), (s16)( fy + 24 ) );
586         GXPosition3s16( (s16)( x + 0 ), (s16)( y + h ), (s16)z );
587         GXTexCoord2s16( (s16)( fx +  0 ), (s16)( fy + 24 ) );
588     }
589     GXEnd();
590     return w;
591 }
592 
593 /*---------------------------------------------------------------------------*
594   Name: RenderString
595   Description: Performs the rendering required for each picture frame in order to perform debug display of text string.
596                 Performs rendering.
597   Arguments: None
598   Returns: None
599  *---------------------------------------------------------------------------*/
600 static void
RenderString(void)601 RenderString( void )
602 {
603     s32     i, j;
604     f32     scrWidth    = (f32)( sampleRend.fbWidth );
605     f32     scrHeight   = (f32)( sampleRend.efbHeight );
606 
607 #if ( REXDEMO_SHOW_FRAME_COUNT == 1 )
608     /* Draw frame count */
609     {
610         s16         x, y, z, w, h;
611         char    tempStr[ 20 ];
612         const char* ptr;
613 
614         (void)sprintf( tempStr, "%d", sampleFrameCount );
615         GXSetChanMatColor( GX_COLOR0A0, REXDEMO_COLOR_PURPLE );
616         for( i = 0; i < 20; i ++ )
617         {
618             if( tempStr[ i ] == 0x00 )
619             {
620                 break;
621             }
622         }
623         w   = 16;
624         h   = 32;
625         x   = (s16)( ( scrWidth - ( i * w ) ) - 4 );
626         y   = 2;    /* Position is upper right of screen */
627         z   = -1000;
628         ptr = tempStr;
629         for( j = 0; j < i; j ++ )
630         {
631             x   += REXDEMODrawChar( x, y, z, w, h, &ptr );
632         }
633     }
634 #endif
635 
636     /* Draw string buffer */
637     for( i = 0; i < ( REXDEMO_RAW_COUNT - 1 ); i ++ )
638     {
639         s16         x   = 2;
640         s16         y   = (s16)( ( scrHeight * i ) / ( REXDEMO_RAW_COUNT - 1 ) );
641         s16         z   = -1;
642 
643         const char* ptr       = &( sampleString[ ( sampleRawIndex + i ) % REXDEMO_RAW_COUNT ][ 0 ] );
644         const GXColor* strCol = &( sampleStringCol[ ( sampleRawIndex + i ) % REXDEMO_RAW_COUNT ][ 0 ] );
645         char*       oldPtr;
646 
647         for( j = 0; j < 256; j ++ )
648         {
649             if( ( *ptr == 0x00 ) || ( *ptr == 0x0d ) || ( *ptr == 0x0a ) )
650             {
651                 break;
652             }
653             REXDEMOSetTextColor( *( (const GXColor*)strCol ) );
654             oldPtr  = (char*)ptr;
655             x   += REXDEMODrawChar( x, y, z, -1, -1, &ptr );
656             strCol  += ( (u32)ptr - (u32)oldPtr );
657             if( x >= scrWidth )
658             {
659                 break;
660             }
661         }
662     }
663 }
664 
RenderThread(void * arg)665 static void* RenderThread( void* arg )
666 {
667 #pragma unused(arg)
668     while(TRUE)
669     {
670         REXDEMOWaitRetrace();
671     }
672 }
673 
674 /*---------------------------------------------------------------------------*
675   End of file
676  *---------------------------------------------------------------------------*/
677